From 8ed50890e12088cf7b8bea117aee27ac5fa5eb59 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 2 Aug 2020 10:59:41 -0230 Subject: [PATCH 001/263] Finalize AVox CTS support. Now more testing is needed ... --- Changes.txt | 4 ++++ src/emucore/AtariVox.cxx | 16 ++++++++++------ src/emucore/AtariVox.hxx | 5 +++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Changes.txt b/Changes.txt index 9db31b627..61b036ebc 100644 --- a/Changes.txt +++ b/Changes.txt @@ -33,6 +33,10 @@ Basically, you are now able to put many files that Stella uses inside one ZIP file, and distribute just that file. + * Extended AtariVox support to handle flow control, so that long phrases + are no longer corrupted/cut off. Note that some USB-serial adaptors + don't support this mode, so there may still be issues with those. + * Added option to select the audio device. * Added option to display detected settings info when a ROM is loaded. diff --git a/src/emucore/AtariVox.cxx b/src/emucore/AtariVox.cxx index fd75024e4..731232456 100644 --- a/src/emucore/AtariVox.cxx +++ b/src/emucore/AtariVox.cxx @@ -28,7 +28,13 @@ AtariVox::AtariVox(Jack jack, const Event& event, const System& system, { mySerialPort = MediaFactory::createSerialPort(); if(mySerialPort->openPort(portname)) - myAboutString = " (using serial port \'" + portname + "\')"; + { + myCTSFlip = !mySerialPort->isCTS(); + if(myCTSFlip) + myAboutString = " (serial port \'" + portname + "\', inverted CTS)"; + else + myAboutString = " (serial port \'" + portname + "\')"; + } else myAboutString = " (invalid serial port \'" + portname + "\')"; @@ -50,12 +56,10 @@ bool AtariVox::read(DigitalPin pin) switch(pin) { // Pin 2: SpeakJet READY - // CTS (Clear To Send) is connected inverted - // So CTS = 0 means the buffer is full, which pulls pin 2 high + // CTS (Clear To Send) is sent directly to pin 2 + // We also deal with the case where devices send CTS inverted case DigitalPin::Two: - { - return setPin(pin, !mySerialPort->isCTS()); - } + return setPin(pin, mySerialPort->isCTS() ^ myCTSFlip); default: return SaveKey::read(pin); diff --git a/src/emucore/AtariVox.hxx b/src/emucore/AtariVox.hxx index 3251234ed..132b2c377 100644 --- a/src/emucore/AtariVox.hxx +++ b/src/emucore/AtariVox.hxx @@ -117,6 +117,11 @@ class AtariVox : public SaveKey // "close enough". uInt64 myLastDataWriteCycle{0}; + // Some USB-Serial adaptors either don't support CTS, or send the signal + // as inverted; we detect that when opening the port, and flip the signal + // when necessary + bool myCTSFlip{false}; + // Holds information concerning serial port usage string myAboutString; From 0b05320632323e5dd53e1f5f90d30dafe1608a39 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 4 Aug 2020 12:08:43 +0200 Subject: [PATCH 002/263] fixed autofire for trackball using keyboard fire event --- src/emucore/PointingDevice.cxx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/emucore/PointingDevice.cxx b/src/emucore/PointingDevice.cxx index 05cf7c031..accf00a04 100644 --- a/src/emucore/PointingDevice.cxx +++ b/src/emucore/PointingDevice.cxx @@ -88,11 +88,8 @@ void PointingDevice::update() updateDirection(-myEvent.get(Event::MouseAxisYMove), myVCounterRemainder, myTrackBallDown, myTrackBallLinesV, myScanCountV, myFirstScanOffsetV); - // Digital events (from keyboard or joystick hats & buttons) - setPin(DigitalPin::Six, myEvent.get(Event::JoystickZeroFire) == 0); - // We allow left and right mouse buttons for fire button - setPin(DigitalPin::Six, !getAutoFireState( + setPin(DigitalPin::Six, !getAutoFireState(myEvent.get(Event::JoystickZeroFire) == 0 || myEvent.get(Event::MouseButtonLeftValue) || myEvent.get(Event::MouseButtonRightValue))); } From 9b6c29bfca0e6a0b871b90feef95f749227f7bf8 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 14 Aug 2020 13:37:15 -0230 Subject: [PATCH 003/263] Fix compiler warnings: uInt32 to size_t. --- src/common/LinkedObjectPool.hxx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/common/LinkedObjectPool.hxx b/src/common/LinkedObjectPool.hxx index 7c35439e3..b31446e79 100644 --- a/src/common/LinkedObjectPool.hxx +++ b/src/common/LinkedObjectPool.hxx @@ -49,7 +49,7 @@ */ namespace Common { -template +template class LinkedObjectPool { public: @@ -75,12 +75,12 @@ class LinkedObjectPool SLOW, but only required for messages */ - uInt32 currentIdx() const { + size_t currentIdx() const { if(empty()) return 0; iter it = myCurrent; - uInt32 idx = 1; + size_t idx = 1; while(it-- != myList.begin()) ++idx; return idx; @@ -210,7 +210,7 @@ class LinkedObjectPool the beginning of the list. (ie, '0' means first element, '1' is second, and so on). */ - void remove(uInt32 index) { + void remove(size_t index) { myPool.splice(myPool.end(), myList, std::next(myList.begin(), index)); } @@ -234,15 +234,15 @@ class LinkedObjectPool Resize the pool to specified size, invalidating the list in the process (ie, the list essentially becomes empty again). */ - void resize(uInt32 capacity) { + void resize(size_t capacity) { if(myCapacity != capacity) // only resize when necessary { myList.clear(); myPool.clear(); myCurrent = myList.end(); myCapacity = capacity; - for(uInt32 i = 0; i < myCapacity; ++i) - myPool.emplace_back(T()); + for(size_t i = 0; i < myCapacity; ++i) + myPool.emplace_back(); } } @@ -254,11 +254,11 @@ class LinkedObjectPool myCurrent = myList.end(); } - uInt32 capacity() const { return myCapacity; } + size_t capacity() const { return myCapacity; } - uInt32 size() const { return uInt32(myList.size()); } - bool empty() const { return size() == 0; } - bool full() const { return size() >= capacity(); } + size_t size() const { return myList.size(); } + bool empty() const { return size() == 0; } + bool full() const { return size() >= capacity(); } friend ostream& operator<<(ostream& os, const LinkedObjectPool& p) { for(const auto& i: p.myList) @@ -273,7 +273,7 @@ class LinkedObjectPool iter myCurrent{myList.end()}; // Total capacity of the pool - uInt32 myCapacity{0}; + size_t myCapacity{0}; private: // Following constructors and assignment operators not supported From 86b73b781dc9e85171bee833b8bec124a7e1753c Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 15 Aug 2020 17:37:23 -0230 Subject: [PATCH 004/263] Revert "Fix compiler warnings: uInt32 to size_t." This causes more problems than it's worth. This reverts commit 9b6c29bfca0e6a0b871b90feef95f749227f7bf8. --- src/common/LinkedObjectPool.hxx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/common/LinkedObjectPool.hxx b/src/common/LinkedObjectPool.hxx index b31446e79..7c35439e3 100644 --- a/src/common/LinkedObjectPool.hxx +++ b/src/common/LinkedObjectPool.hxx @@ -49,7 +49,7 @@ */ namespace Common { -template +template class LinkedObjectPool { public: @@ -75,12 +75,12 @@ class LinkedObjectPool SLOW, but only required for messages */ - size_t currentIdx() const { + uInt32 currentIdx() const { if(empty()) return 0; iter it = myCurrent; - size_t idx = 1; + uInt32 idx = 1; while(it-- != myList.begin()) ++idx; return idx; @@ -210,7 +210,7 @@ class LinkedObjectPool the beginning of the list. (ie, '0' means first element, '1' is second, and so on). */ - void remove(size_t index) { + void remove(uInt32 index) { myPool.splice(myPool.end(), myList, std::next(myList.begin(), index)); } @@ -234,15 +234,15 @@ class LinkedObjectPool Resize the pool to specified size, invalidating the list in the process (ie, the list essentially becomes empty again). */ - void resize(size_t capacity) { + void resize(uInt32 capacity) { if(myCapacity != capacity) // only resize when necessary { myList.clear(); myPool.clear(); myCurrent = myList.end(); myCapacity = capacity; - for(size_t i = 0; i < myCapacity; ++i) - myPool.emplace_back(); + for(uInt32 i = 0; i < myCapacity; ++i) + myPool.emplace_back(T()); } } @@ -254,11 +254,11 @@ class LinkedObjectPool myCurrent = myList.end(); } - size_t capacity() const { return myCapacity; } + uInt32 capacity() const { return myCapacity; } - size_t size() const { return myList.size(); } - bool empty() const { return size() == 0; } - bool full() const { return size() >= capacity(); } + uInt32 size() const { return uInt32(myList.size()); } + bool empty() const { return size() == 0; } + bool full() const { return size() >= capacity(); } friend ostream& operator<<(ostream& os, const LinkedObjectPool& p) { for(const auto& i: p.myList) @@ -273,7 +273,7 @@ class LinkedObjectPool iter myCurrent{myList.end()}; // Total capacity of the pool - size_t myCapacity{0}; + uInt32 myCapacity{0}; private: // Following constructors and assignment operators not supported From be85557e6bc6569cb89b4bf3c352a8a076e40c10 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 17 Aug 2020 10:38:43 -0230 Subject: [PATCH 005/263] Fix warnings from Clang 11. Apparently d'tors in child classes should now be marked override rather than virtual (to match other methods). So we do that specifically now. --- src/cheat/BankRomCheat.hxx | 2 +- src/cheat/CheatCodeDialog.hxx | 2 +- src/cheat/CheetahCheat.hxx | 2 +- src/cheat/RamCheat.hxx | 2 +- src/common/EventHandlerSDL2.cxx | 1 - src/common/EventHandlerSDL2.hxx | 4 +- src/common/FBSurfaceSDL2.hxx | 2 +- src/common/FrameBufferSDL2.hxx | 2 +- src/common/PaletteHandler.hxx | 1 - src/common/SoundNull.hxx | 6 +-- src/common/SoundSDL2.hxx | 2 +- src/common/sdl_blitter/BilinearBlitter.hxx | 2 +- src/common/sdl_blitter/QisBlitter.hxx | 2 +- src/debugger/CartDebug.hxx | 2 +- src/debugger/Debugger.hxx | 2 +- src/debugger/DebuggerSystem.hxx | 2 +- src/debugger/gui/AmigaMouseWidget.hxx | 2 +- src/debugger/gui/AtariMouseWidget.hxx | 3 +- src/debugger/gui/AtariVoxWidget.hxx | 2 +- src/debugger/gui/AudioWidget.hxx | 2 +- src/debugger/gui/BoosterWidget.hxx | 2 +- src/debugger/gui/Cart0840Widget.hxx | 2 +- src/debugger/gui/Cart2KWidget.hxx | 2 +- src/debugger/gui/Cart3EPlusWidget.hxx | 2 +- src/debugger/gui/Cart3EWidget.hxx | 2 +- src/debugger/gui/Cart3FWidget.hxx | 2 +- src/debugger/gui/Cart4A50Widget.hxx | 2 +- src/debugger/gui/Cart4KSCWidget.hxx | 2 +- src/debugger/gui/Cart4KWidget.hxx | 2 +- src/debugger/gui/CartARWidget.hxx | 2 +- src/debugger/gui/CartBFSCWidget.hxx | 2 +- src/debugger/gui/CartBFWidget.hxx | 2 +- src/debugger/gui/CartBUSWidget.hxx | 2 +- src/debugger/gui/CartCDFInfoWidget.hxx | 2 +- src/debugger/gui/CartCDFWidget.hxx | 2 +- src/debugger/gui/CartCMWidget.hxx | 2 +- src/debugger/gui/CartCTYWidget.hxx | 2 +- src/debugger/gui/CartCVWidget.hxx | 2 +- src/debugger/gui/CartDFSCWidget.hxx | 2 +- src/debugger/gui/CartDFWidget.hxx | 2 +- src/debugger/gui/CartDPCPlusWidget.hxx | 2 +- src/debugger/gui/CartDPCWidget.hxx | 2 +- src/debugger/gui/CartDebugWidget.hxx | 2 +- src/debugger/gui/CartE0Widget.hxx | 2 +- src/debugger/gui/CartE78KWidget.hxx | 2 +- src/debugger/gui/CartE7Widget.hxx | 2 +- src/debugger/gui/CartEFSCWidget.hxx | 2 +- src/debugger/gui/CartEFWidget.hxx | 2 +- src/debugger/gui/CartEnhancedWidget.hxx | 2 +- src/debugger/gui/CartF0Widget.hxx | 2 +- src/debugger/gui/CartF4SCWidget.hxx | 2 +- src/debugger/gui/CartF4Widget.hxx | 2 +- src/debugger/gui/CartF6SCWidget.hxx | 2 +- src/debugger/gui/CartF6Widget.hxx | 2 +- src/debugger/gui/CartF8SCWidget.hxx | 2 +- src/debugger/gui/CartF8Widget.hxx | 2 +- src/debugger/gui/CartFA2Widget.hxx | 2 +- src/debugger/gui/CartFAWidget.hxx | 2 +- src/debugger/gui/CartFCWidget.hxx | 2 +- src/debugger/gui/CartFEWidget.hxx | 2 +- src/debugger/gui/CartMDMWidget.hxx | 2 +- src/debugger/gui/CartMNetworkWidget.hxx | 2 +- src/debugger/gui/CartRamWidget.hxx | 4 +- src/debugger/gui/CartSBWidget.hxx | 2 +- src/debugger/gui/CartTVBoyWidget.hxx | 2 +- src/debugger/gui/CartUAWidget.hxx | 2 +- src/debugger/gui/CartWDWidget.hxx | 4 +- src/debugger/gui/CartX07Widget.hxx | 2 +- src/debugger/gui/ControllerWidget.hxx | 2 +- src/debugger/gui/CpuWidget.hxx | 2 +- src/debugger/gui/DataGridOpsWidget.hxx | 2 +- src/debugger/gui/DataGridWidget.hxx | 2 +- src/debugger/gui/DebuggerDialog.hxx | 2 +- src/debugger/gui/DelayQueueWidget.hxx | 2 +- src/debugger/gui/DrivingWidget.hxx | 2 +- src/debugger/gui/FlashWidget.hxx | 2 +- src/debugger/gui/GenesisWidget.hxx | 2 +- src/debugger/gui/JoystickWidget.hxx | 2 +- src/debugger/gui/KeyboardWidget.hxx | 2 +- src/debugger/gui/NullControlWidget.hxx | 2 +- src/debugger/gui/PaddleWidget.hxx | 2 +- src/debugger/gui/PointingDeviceWidget.hxx | 3 +- src/debugger/gui/PromptWidget.hxx | 2 +- src/debugger/gui/RamWidget.hxx | 2 +- src/debugger/gui/RiotRamWidget.hxx | 2 +- src/debugger/gui/RiotWidget.hxx | 2 +- src/debugger/gui/RomListSettings.hxx | 2 +- src/debugger/gui/RomListWidget.hxx | 2 +- src/debugger/gui/RomWidget.hxx | 2 +- src/debugger/gui/SaveKeyWidget.hxx | 2 +- src/debugger/gui/TiaInfoWidget.hxx | 2 +- src/debugger/gui/TiaOutputWidget.hxx | 2 +- src/debugger/gui/TiaWidget.hxx | 2 +- src/debugger/gui/TiaZoomWidget.hxx | 2 +- src/debugger/gui/ToggleBitWidget.hxx | 2 +- src/debugger/gui/TogglePixelWidget.hxx | 2 +- src/debugger/gui/ToggleWidget.hxx | 2 +- src/debugger/gui/TrakBallWidget.hxx | 2 +- src/emucore/AmigaMouse.hxx | 2 +- src/emucore/AtariMouse.hxx | 2 +- src/emucore/AtariVox.hxx | 2 +- src/emucore/Booster.hxx | 2 +- src/emucore/Cart.hxx | 2 +- src/emucore/Cart0840.hxx | 2 +- src/emucore/Cart2K.hxx | 2 +- src/emucore/Cart3E.hxx | 2 +- src/emucore/Cart3EPlus.hxx | 2 +- src/emucore/Cart3EX.hxx | 2 +- src/emucore/Cart3F.hxx | 2 +- src/emucore/Cart4A50.hxx | 2 +- src/emucore/Cart4K.hxx | 2 +- src/emucore/Cart4KSC.hxx | 2 +- src/emucore/CartAR.hxx | 2 +- src/emucore/CartBF.hxx | 2 +- src/emucore/CartBFSC.hxx | 2 +- src/emucore/CartBUS.hxx | 2 +- src/emucore/CartCDF.hxx | 2 +- src/emucore/CartCM.hxx | 4 +- src/emucore/CartCTY.hxx | 2 +- src/emucore/CartCV.hxx | 2 +- src/emucore/CartDF.hxx | 2 +- src/emucore/CartDFSC.hxx | 2 +- src/emucore/CartDPC.hxx | 2 +- src/emucore/CartDPCPlus.hxx | 2 +- src/emucore/CartE0.hxx | 2 +- src/emucore/CartE7.hxx | 2 +- src/emucore/CartE78K.hxx | 2 +- src/emucore/CartEF.hxx | 2 +- src/emucore/CartEFSC.hxx | 2 +- src/emucore/CartEnhanced.hxx | 2 +- src/emucore/CartF0.hxx | 2 +- src/emucore/CartF4.hxx | 2 +- src/emucore/CartF4SC.hxx | 2 +- src/emucore/CartF6.hxx | 2 +- src/emucore/CartF6SC.hxx | 2 +- src/emucore/CartF8.hxx | 2 +- src/emucore/CartF8SC.hxx | 2 +- src/emucore/CartFA.hxx | 2 +- src/emucore/CartFA2.hxx | 2 +- src/emucore/CartFC.hxx | 2 +- src/emucore/CartFE.hxx | 2 +- src/emucore/CartMDM.hxx | 2 +- src/emucore/CartMNetwork.hxx | 2 +- src/emucore/CartSB.hxx | 2 +- src/emucore/CartTVBoy.hxx | 2 +- src/emucore/CartUA.hxx | 2 +- src/emucore/CartWD.hxx | 2 +- src/emucore/CartX07.hxx | 2 +- src/emucore/CompuMate.hxx | 3 +- src/emucore/Console.hxx | 2 +- src/emucore/Control.hxx | 2 +- src/emucore/Device.hxx | 2 +- src/emucore/Driving.hxx | 2 +- src/emucore/Genesis.hxx | 2 +- src/emucore/Joystick.hxx | 2 +- src/emucore/Keyboard.hxx | 2 +- src/emucore/KidVid.hxx | 2 +- src/emucore/Lightgun.hxx | 2 +- src/emucore/M6502.hxx | 2 +- src/emucore/M6532.hxx | 2 +- src/emucore/MindLink.hxx | 2 +- src/emucore/NullDev.hxx | 2 +- src/emucore/Paddles.hxx | 2 +- src/emucore/PointingDevice.hxx | 2 +- src/emucore/SaveKey.hxx | 2 +- src/emucore/Switches.hxx | 2 +- src/emucore/System.hxx | 2 +- src/emucore/TrakBall.hxx | 2 +- src/emucore/tia/TIA.hxx | 2 +- src/gui/AboutDialog.hxx | 2 +- src/gui/BrowserDialog.hxx | 2 +- src/gui/CheckListWidget.hxx | 2 +- src/gui/ColorWidget.hxx | 2 +- src/gui/ComboDialog.hxx | 2 +- src/gui/CommandDialog.hxx | 2 +- src/gui/CommandMenu.hxx | 2 +- src/gui/ContextMenu.hxx | 2 +- src/gui/DeveloperDialog.hxx | 2 +- src/gui/Dialog.hxx | 11 +--- src/gui/EditTextWidget.hxx | 2 +- src/gui/EditableWidget.hxx | 2 +- src/gui/EmulationDialog.hxx | 58 +++++++++++----------- src/gui/EventMappingWidget.hxx | 2 +- src/gui/FileListWidget.hxx | 2 +- src/gui/GameInfoDialog.hxx | 2 +- src/gui/GlobalPropsDialog.hxx | 2 +- src/gui/GuiObject.hxx | 2 +- src/gui/HelpDialog.hxx | 2 +- src/gui/InputDialog.hxx | 2 +- src/gui/InputTextDialog.hxx | 2 +- src/gui/JoystickDialog.hxx | 2 +- src/gui/Launcher.hxx | 2 +- src/gui/LauncherDialog.hxx | 2 +- src/gui/ListWidget.hxx | 2 +- src/gui/LoggerDialog.hxx | 2 +- src/gui/Menu.hxx | 2 +- src/gui/MessageBox.hxx | 2 +- src/gui/MessageDialog.hxx | 2 +- src/gui/MessageMenu.hxx | 38 +++++++------- src/gui/MinUICommandDialog.hxx | 2 +- src/gui/OptionsDialog.hxx | 2 +- src/gui/PopUpWidget.hxx | 2 +- src/gui/ProgressDialog.hxx | 2 +- src/gui/R77HelpDialog.hxx | 2 +- src/gui/RomAuditDialog.hxx | 2 +- src/gui/RomInfoWidget.hxx | 2 +- src/gui/ScrollBarWidget.hxx | 2 +- src/gui/SnapshotDialog.hxx | 2 +- src/gui/StellaSettingsDialog.hxx | 2 +- src/gui/StringListWidget.hxx | 2 +- src/gui/TabWidget.hxx | 2 +- src/gui/TimeMachine.hxx | 2 +- src/gui/TimeMachineDialog.hxx | 2 +- src/gui/UIDialog.hxx | 2 +- src/gui/VideoAudioDialog.hxx | 2 +- src/gui/WhatsNewDialog.hxx | 2 +- src/gui/Widget.hxx | 10 ++-- src/libretro/EventHandlerLIBRETRO.cxx | 6 ++- src/libretro/EventHandlerLIBRETRO.hxx | 2 +- src/libretro/FBSurfaceLIBRETRO.hxx | 2 +- src/libretro/FrameBufferLIBRETRO.hxx | 2 +- src/libretro/OSystemLIBRETRO.hxx | 2 +- src/libretro/SoundLIBRETRO.hxx | 8 +-- src/libretro/StellaLIBRETRO.hxx | 1 - src/macos/OSystemMACOS.hxx | 2 +- src/macos/SerialPortMACOS.hxx | 2 +- src/unix/OSystemUNIX.hxx | 2 +- src/unix/SerialPortUNIX.hxx | 2 +- src/unix/r77/OSystemR77.hxx | 2 +- src/unix/r77/SettingsR77.hxx | 2 +- src/windows/OSystemWINDOWS.hxx | 2 +- src/windows/SerialPortWINDOWS.hxx | 2 +- 232 files changed, 287 insertions(+), 308 deletions(-) diff --git a/src/cheat/BankRomCheat.hxx b/src/cheat/BankRomCheat.hxx index add1b5481..c8360eb27 100644 --- a/src/cheat/BankRomCheat.hxx +++ b/src/cheat/BankRomCheat.hxx @@ -24,7 +24,7 @@ class BankRomCheat : public Cheat { public: BankRomCheat(OSystem& os, const string& name, const string& code); - virtual ~BankRomCheat() = default; + ~BankRomCheat() override = default; bool enable() override; bool disable() override; diff --git a/src/cheat/CheatCodeDialog.hxx b/src/cheat/CheatCodeDialog.hxx index 51615f702..9ac69740c 100644 --- a/src/cheat/CheatCodeDialog.hxx +++ b/src/cheat/CheatCodeDialog.hxx @@ -36,7 +36,7 @@ class CheatCodeDialog : public Dialog public: CheatCodeDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font); - virtual ~CheatCodeDialog(); + ~CheatCodeDialog() override; protected: void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/cheat/CheetahCheat.hxx b/src/cheat/CheetahCheat.hxx index c82baedb2..c5a2e1384 100644 --- a/src/cheat/CheetahCheat.hxx +++ b/src/cheat/CheetahCheat.hxx @@ -24,7 +24,7 @@ class CheetahCheat : public Cheat { public: CheetahCheat(OSystem& os, const string& name, const string& code); - virtual ~CheetahCheat() = default; + ~CheetahCheat() override = default; bool enable() override; bool disable() override; diff --git a/src/cheat/RamCheat.hxx b/src/cheat/RamCheat.hxx index 57fcf7968..a7a522973 100644 --- a/src/cheat/RamCheat.hxx +++ b/src/cheat/RamCheat.hxx @@ -24,7 +24,7 @@ class RamCheat : public Cheat { public: RamCheat(OSystem& os, const string& name, const string& code); - virtual ~RamCheat() = default; + ~RamCheat() override = default; bool enable() override; bool disable() override; diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index 57569a6c1..2e8b60323 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -220,7 +220,6 @@ void EventHandlerSDL2::pollEvent() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx) - : myStick(nullptr) { ASSERT_MAIN_THREAD; diff --git a/src/common/EventHandlerSDL2.hxx b/src/common/EventHandlerSDL2.hxx index 840b1fadb..2fea58371 100644 --- a/src/common/EventHandlerSDL2.hxx +++ b/src/common/EventHandlerSDL2.hxx @@ -36,7 +36,7 @@ class EventHandlerSDL2 : public EventHandler Create a new SDL2 event handler object */ explicit EventHandlerSDL2(OSystem& osystem); - virtual ~EventHandlerSDL2(); + ~EventHandlerSDL2() override; private: /** @@ -61,7 +61,7 @@ class EventHandlerSDL2 : public EventHandler virtual ~JoystickSDL2(); private: - SDL_Joystick* myStick; + SDL_Joystick* myStick{nullptr}; }; private: diff --git a/src/common/FBSurfaceSDL2.hxx b/src/common/FBSurfaceSDL2.hxx index cf927c0f9..62e9d96a2 100644 --- a/src/common/FBSurfaceSDL2.hxx +++ b/src/common/FBSurfaceSDL2.hxx @@ -35,7 +35,7 @@ class FBSurfaceSDL2 : public FBSurface FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height, FrameBuffer::ScalingInterpolation interpolation, const uInt32* staticData); - virtual ~FBSurfaceSDL2(); + ~FBSurfaceSDL2() override; // Most of the surface drawing primitives are implemented in FBSurface; // the ones implemented here use SDL-specific code for extra performance diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 7904ed0ee..0b3386d08 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -39,7 +39,7 @@ class FrameBufferSDL2 : public FrameBuffer Creates a new SDL2 framebuffer */ explicit FrameBufferSDL2(OSystem& osystem); - virtual ~FrameBufferSDL2(); + ~FrameBufferSDL2() override; ////////////////////////////////////////////////////////////////////// // The following are derived from public methods in FrameBuffer.hxx diff --git a/src/common/PaletteHandler.hxx b/src/common/PaletteHandler.hxx index ed46da516..956fcf9b3 100644 --- a/src/common/PaletteHandler.hxx +++ b/src/common/PaletteHandler.hxx @@ -54,7 +54,6 @@ class PaletteHandler public: PaletteHandler(OSystem& system); - virtual ~PaletteHandler() = default; /** Cycle through available palettes. diff --git a/src/common/SoundNull.hxx b/src/common/SoundNull.hxx index 6bd9db54d..24dfa4620 100644 --- a/src/common/SoundNull.hxx +++ b/src/common/SoundNull.hxx @@ -43,11 +43,7 @@ class SoundNull : public Sound { Logger::info("Sound disabled.\n"); } - - /** - Destructor - */ - virtual ~SoundNull() = default; + ~SoundNull() override = default; public: /** diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index 586e90ff8..e760aa70b 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -48,7 +48,7 @@ class SoundSDL2 : public Sound /** Destructor */ - virtual ~SoundSDL2(); + ~SoundSDL2() override; public: /** diff --git a/src/common/sdl_blitter/BilinearBlitter.hxx b/src/common/sdl_blitter/BilinearBlitter.hxx index 84c550ad1..8588e390e 100644 --- a/src/common/sdl_blitter/BilinearBlitter.hxx +++ b/src/common/sdl_blitter/BilinearBlitter.hxx @@ -29,7 +29,7 @@ class BilinearBlitter : public Blitter { BilinearBlitter(FrameBufferSDL2& fb, bool interpolate); - virtual ~BilinearBlitter(); + ~BilinearBlitter() override; virtual void reinitialize( SDL_Rect srcRect, diff --git a/src/common/sdl_blitter/QisBlitter.hxx b/src/common/sdl_blitter/QisBlitter.hxx index 14ee84fcc..9aa68e4c0 100644 --- a/src/common/sdl_blitter/QisBlitter.hxx +++ b/src/common/sdl_blitter/QisBlitter.hxx @@ -31,7 +31,7 @@ class QisBlitter : public Blitter { static bool isSupported(FrameBufferSDL2 &fb); - virtual ~QisBlitter(); + ~QisBlitter() override; virtual void reinitialize( SDL_Rect srcRect, diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index 4ab326be1..9d71de51b 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -70,7 +70,7 @@ class CartDebug : public DebuggerSystem public: CartDebug(Debugger& dbg, Console& console, const OSystem& osystem); - virtual ~CartDebug() = default; + ~CartDebug() override = default; const DebuggerState& getState() override; const DebuggerState& getOldState() override { return myOldState; } diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 6083d556a..6435a6d1a 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -73,7 +73,7 @@ class Debugger : public DialogContainer Create a new debugger parent object */ Debugger(OSystem& osystem, Console& console); - virtual ~Debugger(); + ~Debugger() override; private: static const Int8 ANY_BANK = -1; diff --git a/src/debugger/DebuggerSystem.hxx b/src/debugger/DebuggerSystem.hxx index 904b0beed..acdf78389 100644 --- a/src/debugger/DebuggerSystem.hxx +++ b/src/debugger/DebuggerSystem.hxx @@ -31,7 +31,7 @@ class DebuggerState { public: DebuggerState() = default; - ~DebuggerState() = default; + virtual ~DebuggerState() = default; DebuggerState(const DebuggerState&) = default; DebuggerState(DebuggerState&&) = delete; diff --git a/src/debugger/gui/AmigaMouseWidget.hxx b/src/debugger/gui/AmigaMouseWidget.hxx index 622a24a9e..520f3f886 100644 --- a/src/debugger/gui/AmigaMouseWidget.hxx +++ b/src/debugger/gui/AmigaMouseWidget.hxx @@ -28,7 +28,7 @@ class AmigaMouseWidget : public PointingDeviceWidget AmigaMouseWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~AmigaMouseWidget() = default; + ~AmigaMouseWidget() override = default; private: const std::array myGrayCodeTable = { 0b00, 0b10, 0b11, 0b01 }; diff --git a/src/debugger/gui/AtariMouseWidget.hxx b/src/debugger/gui/AtariMouseWidget.hxx index 904430721..2b3554630 100644 --- a/src/debugger/gui/AtariMouseWidget.hxx +++ b/src/debugger/gui/AtariMouseWidget.hxx @@ -27,8 +27,7 @@ class AtariMouseWidget : public PointingDeviceWidget public: AtariMouseWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - - virtual ~AtariMouseWidget() = default; + ~AtariMouseWidget() override = default; private: const std::array myGrayCodeTable = { 0b00, 0b01, 0b11, 0b10 }; diff --git a/src/debugger/gui/AtariVoxWidget.hxx b/src/debugger/gui/AtariVoxWidget.hxx index c205b811d..cf168173d 100644 --- a/src/debugger/gui/AtariVoxWidget.hxx +++ b/src/debugger/gui/AtariVoxWidget.hxx @@ -27,7 +27,7 @@ class AtariVoxWidget : public FlashWidget public: AtariVoxWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~AtariVoxWidget() = default; + ~AtariVoxWidget() override = default; private: void eraseCurrent() override; diff --git a/src/debugger/gui/AudioWidget.hxx b/src/debugger/gui/AudioWidget.hxx index a1a0790ce..7427fe477 100644 --- a/src/debugger/gui/AudioWidget.hxx +++ b/src/debugger/gui/AudioWidget.hxx @@ -29,7 +29,7 @@ class AudioWidget : public Widget, public CommandSender public: AudioWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h); - virtual ~AudioWidget() = default; + ~AudioWidget() override = default; private: // ID's for the various widgets diff --git a/src/debugger/gui/BoosterWidget.hxx b/src/debugger/gui/BoosterWidget.hxx index 09a29cd0f..e82d16888 100644 --- a/src/debugger/gui/BoosterWidget.hxx +++ b/src/debugger/gui/BoosterWidget.hxx @@ -26,7 +26,7 @@ class BoosterWidget : public ControllerWidget public: BoosterWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~BoosterWidget() = default; + ~BoosterWidget() override = default; private: enum { kJUp = 0, kJDown, kJLeft, kJRight, kJFire, kJBooster, kJTrigger }; diff --git a/src/debugger/gui/Cart0840Widget.hxx b/src/debugger/gui/Cart0840Widget.hxx index 00605b262..49e2ed8df 100644 --- a/src/debugger/gui/Cart0840Widget.hxx +++ b/src/debugger/gui/Cart0840Widget.hxx @@ -29,7 +29,7 @@ class Cartridge0840Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge0840& cart); - virtual ~Cartridge0840Widget() = default; + ~Cartridge0840Widget() override = default; private: string manufacturer() override { return "Fred X. Quimby"; } diff --git a/src/debugger/gui/Cart2KWidget.hxx b/src/debugger/gui/Cart2KWidget.hxx index 123e3ddf5..e41fe3915 100644 --- a/src/debugger/gui/Cart2KWidget.hxx +++ b/src/debugger/gui/Cart2KWidget.hxx @@ -29,7 +29,7 @@ class Cartridge2KWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge2K& cart); - virtual ~Cartridge2KWidget() = default; + ~Cartridge2KWidget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/Cart3EPlusWidget.hxx b/src/debugger/gui/Cart3EPlusWidget.hxx index 44473e0cf..e7d47e041 100644 --- a/src/debugger/gui/Cart3EPlusWidget.hxx +++ b/src/debugger/gui/Cart3EPlusWidget.hxx @@ -32,7 +32,7 @@ class Cartridge3EPlusWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge3EPlus& cart); - virtual ~Cartridge3EPlusWidget() = default; + ~Cartridge3EPlusWidget() override = default; private: string manufacturer() override { return "Thomas Jentzsch"; } diff --git a/src/debugger/gui/Cart3EWidget.hxx b/src/debugger/gui/Cart3EWidget.hxx index 424d9a577..c6c2b2180 100644 --- a/src/debugger/gui/Cart3EWidget.hxx +++ b/src/debugger/gui/Cart3EWidget.hxx @@ -31,7 +31,7 @@ class Cartridge3EWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge3E& cart); - virtual ~Cartridge3EWidget() = default; + ~Cartridge3EWidget() override = default; private: enum { diff --git a/src/debugger/gui/Cart3FWidget.hxx b/src/debugger/gui/Cart3FWidget.hxx index ad24d8e56..8e73988d9 100644 --- a/src/debugger/gui/Cart3FWidget.hxx +++ b/src/debugger/gui/Cart3FWidget.hxx @@ -29,7 +29,7 @@ class Cartridge3FWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge3F& cart); - virtual ~Cartridge3FWidget() = default; + ~Cartridge3FWidget() override = default; private: string manufacturer() override { return "TigerVision"; } diff --git a/src/debugger/gui/Cart4A50Widget.hxx b/src/debugger/gui/Cart4A50Widget.hxx index 180cf24c4..5df9576e9 100644 --- a/src/debugger/gui/Cart4A50Widget.hxx +++ b/src/debugger/gui/Cart4A50Widget.hxx @@ -30,7 +30,7 @@ class Cartridge4A50Widget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge4A50& cart); - virtual ~Cartridge4A50Widget() = default; + ~Cartridge4A50Widget() override = default; private: Cartridge4A50& myCart; diff --git a/src/debugger/gui/Cart4KSCWidget.hxx b/src/debugger/gui/Cart4KSCWidget.hxx index 624a5623a..3ac605dc1 100644 --- a/src/debugger/gui/Cart4KSCWidget.hxx +++ b/src/debugger/gui/Cart4KSCWidget.hxx @@ -29,7 +29,7 @@ class Cartridge4KSCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge4KSC& cart); - virtual ~Cartridge4KSCWidget() = default; + ~Cartridge4KSCWidget() override = default; private: string manufacturer() override { return "homebrew intermediate format"; } diff --git a/src/debugger/gui/Cart4KWidget.hxx b/src/debugger/gui/Cart4KWidget.hxx index 3fd18eb66..19d3c70b0 100644 --- a/src/debugger/gui/Cart4KWidget.hxx +++ b/src/debugger/gui/Cart4KWidget.hxx @@ -29,7 +29,7 @@ class Cartridge4KWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, Cartridge4K& cart); - virtual ~Cartridge4KWidget() = default; + ~Cartridge4KWidget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/CartARWidget.hxx b/src/debugger/gui/CartARWidget.hxx index 52e46c595..22fb85bcb 100644 --- a/src/debugger/gui/CartARWidget.hxx +++ b/src/debugger/gui/CartARWidget.hxx @@ -30,7 +30,7 @@ class CartridgeARWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeAR& cart); - virtual ~CartridgeARWidget() = default; + ~CartridgeARWidget() override = default; private: CartridgeAR& myCart; diff --git a/src/debugger/gui/CartBFSCWidget.hxx b/src/debugger/gui/CartBFSCWidget.hxx index 739f41388..ecc1c5b71 100644 --- a/src/debugger/gui/CartBFSCWidget.hxx +++ b/src/debugger/gui/CartBFSCWidget.hxx @@ -29,7 +29,7 @@ class CartridgeBFSCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeBFSC& cart); - virtual ~CartridgeBFSCWidget() = default; + ~CartridgeBFSCWidget() override = default; private: string manufacturer() override { return "CPUWIZ"; } diff --git a/src/debugger/gui/CartBFWidget.hxx b/src/debugger/gui/CartBFWidget.hxx index b67391c63..b2effb8ba 100644 --- a/src/debugger/gui/CartBFWidget.hxx +++ b/src/debugger/gui/CartBFWidget.hxx @@ -29,7 +29,7 @@ class CartridgeBFWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeBF& cart); - virtual ~CartridgeBFWidget() = default; + ~CartridgeBFWidget() override = default; private: string manufacturer() override { return "CPUWIZ"; } diff --git a/src/debugger/gui/CartBUSWidget.hxx b/src/debugger/gui/CartBUSWidget.hxx index 09d23e784..cf975f18b 100644 --- a/src/debugger/gui/CartBUSWidget.hxx +++ b/src/debugger/gui/CartBUSWidget.hxx @@ -32,7 +32,7 @@ class CartridgeBUSWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeBUS& cart); - virtual ~CartridgeBUSWidget() = default; + ~CartridgeBUSWidget() override = default; private: struct CartState { diff --git a/src/debugger/gui/CartCDFInfoWidget.hxx b/src/debugger/gui/CartCDFInfoWidget.hxx index 1a003e2bd..c7867a38d 100644 --- a/src/debugger/gui/CartCDFInfoWidget.hxx +++ b/src/debugger/gui/CartCDFInfoWidget.hxx @@ -28,7 +28,7 @@ class CartridgeCDFInfoWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeCDF& cart); - virtual ~CartridgeCDFInfoWidget() = default; + ~CartridgeCDFInfoWidget() override = default; private: static string describeCDFVersion(CartridgeCDF::CDFSubtype subtype); diff --git a/src/debugger/gui/CartCDFWidget.hxx b/src/debugger/gui/CartCDFWidget.hxx index c0591d795..fdf5622a9 100644 --- a/src/debugger/gui/CartCDFWidget.hxx +++ b/src/debugger/gui/CartCDFWidget.hxx @@ -33,7 +33,7 @@ class CartridgeCDFWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeCDF& cart); - virtual ~CartridgeCDFWidget() = default; + ~CartridgeCDFWidget() override = default; private: struct CartState { diff --git a/src/debugger/gui/CartCMWidget.hxx b/src/debugger/gui/CartCMWidget.hxx index 04651666b..2ee085000 100644 --- a/src/debugger/gui/CartCMWidget.hxx +++ b/src/debugger/gui/CartCMWidget.hxx @@ -34,7 +34,7 @@ class CartridgeCMWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeCM& cart); - virtual ~CartridgeCMWidget() = default; + ~CartridgeCMWidget() override = default; private: struct CartState { diff --git a/src/debugger/gui/CartCTYWidget.hxx b/src/debugger/gui/CartCTYWidget.hxx index 18caa76a5..7c7ec24bd 100644 --- a/src/debugger/gui/CartCTYWidget.hxx +++ b/src/debugger/gui/CartCTYWidget.hxx @@ -30,7 +30,7 @@ class CartridgeCTYWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeCTY& cart); - virtual ~CartridgeCTYWidget() = default; + ~CartridgeCTYWidget() override = default; private: CartridgeCTY& myCart; diff --git a/src/debugger/gui/CartCVWidget.hxx b/src/debugger/gui/CartCVWidget.hxx index 63fc6f237..079cc76f1 100644 --- a/src/debugger/gui/CartCVWidget.hxx +++ b/src/debugger/gui/CartCVWidget.hxx @@ -29,7 +29,7 @@ class CartridgeCVWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeCV& cart); - virtual ~CartridgeCVWidget() = default; + ~CartridgeCVWidget() override = default; private: string manufacturer() override { return "CommaVid"; } diff --git a/src/debugger/gui/CartDFSCWidget.hxx b/src/debugger/gui/CartDFSCWidget.hxx index 9e4481fa8..9017e253b 100644 --- a/src/debugger/gui/CartDFSCWidget.hxx +++ b/src/debugger/gui/CartDFSCWidget.hxx @@ -29,7 +29,7 @@ class CartridgeDFSCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDFSC& cart); - virtual ~CartridgeDFSCWidget() = default; + ~CartridgeDFSCWidget() override = default; private: string manufacturer() override { return "CPUWIZ"; } diff --git a/src/debugger/gui/CartDFWidget.hxx b/src/debugger/gui/CartDFWidget.hxx index 9b45552b9..df7acaf05 100644 --- a/src/debugger/gui/CartDFWidget.hxx +++ b/src/debugger/gui/CartDFWidget.hxx @@ -29,7 +29,7 @@ class CartridgeDFWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDF& cart); - virtual ~CartridgeDFWidget() = default; + ~CartridgeDFWidget() override = default; private: string manufacturer() override { return "CPUWIZ"; } diff --git a/src/debugger/gui/CartDPCPlusWidget.hxx b/src/debugger/gui/CartDPCPlusWidget.hxx index 88e38d2e6..2e800dd28 100644 --- a/src/debugger/gui/CartDPCPlusWidget.hxx +++ b/src/debugger/gui/CartDPCPlusWidget.hxx @@ -32,7 +32,7 @@ class CartridgeDPCPlusWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDPCPlus& cart); - virtual ~CartridgeDPCPlusWidget() = default; + ~CartridgeDPCPlusWidget() override = default; private: struct CartState { diff --git a/src/debugger/gui/CartDPCWidget.hxx b/src/debugger/gui/CartDPCWidget.hxx index 0a675a2c8..2beeacead 100644 --- a/src/debugger/gui/CartDPCWidget.hxx +++ b/src/debugger/gui/CartDPCWidget.hxx @@ -31,7 +31,7 @@ class CartridgeDPCWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDPC& cart); - virtual ~CartridgeDPCWidget() = default; + ~CartridgeDPCWidget() override = default; private: struct CartState { diff --git a/src/debugger/gui/CartDebugWidget.hxx b/src/debugger/gui/CartDebugWidget.hxx index 27c3befa5..22554a472 100644 --- a/src/debugger/gui/CartDebugWidget.hxx +++ b/src/debugger/gui/CartDebugWidget.hxx @@ -35,7 +35,7 @@ class CartDebugWidget : public Widget, public CommandSender CartDebugWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h); - virtual ~CartDebugWidget() = default; + ~CartDebugWidget() override = default; public: int addBaseInformation(size_t bytes, const string& manufacturer, diff --git a/src/debugger/gui/CartE0Widget.hxx b/src/debugger/gui/CartE0Widget.hxx index a50893e84..9c8ab185f 100644 --- a/src/debugger/gui/CartE0Widget.hxx +++ b/src/debugger/gui/CartE0Widget.hxx @@ -29,7 +29,7 @@ class CartridgeE0Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeE0& cart); - virtual ~CartridgeE0Widget() = default; + ~CartridgeE0Widget() override = default; private: string manufacturer() override { return "Parker Brothers"; } diff --git a/src/debugger/gui/CartE78KWidget.hxx b/src/debugger/gui/CartE78KWidget.hxx index 7007e7aef..1b28de3ee 100644 --- a/src/debugger/gui/CartE78KWidget.hxx +++ b/src/debugger/gui/CartE78KWidget.hxx @@ -27,7 +27,7 @@ class CartridgeE78KWidget : public CartridgeMNetworkWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeMNetwork& cart); - virtual ~CartridgeE78KWidget() = default; + ~CartridgeE78KWidget() override = default; protected: const char* getSpotLower(int idx) override; diff --git a/src/debugger/gui/CartE7Widget.hxx b/src/debugger/gui/CartE7Widget.hxx index 8258f6ed1..3620529c7 100644 --- a/src/debugger/gui/CartE7Widget.hxx +++ b/src/debugger/gui/CartE7Widget.hxx @@ -27,7 +27,7 @@ class CartridgeE7Widget : public CartridgeMNetworkWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeMNetwork& cart); - virtual ~CartridgeE7Widget() = default; + ~CartridgeE7Widget() override = default; protected: const char* getSpotLower(int idx) override; diff --git a/src/debugger/gui/CartEFSCWidget.hxx b/src/debugger/gui/CartEFSCWidget.hxx index 975f17f8a..c5517e9c0 100644 --- a/src/debugger/gui/CartEFSCWidget.hxx +++ b/src/debugger/gui/CartEFSCWidget.hxx @@ -29,7 +29,7 @@ class CartridgeEFSCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEFSC& cart); - virtual ~CartridgeEFSCWidget() = default; + ~CartridgeEFSCWidget() override = default; private: string manufacturer() override { return "Paul Slocum / Homestar Runner"; } diff --git a/src/debugger/gui/CartEFWidget.hxx b/src/debugger/gui/CartEFWidget.hxx index 7d173836a..6e0407046 100644 --- a/src/debugger/gui/CartEFWidget.hxx +++ b/src/debugger/gui/CartEFWidget.hxx @@ -29,7 +29,7 @@ class CartridgeEFWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEF& cart); - virtual ~CartridgeEFWidget() = default; + ~CartridgeEFWidget() override = default; private: string manufacturer() override { return "Paul Slocum / Homestar Runner"; } diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx index a367e8def..bebbdcf5d 100644 --- a/src/debugger/gui/CartEnhancedWidget.hxx +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -35,7 +35,7 @@ class CartridgeEnhancedWidget : public CartDebugWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEnhanced& cart); - virtual ~CartridgeEnhancedWidget() = default; + ~CartridgeEnhancedWidget() override = default; protected: int initialize(); diff --git a/src/debugger/gui/CartF0Widget.hxx b/src/debugger/gui/CartF0Widget.hxx index 017d88e78..b772489cf 100644 --- a/src/debugger/gui/CartF0Widget.hxx +++ b/src/debugger/gui/CartF0Widget.hxx @@ -29,7 +29,7 @@ class CartridgeF0Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF0& cart); - virtual ~CartridgeF0Widget() = default; + ~CartridgeF0Widget() override = default; private: string manufacturer() override { return "Dynacom Megaboy"; } diff --git a/src/debugger/gui/CartF4SCWidget.hxx b/src/debugger/gui/CartF4SCWidget.hxx index c6570a9fa..fccc1294f 100644 --- a/src/debugger/gui/CartF4SCWidget.hxx +++ b/src/debugger/gui/CartF4SCWidget.hxx @@ -29,7 +29,7 @@ class CartridgeF4SCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF4SC& cart); - virtual ~CartridgeF4SCWidget() = default; + ~CartridgeF4SCWidget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/CartF4Widget.hxx b/src/debugger/gui/CartF4Widget.hxx index d444a5956..67669cd32 100644 --- a/src/debugger/gui/CartF4Widget.hxx +++ b/src/debugger/gui/CartF4Widget.hxx @@ -29,7 +29,7 @@ class CartridgeF4Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF4& cart); - virtual ~CartridgeF4Widget() = default; + ~CartridgeF4Widget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/CartF6SCWidget.hxx b/src/debugger/gui/CartF6SCWidget.hxx index 1ed6378a7..ce34c61ea 100644 --- a/src/debugger/gui/CartF6SCWidget.hxx +++ b/src/debugger/gui/CartF6SCWidget.hxx @@ -29,7 +29,7 @@ class CartridgeF6SCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF6SC& cart); - virtual ~CartridgeF6SCWidget() = default; + ~CartridgeF6SCWidget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/CartF6Widget.hxx b/src/debugger/gui/CartF6Widget.hxx index 2d0eb3734..3aafaf07c 100644 --- a/src/debugger/gui/CartF6Widget.hxx +++ b/src/debugger/gui/CartF6Widget.hxx @@ -29,7 +29,7 @@ class CartridgeF6Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF6& cart); - virtual ~CartridgeF6Widget() = default; + ~CartridgeF6Widget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/CartF8SCWidget.hxx b/src/debugger/gui/CartF8SCWidget.hxx index 3f6199783..22b22fd71 100644 --- a/src/debugger/gui/CartF8SCWidget.hxx +++ b/src/debugger/gui/CartF8SCWidget.hxx @@ -29,7 +29,7 @@ class CartridgeF8SCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF8SC& cart); - virtual ~CartridgeF8SCWidget() = default; + ~CartridgeF8SCWidget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/CartF8Widget.hxx b/src/debugger/gui/CartF8Widget.hxx index a0577f250..7f7d4514b 100644 --- a/src/debugger/gui/CartF8Widget.hxx +++ b/src/debugger/gui/CartF8Widget.hxx @@ -30,7 +30,7 @@ class CartridgeF8Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF8& cart); - virtual ~CartridgeF8Widget() = default; + ~CartridgeF8Widget() override = default; private: string manufacturer() override { return "Atari"; } diff --git a/src/debugger/gui/CartFA2Widget.hxx b/src/debugger/gui/CartFA2Widget.hxx index 06865c495..d697ac783 100644 --- a/src/debugger/gui/CartFA2Widget.hxx +++ b/src/debugger/gui/CartFA2Widget.hxx @@ -30,7 +30,7 @@ class CartridgeFA2Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFA2& cart); - virtual ~CartridgeFA2Widget() = default; + ~CartridgeFA2Widget() override = default; private: CartridgeFA2& myCartFA2; diff --git a/src/debugger/gui/CartFAWidget.hxx b/src/debugger/gui/CartFAWidget.hxx index 2d7311a71..8d278e4e8 100644 --- a/src/debugger/gui/CartFAWidget.hxx +++ b/src/debugger/gui/CartFAWidget.hxx @@ -29,7 +29,7 @@ class CartridgeFAWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFA& cart); - virtual ~CartridgeFAWidget() = default; + ~CartridgeFAWidget() override = default; private: string manufacturer() override { return "CBS"; } diff --git a/src/debugger/gui/CartFCWidget.hxx b/src/debugger/gui/CartFCWidget.hxx index f6d56af71..9e0a2a54a 100644 --- a/src/debugger/gui/CartFCWidget.hxx +++ b/src/debugger/gui/CartFCWidget.hxx @@ -29,7 +29,7 @@ class CartridgeFCWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFC& cart); - virtual ~CartridgeFCWidget() = default; + ~CartridgeFCWidget() override = default; private: string manufacturer() override { return "Amiga Corp."; } diff --git a/src/debugger/gui/CartFEWidget.hxx b/src/debugger/gui/CartFEWidget.hxx index 468fcc144..a8d0e22a0 100644 --- a/src/debugger/gui/CartFEWidget.hxx +++ b/src/debugger/gui/CartFEWidget.hxx @@ -29,7 +29,7 @@ class CartridgeFEWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFE& cart); - virtual ~CartridgeFEWidget() = default; + ~CartridgeFEWidget() override = default; private: string manufacturer() override { return "Activision"; } diff --git a/src/debugger/gui/CartMDMWidget.hxx b/src/debugger/gui/CartMDMWidget.hxx index c7add24d7..2927aceb5 100644 --- a/src/debugger/gui/CartMDMWidget.hxx +++ b/src/debugger/gui/CartMDMWidget.hxx @@ -30,7 +30,7 @@ class CartridgeMDMWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeMDM& cart); - virtual ~CartridgeMDMWidget() = default; + ~CartridgeMDMWidget() override = default; private: string manufacturer() override { return "Edwin Blink"; } diff --git a/src/debugger/gui/CartMNetworkWidget.hxx b/src/debugger/gui/CartMNetworkWidget.hxx index 4f0a5a0db..c8b258b4f 100644 --- a/src/debugger/gui/CartMNetworkWidget.hxx +++ b/src/debugger/gui/CartMNetworkWidget.hxx @@ -31,7 +31,7 @@ class CartridgeMNetworkWidget : public CartDebugWidget int x, int y, int w, int h, //CartridgeE7& cart); CartridgeMNetwork& cart); - virtual ~CartridgeMNetworkWidget() = default; + ~CartridgeMNetworkWidget() override = default; protected: //CartridgeE7& myCart; diff --git a/src/debugger/gui/CartRamWidget.hxx b/src/debugger/gui/CartRamWidget.hxx index 73aa698d0..bc0f4f810 100644 --- a/src/debugger/gui/CartRamWidget.hxx +++ b/src/debugger/gui/CartRamWidget.hxx @@ -34,7 +34,7 @@ class CartRamWidget : public Widget, public CommandSender CartRamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartDebugWidget& cartDebug); - virtual ~CartRamWidget() = default; + ~CartRamWidget() override = default; void loadConfig() override; void setOpsWidget(DataGridOpsWidget* w); @@ -66,7 +66,7 @@ class CartRamWidget : public Widget, public CommandSender const GUI::Font& nfont, int x, int y, int w, int h, CartDebugWidget& cartDebug); - virtual ~InternalRamWidget() = default; + ~InternalRamWidget() override = default; private: uInt8 getValue(int addr) const override; diff --git a/src/debugger/gui/CartSBWidget.hxx b/src/debugger/gui/CartSBWidget.hxx index 91cc90ec1..646865889 100644 --- a/src/debugger/gui/CartSBWidget.hxx +++ b/src/debugger/gui/CartSBWidget.hxx @@ -29,7 +29,7 @@ class CartridgeSBWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeSB& cart); - virtual ~CartridgeSBWidget() = default; + ~CartridgeSBWidget() override = default; private: string manufacturer() override { return "Fred X. Quimby"; } diff --git a/src/debugger/gui/CartTVBoyWidget.hxx b/src/debugger/gui/CartTVBoyWidget.hxx index e1c2780e6..709ddec2d 100644 --- a/src/debugger/gui/CartTVBoyWidget.hxx +++ b/src/debugger/gui/CartTVBoyWidget.hxx @@ -30,7 +30,7 @@ class CartridgeTVBoyWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeTVBoy& cart); - virtual ~CartridgeTVBoyWidget() = default; + ~CartridgeTVBoyWidget() override = default; private: string manufacturer() override { return "Akor"; } diff --git a/src/debugger/gui/CartUAWidget.hxx b/src/debugger/gui/CartUAWidget.hxx index a610a1316..efbce802a 100644 --- a/src/debugger/gui/CartUAWidget.hxx +++ b/src/debugger/gui/CartUAWidget.hxx @@ -29,7 +29,7 @@ class CartridgeUAWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeUA& cart, bool swapHotspots); - virtual ~CartridgeUAWidget() = default; + ~CartridgeUAWidget() override = default; private: string manufacturer() override { return "UA Limited"; } diff --git a/src/debugger/gui/CartWDWidget.hxx b/src/debugger/gui/CartWDWidget.hxx index 2ccdd7437..f68f1d96b 100644 --- a/src/debugger/gui/CartWDWidget.hxx +++ b/src/debugger/gui/CartWDWidget.hxx @@ -29,9 +29,9 @@ class CartridgeWDWidget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeWD& cart); - virtual ~CartridgeWDWidget() = default; + ~CartridgeWDWidget() override = default; -private: + private: CartridgeWD& myCartWD; private: diff --git a/src/debugger/gui/CartX07Widget.hxx b/src/debugger/gui/CartX07Widget.hxx index 58492e7e6..4d94fe2ab 100644 --- a/src/debugger/gui/CartX07Widget.hxx +++ b/src/debugger/gui/CartX07Widget.hxx @@ -29,7 +29,7 @@ class CartridgeX07Widget : public CartridgeEnhancedWidget const GUI::Font& nfont, int x, int y, int w, int h, CartridgeX07& cart); - virtual ~CartridgeX07Widget() = default; + ~CartridgeX07Widget() override = default; private: string manufacturer() override { return "AtariAge / John Payson / Fred Quimby"; } diff --git a/src/debugger/gui/ControllerWidget.hxx b/src/debugger/gui/ControllerWidget.hxx index d14c1ba69..e45ae2168 100644 --- a/src/debugger/gui/ControllerWidget.hxx +++ b/src/debugger/gui/ControllerWidget.hxx @@ -40,7 +40,7 @@ class ControllerWidget : public Widget, public CommandSender, public ControllerL _w = 18 * font.getMaxCharWidth(); _h = 8 * font.getLineHeight(); } - virtual ~ControllerWidget() = default; + ~ControllerWidget() override = default; virtual void loadConfig() override { } diff --git a/src/debugger/gui/CpuWidget.hxx b/src/debugger/gui/CpuWidget.hxx index 5992970f3..5d4a4893c 100644 --- a/src/debugger/gui/CpuWidget.hxx +++ b/src/debugger/gui/CpuWidget.hxx @@ -33,7 +33,7 @@ class CpuWidget : public Widget, public CommandSender public: CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int max_w); - virtual ~CpuWidget() = default; + ~CpuWidget() override = default; void setOpsWidget(DataGridOpsWidget* w); void loadConfig() override; diff --git a/src/debugger/gui/DataGridOpsWidget.hxx b/src/debugger/gui/DataGridOpsWidget.hxx index b40268d1c..d4d481ec9 100644 --- a/src/debugger/gui/DataGridOpsWidget.hxx +++ b/src/debugger/gui/DataGridOpsWidget.hxx @@ -36,7 +36,7 @@ class DataGridOpsWidget : public Widget, public CommandSender { public: DataGridOpsWidget(GuiObject* boss, const GUI::Font& font, int x, int y); - virtual ~DataGridOpsWidget() = default; + ~DataGridOpsWidget() override = default; void setTarget(CommandReceiver* target); void setEnabled(bool e); diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index 7810e2af9..f7d9988c5 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -45,7 +45,7 @@ class DataGridWidget : public EditableWidget int colchars, int bits, Common::Base::Fmt format = Common::Base::Fmt::_DEFAULT, bool useScrollbar = false); - virtual ~DataGridWidget() = default; + ~DataGridWidget() override = default; void setList(const IntArray& alist, const IntArray& vlist, const BoolArray& changed); diff --git a/src/debugger/gui/DebuggerDialog.hxx b/src/debugger/gui/DebuggerDialog.hxx index f38e8b2dc..0affa5160 100644 --- a/src/debugger/gui/DebuggerDialog.hxx +++ b/src/debugger/gui/DebuggerDialog.hxx @@ -57,7 +57,7 @@ class DebuggerDialog : public Dialog DebuggerDialog(OSystem& osystem, DialogContainer& parent, int x, int y, int w, int h); - virtual ~DebuggerDialog(); + ~DebuggerDialog() override; const GUI::Font& lfont() const { return *myLFont; } const GUI::Font& nfont() const { return *myNFont; } diff --git a/src/debugger/gui/DelayQueueWidget.hxx b/src/debugger/gui/DelayQueueWidget.hxx index bc1d2a8ec..e1eddc399 100644 --- a/src/debugger/gui/DelayQueueWidget.hxx +++ b/src/debugger/gui/DelayQueueWidget.hxx @@ -28,7 +28,7 @@ class DelayQueueWidget : public Widget const GUI::Font& font, int x, int y ); - virtual ~DelayQueueWidget() = default; + ~DelayQueueWidget() override = default; void loadConfig() override; diff --git a/src/debugger/gui/DrivingWidget.hxx b/src/debugger/gui/DrivingWidget.hxx index 711415d31..0ab6c1d15 100644 --- a/src/debugger/gui/DrivingWidget.hxx +++ b/src/debugger/gui/DrivingWidget.hxx @@ -30,7 +30,7 @@ class DrivingWidget : public ControllerWidget public: DrivingWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~DrivingWidget() = default; + ~DrivingWidget() override = default; private: enum { diff --git a/src/debugger/gui/FlashWidget.hxx b/src/debugger/gui/FlashWidget.hxx index b811ac9c2..cb085be9d 100644 --- a/src/debugger/gui/FlashWidget.hxx +++ b/src/debugger/gui/FlashWidget.hxx @@ -28,7 +28,7 @@ class FlashWidget : public ControllerWidget public: FlashWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~FlashWidget() = default; + ~FlashWidget() override = default; protected: void init(GuiObject* boss, const GUI::Font& font, int x, int y); diff --git a/src/debugger/gui/GenesisWidget.hxx b/src/debugger/gui/GenesisWidget.hxx index aa3098f8f..b16db9c9b 100644 --- a/src/debugger/gui/GenesisWidget.hxx +++ b/src/debugger/gui/GenesisWidget.hxx @@ -26,7 +26,7 @@ class GenesisWidget : public ControllerWidget public: GenesisWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~GenesisWidget() = default; + ~GenesisWidget() override = default; private: enum { kJUp = 0, kJDown, kJLeft, kJRight, kJBbtn, kJCbtn }; diff --git a/src/debugger/gui/JoystickWidget.hxx b/src/debugger/gui/JoystickWidget.hxx index e0a550a6f..1c1143b7f 100644 --- a/src/debugger/gui/JoystickWidget.hxx +++ b/src/debugger/gui/JoystickWidget.hxx @@ -26,7 +26,7 @@ class JoystickWidget : public ControllerWidget public: JoystickWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~JoystickWidget() = default; + ~JoystickWidget() override = default; private: enum { kJUp = 0, kJDown, kJLeft, kJRight, kJFire }; diff --git a/src/debugger/gui/KeyboardWidget.hxx b/src/debugger/gui/KeyboardWidget.hxx index b88434ef6..ca0a5984f 100644 --- a/src/debugger/gui/KeyboardWidget.hxx +++ b/src/debugger/gui/KeyboardWidget.hxx @@ -26,7 +26,7 @@ class KeyboardWidget : public ControllerWidget public: KeyboardWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~KeyboardWidget() = default; + ~KeyboardWidget() override = default; private: std::array myBox{nullptr}; diff --git a/src/debugger/gui/NullControlWidget.hxx b/src/debugger/gui/NullControlWidget.hxx index 7b7c83e73..79364ca6e 100644 --- a/src/debugger/gui/NullControlWidget.hxx +++ b/src/debugger/gui/NullControlWidget.hxx @@ -44,7 +44,7 @@ class NullControlWidget : public ControllerWidget TextAlign::Center); } - virtual ~NullControlWidget() = default; + ~NullControlWidget() override = default; private: // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/PaddleWidget.hxx b/src/debugger/gui/PaddleWidget.hxx index 1966299d8..8773b5a1d 100644 --- a/src/debugger/gui/PaddleWidget.hxx +++ b/src/debugger/gui/PaddleWidget.hxx @@ -27,7 +27,7 @@ class PaddleWidget : public ControllerWidget public: PaddleWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~PaddleWidget() = default; + ~PaddleWidget() override = default; private: enum { kP0Changed = 'P0ch', kP1Changed = 'P1ch', diff --git a/src/debugger/gui/PointingDeviceWidget.hxx b/src/debugger/gui/PointingDeviceWidget.hxx index 192f2519a..ae6157582 100644 --- a/src/debugger/gui/PointingDeviceWidget.hxx +++ b/src/debugger/gui/PointingDeviceWidget.hxx @@ -28,8 +28,7 @@ class PointingDeviceWidget : public ControllerWidget public: PointingDeviceWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - - virtual ~PointingDeviceWidget() = default; + ~PointingDeviceWidget() override = default; private: enum { diff --git a/src/debugger/gui/PromptWidget.hxx b/src/debugger/gui/PromptWidget.hxx index a58e16076..0570f025f 100644 --- a/src/debugger/gui/PromptWidget.hxx +++ b/src/debugger/gui/PromptWidget.hxx @@ -39,7 +39,7 @@ class PromptWidget : public Widget, public CommandSender public: PromptWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~PromptWidget() = default; + ~PromptWidget() override = default; public: ATTRIBUTE_FMT_PRINTF int printf(const char* format, ...); diff --git a/src/debugger/gui/RamWidget.hxx b/src/debugger/gui/RamWidget.hxx index 7c4ea99ef..3562187fb 100644 --- a/src/debugger/gui/RamWidget.hxx +++ b/src/debugger/gui/RamWidget.hxx @@ -35,7 +35,7 @@ class RamWidget : public Widget, public CommandSender RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, uInt32 ramsize, uInt32 numrows, uInt32 pagesize); - virtual ~RamWidget(); + ~RamWidget() override; void loadConfig() override; void setOpsWidget(DataGridOpsWidget* w); diff --git a/src/debugger/gui/RiotRamWidget.hxx b/src/debugger/gui/RiotRamWidget.hxx index 694b9af71..53d006bb0 100644 --- a/src/debugger/gui/RiotRamWidget.hxx +++ b/src/debugger/gui/RiotRamWidget.hxx @@ -34,7 +34,7 @@ class RiotRamWidget : public RamWidget public: RiotRamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w); - virtual ~RiotRamWidget() = default; + ~RiotRamWidget() override = default; private: uInt8 getValue(int addr) const override; diff --git a/src/debugger/gui/RiotWidget.hxx b/src/debugger/gui/RiotWidget.hxx index 3feb25ee3..fdfd699ef 100644 --- a/src/debugger/gui/RiotWidget.hxx +++ b/src/debugger/gui/RiotWidget.hxx @@ -34,7 +34,7 @@ class RiotWidget : public Widget, public CommandSender public: RiotWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h); - virtual ~RiotWidget() = default; + ~RiotWidget() override = default; private: ControllerWidget* addControlWidget(GuiObject* boss, const GUI::Font& font, diff --git a/src/debugger/gui/RomListSettings.hxx b/src/debugger/gui/RomListSettings.hxx index ba65c24a4..0845dd8ab 100644 --- a/src/debugger/gui/RomListSettings.hxx +++ b/src/debugger/gui/RomListSettings.hxx @@ -32,7 +32,7 @@ class RomListSettings : public Dialog, public CommandSender { public: RomListSettings(GuiObject* boss, const GUI::Font& font); - virtual ~RomListSettings() = default; + ~RomListSettings() override = default; /** Show dialog onscreen at the specified coordinates ('data' will be the currently selected line number in RomListWidget) */ diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx index 24861b157..40abb0adf 100644 --- a/src/debugger/gui/RomListWidget.hxx +++ b/src/debugger/gui/RomListWidget.hxx @@ -47,7 +47,7 @@ class RomListWidget : public EditableWidget public: RomListWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h); - virtual ~RomListWidget() = default; + ~RomListWidget() override = default; void setList(const CartDebug::Disassembly& disasm); diff --git a/src/debugger/gui/RomWidget.hxx b/src/debugger/gui/RomWidget.hxx index 8dc4aabee..adf9a4443 100644 --- a/src/debugger/gui/RomWidget.hxx +++ b/src/debugger/gui/RomWidget.hxx @@ -37,7 +37,7 @@ class RomWidget : public Widget, public CommandSender public: RomWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h); - virtual ~RomWidget() = default; + ~RomWidget() override = default; void invalidate(bool forcereload = true) { myListIsDirty = true; if(forcereload) loadConfig(); } diff --git a/src/debugger/gui/SaveKeyWidget.hxx b/src/debugger/gui/SaveKeyWidget.hxx index 287e98c22..3a646f2d4 100644 --- a/src/debugger/gui/SaveKeyWidget.hxx +++ b/src/debugger/gui/SaveKeyWidget.hxx @@ -27,7 +27,7 @@ class SaveKeyWidget : public FlashWidget public: SaveKeyWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~SaveKeyWidget() = default; + ~SaveKeyWidget() override = default; private: void eraseCurrent() override; diff --git a/src/debugger/gui/TiaInfoWidget.hxx b/src/debugger/gui/TiaInfoWidget.hxx index cfea723fb..2f7796162 100644 --- a/src/debugger/gui/TiaInfoWidget.hxx +++ b/src/debugger/gui/TiaInfoWidget.hxx @@ -31,7 +31,7 @@ class TiaInfoWidget : public Widget, public CommandSender public: TiaInfoWidget(GuiObject *boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int max_w); - virtual ~TiaInfoWidget() = default; + ~TiaInfoWidget() override = default; void loadConfig() override; diff --git a/src/debugger/gui/TiaOutputWidget.hxx b/src/debugger/gui/TiaOutputWidget.hxx index 722eac6aa..c7bfd26f6 100644 --- a/src/debugger/gui/TiaOutputWidget.hxx +++ b/src/debugger/gui/TiaOutputWidget.hxx @@ -31,7 +31,7 @@ class TiaOutputWidget : public Widget, public CommandSender public: TiaOutputWidget(GuiObject *boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~TiaOutputWidget() = default; + ~TiaOutputWidget() override = default; void loadConfig() override; void setZoomWidget(TiaZoomWidget* w) { myZoom = w; } diff --git a/src/debugger/gui/TiaWidget.hxx b/src/debugger/gui/TiaWidget.hxx index bc6c6c632..1f058d555 100644 --- a/src/debugger/gui/TiaWidget.hxx +++ b/src/debugger/gui/TiaWidget.hxx @@ -36,7 +36,7 @@ class TiaWidget : public Widget, public CommandSender public: TiaWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h); - virtual ~TiaWidget() = default; + ~TiaWidget() override = default; private: DataGridWidget* myColorRegs{nullptr}; diff --git a/src/debugger/gui/TiaZoomWidget.hxx b/src/debugger/gui/TiaZoomWidget.hxx index 91e511bda..d4d3a9835 100644 --- a/src/debugger/gui/TiaZoomWidget.hxx +++ b/src/debugger/gui/TiaZoomWidget.hxx @@ -29,7 +29,7 @@ class TiaZoomWidget : public Widget, public CommandSender public: TiaZoomWidget(GuiObject *boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~TiaZoomWidget() = default; + ~TiaZoomWidget() override = default; void loadConfig() override; void setPos(int x, int y); diff --git a/src/debugger/gui/ToggleBitWidget.hxx b/src/debugger/gui/ToggleBitWidget.hxx index 0f595091b..6d5505030 100644 --- a/src/debugger/gui/ToggleBitWidget.hxx +++ b/src/debugger/gui/ToggleBitWidget.hxx @@ -26,7 +26,7 @@ class ToggleBitWidget : public ToggleWidget public: ToggleBitWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int cols, int rows, int colchars = 1); - virtual ~ToggleBitWidget() = default; + ~ToggleBitWidget() override = default; void setList(const StringList& off, const StringList& on); void setState(const BoolArray& state, const BoolArray& changed); diff --git a/src/debugger/gui/TogglePixelWidget.hxx b/src/debugger/gui/TogglePixelWidget.hxx index 06dbc508d..6177cac45 100644 --- a/src/debugger/gui/TogglePixelWidget.hxx +++ b/src/debugger/gui/TogglePixelWidget.hxx @@ -26,7 +26,7 @@ class TogglePixelWidget : public ToggleWidget public: TogglePixelWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int cols, int rows); - virtual ~TogglePixelWidget() = default; + ~TogglePixelWidget() override = default; void setColor(ColorId color) { _pixelColor = color; } void clearColor() { _pixelColor = kDlgColor; } diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index b7540a90c..67777a13a 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -35,7 +35,7 @@ class ToggleWidget : public Widget, public CommandSender ToggleWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int cols, int rows, int clicksToChange = 2); - virtual ~ToggleWidget() = default; + ~ToggleWidget() override = default; const BoolArray& getState() { return _stateList; } bool getSelectedState() const { return _stateList[_selectedItem]; } diff --git a/src/debugger/gui/TrakBallWidget.hxx b/src/debugger/gui/TrakBallWidget.hxx index 1ac611ec3..470cd95b7 100644 --- a/src/debugger/gui/TrakBallWidget.hxx +++ b/src/debugger/gui/TrakBallWidget.hxx @@ -28,7 +28,7 @@ class TrakBallWidget : public PointingDeviceWidget TrakBallWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller); - virtual ~TrakBallWidget() = default; + ~TrakBallWidget() override = default; private: const std::array myGrayCodeTable = { 0b00, 0b10, 0b01, 0b11 }; diff --git a/src/emucore/AmigaMouse.hxx b/src/emucore/AmigaMouse.hxx index d34281d4d..1973cb3e3 100644 --- a/src/emucore/AmigaMouse.hxx +++ b/src/emucore/AmigaMouse.hxx @@ -33,7 +33,7 @@ class AmigaMouse : public PointingDevice AmigaMouse(Jack jack, const Event& event, const System& system) : PointingDevice(jack, event, system, Controller::Type::AmigaMouse, trackballSensitivity) { } - virtual ~AmigaMouse() = default; + ~AmigaMouse() override = default; /** Returns the name of this controller. diff --git a/src/emucore/AtariMouse.hxx b/src/emucore/AtariMouse.hxx index 2ecb587c4..1696aa67d 100644 --- a/src/emucore/AtariMouse.hxx +++ b/src/emucore/AtariMouse.hxx @@ -33,7 +33,7 @@ class AtariMouse : public PointingDevice AtariMouse(Jack jack, const Event& event, const System& system) : PointingDevice(jack, event, system, Controller::Type::AtariMouse, trackballSensitivity) { } - virtual ~AtariMouse() = default; + ~AtariMouse() override = default; /** Returns the name of this controller. diff --git a/src/emucore/AtariVox.hxx b/src/emucore/AtariVox.hxx index 132b2c377..d868338ed 100644 --- a/src/emucore/AtariVox.hxx +++ b/src/emucore/AtariVox.hxx @@ -50,7 +50,7 @@ class AtariVox : public SaveKey AtariVox(Jack jack, const Event& event, const System& system, const string& portname, const FilesystemNode& eepromfile, const onMessageCallback& callback); - virtual ~AtariVox(); + ~AtariVox() override; public: using Controller::read; diff --git a/src/emucore/Booster.hxx b/src/emucore/Booster.hxx index 866c90811..97d519da7 100644 --- a/src/emucore/Booster.hxx +++ b/src/emucore/Booster.hxx @@ -39,7 +39,7 @@ class BoosterGrip : public Controller @param system The system using this controller */ BoosterGrip(Jack jack, const Event& event, const System& system); - virtual ~BoosterGrip() = default; + ~BoosterGrip() override = default; public: /** diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index 008135a73..5c3b65af2 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -60,7 +60,7 @@ class Cartridge : public Device @param md5 The md5sum of the cart image */ Cartridge(const Settings& settings, const string& md5); - virtual ~Cartridge() = default; + ~Cartridge() override = default; /** Set/query some information about this cartridge. diff --git a/src/emucore/Cart0840.hxx b/src/emucore/Cart0840.hxx index 0d120aad4..2ac1dca71 100644 --- a/src/emucore/Cart0840.hxx +++ b/src/emucore/Cart0840.hxx @@ -48,7 +48,7 @@ class Cartridge0840 : public CartridgeEnhanced */ Cartridge0840(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 8_KB); - virtual ~Cartridge0840() = default; + ~Cartridge0840() override = default; public: /** diff --git a/src/emucore/Cart2K.hxx b/src/emucore/Cart2K.hxx index 878df4714..5d2542c55 100644 --- a/src/emucore/Cart2K.hxx +++ b/src/emucore/Cart2K.hxx @@ -51,7 +51,7 @@ class Cartridge2K : public CartridgeEnhanced */ Cartridge2K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 2_KB); - virtual ~Cartridge2K() = default; + ~Cartridge2K() override = default; public: /** diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index 60e50613a..a181b84d9 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -76,7 +76,7 @@ class Cartridge3E : public CartridgeEnhanced */ Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 0); - virtual ~Cartridge3E() = default; + ~Cartridge3E() override = default; public: diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index 2ba54d313..bdb8f85f5 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -99,7 +99,7 @@ class Cartridge3EPlus: public Cartridge3E */ Cartridge3EPlus(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 0); - virtual ~Cartridge3EPlus() = default; + ~Cartridge3EPlus() override = default; public: /** Reset device to its power-on state */ diff --git a/src/emucore/Cart3EX.hxx b/src/emucore/Cart3EX.hxx index c949a0c9c..19e33169f 100644 --- a/src/emucore/Cart3EX.hxx +++ b/src/emucore/Cart3EX.hxx @@ -43,7 +43,7 @@ class Cartridge3EX : public Cartridge3E */ Cartridge3EX(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~Cartridge3EX() = default; + ~Cartridge3EX() override = default; public: /** diff --git a/src/emucore/Cart3F.hxx b/src/emucore/Cart3F.hxx index f5eeac809..fee14e97e 100644 --- a/src/emucore/Cart3F.hxx +++ b/src/emucore/Cart3F.hxx @@ -55,7 +55,7 @@ class Cartridge3F : public CartridgeEnhanced */ Cartridge3F(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 0); - virtual ~Cartridge3F() = default; + ~Cartridge3F() override = default; public: /** diff --git a/src/emucore/Cart4A50.hxx b/src/emucore/Cart4A50.hxx index 8a4fdaa2d..afa3a489c 100644 --- a/src/emucore/Cart4A50.hxx +++ b/src/emucore/Cart4A50.hxx @@ -67,7 +67,7 @@ class Cartridge4A50 : public Cartridge */ Cartridge4A50(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~Cartridge4A50() = default; + ~Cartridge4A50() override = default; public: /** diff --git a/src/emucore/Cart4K.hxx b/src/emucore/Cart4K.hxx index cc2bb5aef..908944b9f 100644 --- a/src/emucore/Cart4K.hxx +++ b/src/emucore/Cart4K.hxx @@ -48,7 +48,7 @@ class Cartridge4K : public CartridgeEnhanced */ Cartridge4K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 4_KB); - virtual ~Cartridge4K() = default; + ~Cartridge4K() override = default; public: /** diff --git a/src/emucore/Cart4KSC.hxx b/src/emucore/Cart4KSC.hxx index a2197e018..2b90458bd 100644 --- a/src/emucore/Cart4KSC.hxx +++ b/src/emucore/Cart4KSC.hxx @@ -49,7 +49,7 @@ class Cartridge4KSC : public Cartridge4K */ Cartridge4KSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 4_KB); - virtual ~Cartridge4KSC() = default; + ~Cartridge4KSC() override = default; public: /** diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index 0b4369f31..6484a415f 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -54,7 +54,7 @@ class CartridgeAR : public Cartridge */ CartridgeAR(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeAR() = default; + ~CartridgeAR() override = default; public: /** diff --git a/src/emucore/CartBF.hxx b/src/emucore/CartBF.hxx index 5190f73da..a0c9d9e1d 100644 --- a/src/emucore/CartBF.hxx +++ b/src/emucore/CartBF.hxx @@ -49,7 +49,7 @@ class CartridgeBF : public CartridgeEnhanced */ CartridgeBF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 256_KB); - virtual ~CartridgeBF() = default; + ~CartridgeBF() override = default; public: /** diff --git a/src/emucore/CartBFSC.hxx b/src/emucore/CartBFSC.hxx index 4a660ecc8..bc1fa8911 100644 --- a/src/emucore/CartBFSC.hxx +++ b/src/emucore/CartBFSC.hxx @@ -49,7 +49,7 @@ class CartridgeBFSC : public CartridgeBF */ CartridgeBFSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 256_KB); - virtual ~CartridgeBFSC() = default; + ~CartridgeBFSC() override = default; /** Get a descriptor for the device name (used in error checking). diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 2e21b5f24..054324353 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -56,7 +56,7 @@ class CartridgeBUS : public Cartridge */ CartridgeBUS(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeBUS() = default; + ~CartridgeBUS() override = default; public: /** diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 99374de2b..d2110a112 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -62,7 +62,7 @@ class CartridgeCDF : public Cartridge */ CartridgeCDF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeCDF() = default; + ~CartridgeCDF() override = default; public: /** diff --git a/src/emucore/CartCM.hxx b/src/emucore/CartCM.hxx index 3a58889b4..0c2ffd0ef 100644 --- a/src/emucore/CartCM.hxx +++ b/src/emucore/CartCM.hxx @@ -122,7 +122,7 @@ class CartridgeCM : public Cartridge */ CartridgeCM(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeCM() = default; + ~CartridgeCM() override = default; public: /** @@ -257,7 +257,7 @@ class CartridgeCM : public Cartridge // Indicates the offset into the ROM image (aligns to current bank) uInt16 myBankOffset{0}; -private: + private: // Following constructors and assignment operators not supported CartridgeCM() = delete; CartridgeCM(const CartridgeCM&) = delete; diff --git a/src/emucore/CartCTY.hxx b/src/emucore/CartCTY.hxx index 5af3ceff4..42c077a2b 100644 --- a/src/emucore/CartCTY.hxx +++ b/src/emucore/CartCTY.hxx @@ -120,7 +120,7 @@ class CartridgeCTY : public Cartridge */ CartridgeCTY(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeCTY() = default; + ~CartridgeCTY() override = default; public: /** diff --git a/src/emucore/CartCV.hxx b/src/emucore/CartCV.hxx index 809d9b373..33c00b256 100644 --- a/src/emucore/CartCV.hxx +++ b/src/emucore/CartCV.hxx @@ -51,7 +51,7 @@ class CartridgeCV : public CartridgeEnhanced */ CartridgeCV(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 2_KB); - virtual ~CartridgeCV() = default; + ~CartridgeCV() override = default; public: /** diff --git a/src/emucore/CartDF.hxx b/src/emucore/CartDF.hxx index 18d0f2489..014aaccd4 100644 --- a/src/emucore/CartDF.hxx +++ b/src/emucore/CartDF.hxx @@ -49,7 +49,7 @@ class CartridgeDF : public CartridgeEnhanced */ CartridgeDF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 128_KB); - virtual ~CartridgeDF() = default; + ~CartridgeDF() override = default; public: /** diff --git a/src/emucore/CartDFSC.hxx b/src/emucore/CartDFSC.hxx index efc6d30e8..4a30af5c7 100644 --- a/src/emucore/CartDFSC.hxx +++ b/src/emucore/CartDFSC.hxx @@ -49,7 +49,7 @@ class CartridgeDFSC : public CartridgeDF */ CartridgeDFSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 128_KB); - virtual ~CartridgeDFSC() = default; + ~CartridgeDFSC() override = default; public: /** diff --git a/src/emucore/CartDPC.hxx b/src/emucore/CartDPC.hxx index 4d90fb140..382d5b12f 100644 --- a/src/emucore/CartDPC.hxx +++ b/src/emucore/CartDPC.hxx @@ -50,7 +50,7 @@ class CartridgeDPC : public CartridgeF8 */ CartridgeDPC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 10_KB); - virtual ~CartridgeDPC() = default; + ~CartridgeDPC() override = default; public: /** diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 04a1b0de4..5c83da263 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -58,7 +58,7 @@ class CartridgeDPCPlus : public Cartridge */ CartridgeDPCPlus(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeDPCPlus() = default; + ~CartridgeDPCPlus() override = default; public: /** diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 70af8f85d..db6b1e29e 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -57,7 +57,7 @@ class CartridgeE0 : public CartridgeEnhanced */ CartridgeE0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 8_KB); - virtual ~CartridgeE0() = default; + ~CartridgeE0() override = default; public: /** diff --git a/src/emucore/CartE7.hxx b/src/emucore/CartE7.hxx index 926fdeaec..07dee06c8 100644 --- a/src/emucore/CartE7.hxx +++ b/src/emucore/CartE7.hxx @@ -45,7 +45,7 @@ class CartridgeE7 : public CartridgeMNetwork */ CartridgeE7(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeE7() = default; + ~CartridgeE7() override = default; public: /** diff --git a/src/emucore/CartE78K.hxx b/src/emucore/CartE78K.hxx index d25e9f889..cc23e1feb 100644 --- a/src/emucore/CartE78K.hxx +++ b/src/emucore/CartE78K.hxx @@ -43,7 +43,7 @@ class CartridgeE78K : public CartridgeMNetwork */ CartridgeE78K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeE78K() = default; + ~CartridgeE78K() override = default; public: /** diff --git a/src/emucore/CartEF.hxx b/src/emucore/CartEF.hxx index 2c86d0d71..0ec1bf741 100644 --- a/src/emucore/CartEF.hxx +++ b/src/emucore/CartEF.hxx @@ -49,7 +49,7 @@ class CartridgeEF : public CartridgeEnhanced */ CartridgeEF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 64_KB); - virtual ~CartridgeEF() = default; + ~CartridgeEF() override = default; public: /** diff --git a/src/emucore/CartEFSC.hxx b/src/emucore/CartEFSC.hxx index ac95c9e2c..661dbaa8f 100644 --- a/src/emucore/CartEFSC.hxx +++ b/src/emucore/CartEFSC.hxx @@ -50,7 +50,7 @@ class CartridgeEFSC : public CartridgeEF */ CartridgeEFSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 64_KB); - virtual ~CartridgeEFSC() = default; + ~CartridgeEFSC() override = default; public: /** diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index e99afc917..98fb8e910 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -48,7 +48,7 @@ class CartridgeEnhanced : public Cartridge CartridgeEnhanced(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize); - virtual ~CartridgeEnhanced() = default; + ~CartridgeEnhanced() override = default; public: /** diff --git a/src/emucore/CartF0.hxx b/src/emucore/CartF0.hxx index e49b8ce31..2f287b5f2 100644 --- a/src/emucore/CartF0.hxx +++ b/src/emucore/CartF0.hxx @@ -46,7 +46,7 @@ class CartridgeF0 : public CartridgeEnhanced */ CartridgeF0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 64_KB); - virtual ~CartridgeF0() = default; + ~CartridgeF0() override = default; public: /** diff --git a/src/emucore/CartF4.hxx b/src/emucore/CartF4.hxx index 81a5e176e..7da18159f 100644 --- a/src/emucore/CartF4.hxx +++ b/src/emucore/CartF4.hxx @@ -45,7 +45,7 @@ class CartridgeF4 : public CartridgeEnhanced */ CartridgeF4(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 32_KB); - virtual ~CartridgeF4() = default; + ~CartridgeF4() override = default; public: /** diff --git a/src/emucore/CartF4SC.hxx b/src/emucore/CartF4SC.hxx index 49f1278ac..1cdd2865c 100644 --- a/src/emucore/CartF4SC.hxx +++ b/src/emucore/CartF4SC.hxx @@ -46,7 +46,7 @@ class CartridgeF4SC : public CartridgeF4 */ CartridgeF4SC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 32_KB); - virtual ~CartridgeF4SC() = default; + ~CartridgeF4SC() override = default; public: /** diff --git a/src/emucore/CartF6.hxx b/src/emucore/CartF6.hxx index 7707f1ef6..7e04a8521 100644 --- a/src/emucore/CartF6.hxx +++ b/src/emucore/CartF6.hxx @@ -45,7 +45,7 @@ class CartridgeF6 : public CartridgeEnhanced */ CartridgeF6(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 16_KB); - virtual ~CartridgeF6() = default; + ~CartridgeF6() override = default; public: /** diff --git a/src/emucore/CartF6SC.hxx b/src/emucore/CartF6SC.hxx index 4365036bb..f7a4ac59e 100644 --- a/src/emucore/CartF6SC.hxx +++ b/src/emucore/CartF6SC.hxx @@ -46,7 +46,7 @@ class CartridgeF6SC : public CartridgeF6 */ CartridgeF6SC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 16_KB); - virtual ~CartridgeF6SC() = default; + ~CartridgeF6SC() override = default; public: /** diff --git a/src/emucore/CartF8.hxx b/src/emucore/CartF8.hxx index 90b34497a..78110f95a 100644 --- a/src/emucore/CartF8.hxx +++ b/src/emucore/CartF8.hxx @@ -45,7 +45,7 @@ class CartridgeF8 : public CartridgeEnhanced */ CartridgeF8(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 8_KB); - virtual ~CartridgeF8() = default; + ~CartridgeF8() override = default; public: /** diff --git a/src/emucore/CartF8SC.hxx b/src/emucore/CartF8SC.hxx index 3eb3539ae..7f0fdd1c7 100644 --- a/src/emucore/CartF8SC.hxx +++ b/src/emucore/CartF8SC.hxx @@ -46,7 +46,7 @@ class CartridgeF8SC : public CartridgeF8 */ CartridgeF8SC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 8_KB); - virtual ~CartridgeF8SC() = default; + ~CartridgeF8SC() override = default; public: /** diff --git a/src/emucore/CartFA.hxx b/src/emucore/CartFA.hxx index d234de743..a8d23ebce 100644 --- a/src/emucore/CartFA.hxx +++ b/src/emucore/CartFA.hxx @@ -49,7 +49,7 @@ class CartridgeFA : public CartridgeEnhanced */ CartridgeFA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 12_KB); - virtual ~CartridgeFA() = default; + ~CartridgeFA() override = default; public: /** diff --git a/src/emucore/CartFA2.hxx b/src/emucore/CartFA2.hxx index ea60fbe45..a7c5aa03a 100644 --- a/src/emucore/CartFA2.hxx +++ b/src/emucore/CartFA2.hxx @@ -61,7 +61,7 @@ class CartridgeFA2 : public CartridgeFA */ CartridgeFA2(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 28_KB); - virtual ~CartridgeFA2() = default; + ~CartridgeFA2() override = default; public: /** diff --git a/src/emucore/CartFC.hxx b/src/emucore/CartFC.hxx index 92be2a421..3a478c597 100644 --- a/src/emucore/CartFC.hxx +++ b/src/emucore/CartFC.hxx @@ -52,7 +52,7 @@ class CartridgeFC : public CartridgeEnhanced */ CartridgeFC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 0); - virtual ~CartridgeFC() = default; + ~CartridgeFC() override = default; public: /** diff --git a/src/emucore/CartFE.hxx b/src/emucore/CartFE.hxx index 77ebee767..8f5d75e8d 100644 --- a/src/emucore/CartFE.hxx +++ b/src/emucore/CartFE.hxx @@ -91,7 +91,7 @@ class CartridgeFE : public CartridgeEnhanced */ CartridgeFE(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 8_KB); - virtual ~CartridgeFE() = default; + ~CartridgeFE() override = default; public: /** diff --git a/src/emucore/CartMDM.hxx b/src/emucore/CartMDM.hxx index 4e12571e1..715738977 100644 --- a/src/emucore/CartMDM.hxx +++ b/src/emucore/CartMDM.hxx @@ -61,7 +61,7 @@ class CartridgeMDM : public CartridgeEnhanced */ CartridgeMDM(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 0); - virtual ~CartridgeMDM() = default; + ~CartridgeMDM() override = default; public: /** diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index 9b17a4b67..64bfd0e6b 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -75,7 +75,7 @@ class CartridgeMNetwork : public Cartridge */ CartridgeMNetwork(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings); - virtual ~CartridgeMNetwork() = default; + ~CartridgeMNetwork() override = default; public: /** diff --git a/src/emucore/CartSB.hxx b/src/emucore/CartSB.hxx index 17cea387c..5e2c7ffa4 100644 --- a/src/emucore/CartSB.hxx +++ b/src/emucore/CartSB.hxx @@ -50,7 +50,7 @@ class CartridgeSB : public CartridgeEnhanced */ CartridgeSB(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 0); - virtual ~CartridgeSB() = default; + ~CartridgeSB() override = default; public: /** diff --git a/src/emucore/CartTVBoy.hxx b/src/emucore/CartTVBoy.hxx index d1787e55b..117f84f68 100644 --- a/src/emucore/CartTVBoy.hxx +++ b/src/emucore/CartTVBoy.hxx @@ -48,7 +48,7 @@ class CartridgeTVBoy : public CartridgeEnhanced */ CartridgeTVBoy(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 512_KB); - virtual ~CartridgeTVBoy() = default; + ~CartridgeTVBoy() override = default; public: /** diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx index 77b83d10b..95d4d022d 100644 --- a/src/emucore/CartUA.hxx +++ b/src/emucore/CartUA.hxx @@ -48,7 +48,7 @@ class CartridgeUA : public CartridgeEnhanced */ CartridgeUA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, bool swapHotspots = false); - virtual ~CartridgeUA() = default; + ~CartridgeUA() override = default; public: /** diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 4c1d9d3d9..de4cbd68d 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -69,7 +69,7 @@ class CartridgeWD : public CartridgeEnhanced */ CartridgeWD(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 8_KB); - virtual ~CartridgeWD() = default; + ~CartridgeWD() override = default; public: /** diff --git a/src/emucore/CartX07.hxx b/src/emucore/CartX07.hxx index 3f59ca7c3..65dd83f41 100644 --- a/src/emucore/CartX07.hxx +++ b/src/emucore/CartX07.hxx @@ -58,7 +58,7 @@ class CartridgeX07 : public CartridgeEnhanced */ CartridgeX07(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, size_t bsSize = 64_KB); - virtual ~CartridgeX07() = default; + ~CartridgeX07() override = default; public: /** diff --git a/src/emucore/CompuMate.hxx b/src/emucore/CompuMate.hxx index 8b8d772e8..e9a9a047e 100644 --- a/src/emucore/CompuMate.hxx +++ b/src/emucore/CompuMate.hxx @@ -52,7 +52,6 @@ class CompuMate @param system The system using this controller */ CompuMate(const Console& console, const Event& event, const System& system); - virtual ~CompuMate() = default; // Controllers are deleted outside this class /** Return the left and right CompuMate controllers @@ -88,7 +87,7 @@ class CompuMate const System& system) : Controller(jack, event, system, Controller::Type::CompuMate), myHandler(handler) { } - virtual ~CMControl() = default; + ~CMControl() override = default; public: /** diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index 366e606a0..78f14ba20 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -78,7 +78,7 @@ class Console : public Serializable, public ConsoleIO /** Destructor */ - virtual ~Console(); + ~Console() override; public: diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx index 128912dcd..629a2afee 100644 --- a/src/emucore/Control.hxx +++ b/src/emucore/Control.hxx @@ -119,7 +119,7 @@ class Controller : public Serializable */ Controller(Jack jack, const Event& event, const System& system, Type type); - virtual ~Controller() = default; + ~Controller() override = default; /** Returns the jack that this controller is plugged into. diff --git a/src/emucore/Device.hxx b/src/emucore/Device.hxx index fb2423a35..c690e0ab2 100644 --- a/src/emucore/Device.hxx +++ b/src/emucore/Device.hxx @@ -67,7 +67,7 @@ class Device : public Serializable public: Device() = default; - virtual ~Device() = default; + ~Device() override = default; public: /** diff --git a/src/emucore/Driving.hxx b/src/emucore/Driving.hxx index 6d0adaea8..35a02b2c1 100644 --- a/src/emucore/Driving.hxx +++ b/src/emucore/Driving.hxx @@ -38,7 +38,7 @@ class Driving : public Controller @param system The system using this controller */ Driving(Jack jack, const Event& event, const System& system); - virtual ~Driving() = default; + ~Driving() override = default; public: /** diff --git a/src/emucore/Genesis.hxx b/src/emucore/Genesis.hxx index fb0f65c20..3500cfbde 100644 --- a/src/emucore/Genesis.hxx +++ b/src/emucore/Genesis.hxx @@ -41,7 +41,7 @@ class Genesis : public Controller @param system The system using this controller */ Genesis(Jack jack, const Event& event, const System& system); - virtual ~Genesis() = default; + ~Genesis() override = default; public: /** diff --git a/src/emucore/Joystick.hxx b/src/emucore/Joystick.hxx index 505294456..99675c51e 100644 --- a/src/emucore/Joystick.hxx +++ b/src/emucore/Joystick.hxx @@ -38,7 +38,7 @@ class Joystick : public Controller @param system The system using this controller */ Joystick(Jack jack, const Event& event, const System& system); - virtual ~Joystick() = default; + ~Joystick() override = default; public: /** diff --git a/src/emucore/Keyboard.hxx b/src/emucore/Keyboard.hxx index 9ec176d71..3f6a714e5 100644 --- a/src/emucore/Keyboard.hxx +++ b/src/emucore/Keyboard.hxx @@ -38,7 +38,7 @@ class Keyboard : public Controller @param system The system using this controller */ Keyboard(Jack jack, const Event& event, const System& system); - virtual ~Keyboard() = default; + ~Keyboard() override = default; public: /** diff --git a/src/emucore/KidVid.hxx b/src/emucore/KidVid.hxx index 4c23761a1..b62107622 100644 --- a/src/emucore/KidVid.hxx +++ b/src/emucore/KidVid.hxx @@ -49,7 +49,7 @@ class KidVid : public Controller */ KidVid(Jack jack, const Event& event, const System& system, const string& romMd5); - virtual ~KidVid(); + ~KidVid() override; public: /** diff --git a/src/emucore/Lightgun.hxx b/src/emucore/Lightgun.hxx index facdffe1e..11a4c2e5b 100644 --- a/src/emucore/Lightgun.hxx +++ b/src/emucore/Lightgun.hxx @@ -44,7 +44,7 @@ class Lightgun : public Controller */ Lightgun(Jack jack, const Event& event, const System& system, const string& romMd5, const FrameBuffer& frameBuffer); - virtual ~Lightgun() = default; + ~Lightgun() override = default; public: using Controller::read; diff --git a/src/emucore/M6502.hxx b/src/emucore/M6502.hxx index 6cb3ccc65..6895025ac 100644 --- a/src/emucore/M6502.hxx +++ b/src/emucore/M6502.hxx @@ -64,7 +64,7 @@ class M6502 : public Serializable Create a new 6502 microprocessor. */ explicit M6502(const Settings& settings); - virtual ~M6502() = default; + ~M6502() override = default; public: /** diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index 6e7408798..d35877ab8 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -52,7 +52,7 @@ class M6532 : public Device @param settings The settings used by the system */ M6532(const ConsoleIO& console, const Settings& settings); - virtual ~M6532() = default; + ~M6532() override = default; public: /** diff --git a/src/emucore/MindLink.hxx b/src/emucore/MindLink.hxx index c1c2fbcf7..a205a61da 100644 --- a/src/emucore/MindLink.hxx +++ b/src/emucore/MindLink.hxx @@ -48,7 +48,7 @@ class MindLink : public Controller @param system The system using this controller */ MindLink(Jack jack, const Event& event, const System& system); - virtual ~MindLink() = default; + ~MindLink() override = default; public: /** diff --git a/src/emucore/NullDev.hxx b/src/emucore/NullDev.hxx index 7ef3b24b0..798edd64b 100644 --- a/src/emucore/NullDev.hxx +++ b/src/emucore/NullDev.hxx @@ -34,7 +34,7 @@ class NullDevice : public Device { public: NullDevice() = default; - virtual ~NullDevice() = default; + ~NullDevice() override = default; public: /** diff --git a/src/emucore/Paddles.hxx b/src/emucore/Paddles.hxx index bb8144b21..a84bf813c 100644 --- a/src/emucore/Paddles.hxx +++ b/src/emucore/Paddles.hxx @@ -45,7 +45,7 @@ class Paddles : public Controller */ Paddles(Jack jack, const Event& event, const System& system, bool swappaddle, bool swapaxis, bool swapdir); - virtual ~Paddles() = default; + ~Paddles() override = default; public: static constexpr float BASE_ANALOG_SENSE = 0.148643628F; diff --git a/src/emucore/PointingDevice.hxx b/src/emucore/PointingDevice.hxx index 11b9fcd2d..105d07f43 100644 --- a/src/emucore/PointingDevice.hxx +++ b/src/emucore/PointingDevice.hxx @@ -37,7 +37,7 @@ class PointingDevice : public Controller PointingDevice(Jack jack, const Event& event, const System& system, Controller::Type type, float sensitivity); - virtual ~PointingDevice() = default; + ~PointingDevice() override = default; public: using Controller::read; diff --git a/src/emucore/SaveKey.hxx b/src/emucore/SaveKey.hxx index ce5c3e347..79b8c25a3 100644 --- a/src/emucore/SaveKey.hxx +++ b/src/emucore/SaveKey.hxx @@ -47,7 +47,7 @@ class SaveKey : public Controller */ SaveKey(Jack jack, const Event& event, const System& system, const FilesystemNode& eepromfile, const onMessageCallback& callback); - virtual ~SaveKey(); + ~SaveKey() override; protected: /** diff --git a/src/emucore/Switches.hxx b/src/emucore/Switches.hxx index 16c4dba74..19fc47069 100644 --- a/src/emucore/Switches.hxx +++ b/src/emucore/Switches.hxx @@ -47,7 +47,7 @@ class Switches : public Serializable @param settings The settings used by the system */ Switches(const Event& event, const Properties& props, const Settings& settings); - virtual ~Switches() = default; + ~Switches() override = default; public: /** diff --git a/src/emucore/System.hxx b/src/emucore/System.hxx index b0660fec7..cf483c342 100644 --- a/src/emucore/System.hxx +++ b/src/emucore/System.hxx @@ -50,7 +50,7 @@ class System : public Serializable */ System(Random& random, M6502& m6502, M6532& m6532, TIA& mTIA, Cartridge& mCart); - virtual ~System() = default; + ~System() override = default; // Mask to apply to an address before accessing memory static constexpr uInt16 ADDRESS_MASK = (1 << 13) - 1; diff --git a/src/emucore/TrakBall.hxx b/src/emucore/TrakBall.hxx index 9e5a86234..7691543db 100644 --- a/src/emucore/TrakBall.hxx +++ b/src/emucore/TrakBall.hxx @@ -33,7 +33,7 @@ class TrakBall : public PointingDevice TrakBall(Jack jack, const Event& event, const System& system) : PointingDevice(jack, event, system, Controller::Type::TrakBall, trackballSensitivity) { } - virtual ~TrakBall() = default; + ~TrakBall() override = default; /** Returns the name of this controller. diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 3b2cbea7c..608caf184 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -117,7 +117,7 @@ class TIA : public Device */ TIA(ConsoleIO& console, const ConsoleTimingProvider& timingProvider, Settings& settings); - virtual ~TIA() = default; + ~TIA() override = default; public: /** diff --git a/src/gui/AboutDialog.hxx b/src/gui/AboutDialog.hxx index fd3ad0a4c..6ae420537 100644 --- a/src/gui/AboutDialog.hxx +++ b/src/gui/AboutDialog.hxx @@ -32,7 +32,7 @@ class AboutDialog : public Dialog public: AboutDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font); - virtual ~AboutDialog(); + ~AboutDialog() override; private: void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/BrowserDialog.hxx b/src/gui/BrowserDialog.hxx index 066b103c8..253e183b7 100644 --- a/src/gui/BrowserDialog.hxx +++ b/src/gui/BrowserDialog.hxx @@ -41,7 +41,7 @@ class BrowserDialog : public Dialog, public CommandSender public: BrowserDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h, const string& title = ""); - virtual ~BrowserDialog() = default; + ~BrowserDialog() override = default; /** Place the browser window onscreen, using the given attributes */ void show(const string& startpath, diff --git a/src/gui/CheckListWidget.hxx b/src/gui/CheckListWidget.hxx index 517e87e2b..625875a9d 100644 --- a/src/gui/CheckListWidget.hxx +++ b/src/gui/CheckListWidget.hxx @@ -34,7 +34,7 @@ class CheckListWidget : public ListWidget public: CheckListWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~CheckListWidget() = default; + ~CheckListWidget() override = default; void setList(const StringList& list, const BoolArray& state); void setLine(int line, const string& str, const bool& state); diff --git a/src/gui/ColorWidget.hxx b/src/gui/ColorWidget.hxx index 9169c2153..4d39871fa 100644 --- a/src/gui/ColorWidget.hxx +++ b/src/gui/ColorWidget.hxx @@ -37,7 +37,7 @@ class ColorWidget : public Widget, public CommandSender public: ColorWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, int cmd = 0, bool framed = true); - virtual ~ColorWidget() = default; + ~ColorWidget() override = default; void setColor(ColorId color); ColorId getColor() const { return _color; } diff --git a/src/gui/ComboDialog.hxx b/src/gui/ComboDialog.hxx index 7a539796d..5e57e8ae2 100644 --- a/src/gui/ComboDialog.hxx +++ b/src/gui/ComboDialog.hxx @@ -30,7 +30,7 @@ class ComboDialog : public Dialog { public: ComboDialog(GuiObject* boss, const GUI::Font& font, const VariantList& combolist); - virtual ~ComboDialog() = default; + ~ComboDialog() override = default; /** Place the dialog onscreen and center it */ void show(Event::Type event, const string& name); diff --git a/src/gui/CommandDialog.hxx b/src/gui/CommandDialog.hxx index bd366fc08..3cfaf7576 100644 --- a/src/gui/CommandDialog.hxx +++ b/src/gui/CommandDialog.hxx @@ -29,7 +29,7 @@ class CommandDialog : public Dialog { public: CommandDialog(OSystem& osystem, DialogContainer& parent); - virtual ~CommandDialog() = default; + ~CommandDialog() override = default; protected: void loadConfig() override; diff --git a/src/gui/CommandMenu.hxx b/src/gui/CommandMenu.hxx index 2873e9213..0a09ea140 100644 --- a/src/gui/CommandMenu.hxx +++ b/src/gui/CommandMenu.hxx @@ -35,7 +35,7 @@ class CommandMenu : public DialogContainer Create a new menu stack */ explicit CommandMenu(OSystem& osystem); - virtual ~CommandMenu(); + ~CommandMenu() override; /** Return (and possibly create) the bottom-most dialog of this container. diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index 221b90a30..423ef3074 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -43,7 +43,7 @@ class ContextMenu : public Dialog, public CommandSender public: ContextMenu(GuiObject* boss, const GUI::Font& font, const VariantList& items, int cmd = 0, int width = 0); - virtual ~ContextMenu() = default; + ~ContextMenu() override = default; /** Set the parent widget's ID */ void setID(uInt32 id) { _id = id; } diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx index 8dd2dc4e2..c2e88828b 100644 --- a/src/gui/DeveloperDialog.hxx +++ b/src/gui/DeveloperDialog.hxx @@ -42,7 +42,7 @@ class DeveloperDialog : public Dialog public: DeveloperDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h); - virtual ~DeveloperDialog() = default; + ~DeveloperDialog() override = default; private: void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 3c0242e9c..1f6bbec60 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -48,8 +48,7 @@ class Dialog : public GuiObject int x = 0, int y = 0, int w = 0, int h = 0); Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font, const string& title = "", int x = 0, int y = 0, int w = 0, int h = 0); - - virtual ~Dialog(); + ~Dialog() override; void open(); void close(); @@ -212,10 +211,6 @@ class Dialog : public GuiObject WidgetArray list; explicit Focus(Widget* w = nullptr) : widget(w) { } - virtual ~Focus() = default; - - Focus(const Focus&) = default; - Focus& operator=(const Focus&) = default; }; using FocusList = vector; @@ -225,10 +220,6 @@ class Dialog : public GuiObject uInt32 currentTab{0}; explicit TabFocus(TabWidget* w = nullptr) : widget(w) { } - virtual ~TabFocus() = default; - - TabFocus(const TabFocus&) = default; - TabFocus& operator=(const TabFocus&) = default; void appendFocusList(WidgetArray& list); void saveCurrentFocus(Widget* w); diff --git a/src/gui/EditTextWidget.hxx b/src/gui/EditTextWidget.hxx index c7a346804..fe063e042 100644 --- a/src/gui/EditTextWidget.hxx +++ b/src/gui/EditTextWidget.hxx @@ -27,7 +27,7 @@ class EditTextWidget : public EditableWidget public: EditTextWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, const string& text = ""); - virtual ~EditTextWidget() = default; + ~EditTextWidget() override = default; void setText(const string& str, bool changed = false) override; diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 3167e5d34..933d033af 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -46,7 +46,7 @@ class EditableWidget : public Widget, public CommandSender public: EditableWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, const string& str = ""); - virtual ~EditableWidget() = default; + ~EditableWidget() override = default; virtual void setText(const string& str, bool changed = false); const string& getText() const { return _editString; } diff --git a/src/gui/EmulationDialog.hxx b/src/gui/EmulationDialog.hxx index f1470d7bb..a03d27a70 100644 --- a/src/gui/EmulationDialog.hxx +++ b/src/gui/EmulationDialog.hxx @@ -24,40 +24,40 @@ class RadioButtonGroup; class EmulationDialog : public Dialog { -public: - EmulationDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, - int max_w, int max_h); - virtual ~EmulationDialog() = default; + public: + EmulationDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, + int max_w, int max_h); + ~EmulationDialog() override = default; -private: - void loadConfig() override; - void saveConfig() override; - void setDefaults() override; + private: + void loadConfig() override; + void saveConfig() override; + void setDefaults() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; -private: - SliderWidget* mySpeed{nullptr}; - CheckboxWidget* myUseVSync{nullptr}; - CheckboxWidget* myTurbo{nullptr}; - CheckboxWidget* myUIMessages{nullptr}; - CheckboxWidget* myFastSCBios{nullptr}; - CheckboxWidget* myUseThreads{nullptr}; - CheckboxWidget* myConfirmExitWidget{nullptr}; - RadioButtonGroup* mySaveOnExitGroup{nullptr}; - CheckboxWidget* myAutoSlotWidget{nullptr}; + private: + SliderWidget* mySpeed{nullptr}; + CheckboxWidget* myUseVSync{nullptr}; + CheckboxWidget* myTurbo{nullptr}; + CheckboxWidget* myUIMessages{nullptr}; + CheckboxWidget* myFastSCBios{nullptr}; + CheckboxWidget* myUseThreads{nullptr}; + CheckboxWidget* myConfirmExitWidget{nullptr}; + RadioButtonGroup* mySaveOnExitGroup{nullptr}; + CheckboxWidget* myAutoSlotWidget{nullptr}; - enum { - kSpeedupChanged = 'EDSp', - }; + enum { + kSpeedupChanged = 'EDSp', + }; -private: - // Following constructors and assignment operators not supported - EmulationDialog() = delete; - EmulationDialog(const EmulationDialog&) = delete; - EmulationDialog(EmulationDialog&&) = delete; - EmulationDialog& operator=(const EmulationDialog&) = delete; - EmulationDialog& operator=(EmulationDialog&&) = delete; + private: + // Following constructors and assignment operators not supported + EmulationDialog() = delete; + EmulationDialog(const EmulationDialog&) = delete; + EmulationDialog(EmulationDialog&&) = delete; + EmulationDialog& operator=(const EmulationDialog&) = delete; + EmulationDialog& operator=(EmulationDialog&&) = delete; }; #endif diff --git a/src/gui/EventMappingWidget.hxx b/src/gui/EventMappingWidget.hxx index 901f1ca70..074f87e6e 100644 --- a/src/gui/EventMappingWidget.hxx +++ b/src/gui/EventMappingWidget.hxx @@ -41,7 +41,7 @@ class EventMappingWidget : public Widget, public CommandSender EventMappingWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, EventMode mode); - virtual ~EventMappingWidget() = default; + ~EventMappingWidget() override = default; bool remapMode() { return myRemapStatus; } diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx index 552331b29..2bcc64048 100644 --- a/src/gui/FileListWidget.hxx +++ b/src/gui/FileListWidget.hxx @@ -50,7 +50,7 @@ class FileListWidget : public StringListWidget public: FileListWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~FileListWidget() = default; + ~FileListWidget() override = default; /** Determines how to display files/folders; either setDirectory or reload must be called after any of these are called. */ diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index 7e5febdde..c1302e753 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -36,7 +36,7 @@ class GameInfoDialog : public Dialog, public CommandSender public: GameInfoDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, GuiObject* boss, int max_w, int max_h); - virtual ~GameInfoDialog() = default; + ~GameInfoDialog() override = default; private: void loadConfig() override; diff --git a/src/gui/GlobalPropsDialog.hxx b/src/gui/GlobalPropsDialog.hxx index 2babd01fe..b63a771e1 100644 --- a/src/gui/GlobalPropsDialog.hxx +++ b/src/gui/GlobalPropsDialog.hxx @@ -31,7 +31,7 @@ class GlobalPropsDialog : public Dialog, public CommandSender { public: GlobalPropsDialog(GuiObject* boss, const GUI::Font& font); - virtual ~GlobalPropsDialog() = default; + ~GlobalPropsDialog() override = default; private: int addHoldWidgets(const GUI::Font& font, int x, int y, WidgetArray& wid); diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index fc8f77285..77392209c 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -60,7 +60,7 @@ class GuiObject : public CommandReceiver myDialog(dialog), _x(x), _y(y), _w(w), _h(h) { } - virtual ~GuiObject() = default; + ~GuiObject() override = default; OSystem& instance() const { return myOSystem; } DialogContainer& parent() const { return myParent; } diff --git a/src/gui/HelpDialog.hxx b/src/gui/HelpDialog.hxx index 352824f0d..1d44edb30 100644 --- a/src/gui/HelpDialog.hxx +++ b/src/gui/HelpDialog.hxx @@ -31,7 +31,7 @@ class HelpDialog : public Dialog { public: HelpDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font); - virtual ~HelpDialog() = default; + ~HelpDialog() override = default; private: void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx index 6893d2c43..6cb6c4742 100644 --- a/src/gui/InputDialog.hxx +++ b/src/gui/InputDialog.hxx @@ -40,7 +40,7 @@ class InputDialog : public Dialog public: InputDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h); - virtual ~InputDialog(); + ~InputDialog() override; protected: // disable repeat during and directly after mapping events diff --git a/src/gui/InputTextDialog.hxx b/src/gui/InputTextDialog.hxx index d48d10a45..e89e00651 100644 --- a/src/gui/InputTextDialog.hxx +++ b/src/gui/InputTextDialog.hxx @@ -34,7 +34,7 @@ class InputTextDialog : public Dialog, public CommandSender InputTextDialog(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, const StringList& labels, const string& title = ""); - virtual ~InputTextDialog() = default; + ~InputTextDialog() override = default; /** Place the input dialog onscreen and center it */ void show(); diff --git a/src/gui/JoystickDialog.hxx b/src/gui/JoystickDialog.hxx index 7221763f1..67074d1d2 100644 --- a/src/gui/JoystickDialog.hxx +++ b/src/gui/JoystickDialog.hxx @@ -35,7 +35,7 @@ class JoystickDialog : public Dialog public: JoystickDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h); - virtual ~JoystickDialog() = default; + ~JoystickDialog() override = default; /** Place the dialog onscreen and center it */ void show() { open(); } diff --git a/src/gui/Launcher.hxx b/src/gui/Launcher.hxx index af0e91f8b..4148db945 100644 --- a/src/gui/Launcher.hxx +++ b/src/gui/Launcher.hxx @@ -37,7 +37,7 @@ class Launcher : public DialogContainer Create a new menu stack */ explicit Launcher(OSystem& osystem); - virtual ~Launcher(); + ~Launcher() override; /** Initialize the video subsystem wrt this class. diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index 0f1f1cda2..0dd9b898d 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -58,7 +58,7 @@ class LauncherDialog : public Dialog public: LauncherDialog(OSystem& osystem, DialogContainer& parent, int x, int y, int w, int h); - virtual ~LauncherDialog() = default; + ~LauncherDialog() override = default; /** Get path for the currently selected file. diff --git a/src/gui/ListWidget.hxx b/src/gui/ListWidget.hxx index b60c7dc9a..75d2600ae 100644 --- a/src/gui/ListWidget.hxx +++ b/src/gui/ListWidget.hxx @@ -43,7 +43,7 @@ class ListWidget : public EditableWidget public: ListWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~ListWidget() = default; + ~ListWidget() override = default; int rows() const { return _rows; } int currentPos() const { return _currentPos; } diff --git a/src/gui/LoggerDialog.hxx b/src/gui/LoggerDialog.hxx index 9ab22d769..2f5188343 100644 --- a/src/gui/LoggerDialog.hxx +++ b/src/gui/LoggerDialog.hxx @@ -32,7 +32,7 @@ class LoggerDialog : public Dialog LoggerDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h, bool useLargeFont = true); - virtual ~LoggerDialog() = default; + ~LoggerDialog() override = default; private: void loadConfig() override; diff --git a/src/gui/Menu.hxx b/src/gui/Menu.hxx index ead0b9065..cb6acf30c 100644 --- a/src/gui/Menu.hxx +++ b/src/gui/Menu.hxx @@ -39,7 +39,7 @@ class Menu : public DialogContainer Create a new menu stack */ explicit Menu(OSystem& osystem); - virtual ~Menu(); + ~Menu() override; private: Dialog* baseDialog() override; diff --git a/src/gui/MessageBox.hxx b/src/gui/MessageBox.hxx index c6b1934aa..4ed74fa58 100644 --- a/src/gui/MessageBox.hxx +++ b/src/gui/MessageBox.hxx @@ -54,7 +54,7 @@ class MessageBox : public Dialog, public CommandSender const string& okText = "OK", const string& cancelText = "Cancel", const string& title = "", bool focusOKButton = true); - virtual ~MessageBox() = default; + ~MessageBox() override = default; /** Place the input dialog onscreen and center it */ void show() { open(); } diff --git a/src/gui/MessageDialog.hxx b/src/gui/MessageDialog.hxx index 4ebb6607a..7e0928ced 100644 --- a/src/gui/MessageDialog.hxx +++ b/src/gui/MessageDialog.hxx @@ -30,7 +30,7 @@ class MessageDialog : public Dialog public: MessageDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h); - virtual ~MessageDialog(); + ~MessageDialog() override; // Define the message displayed void setMessage(const string& title, const string& text, bool yesNo = false); diff --git a/src/gui/MessageMenu.hxx b/src/gui/MessageMenu.hxx index e5246e5ae..cfe114e76 100644 --- a/src/gui/MessageMenu.hxx +++ b/src/gui/MessageMenu.hxx @@ -30,28 +30,28 @@ class MessageDialog; */ class MessageMenu : public DialogContainer { -public: - /** - Create a new menu stack - */ - explicit MessageMenu(OSystem& osystem); - virtual ~MessageMenu(); + public: + /** + Create a new menu stack + */ + explicit MessageMenu(OSystem& osystem); + ~MessageMenu() override; - void setMessage(const string& title, const string& text, bool yesNo = false); - void setMessage(const string& title, const StringList& text, bool yesNo = false); - bool confirmed(); + void setMessage(const string& title, const string& text, bool yesNo = false); + void setMessage(const string& title, const StringList& text, bool yesNo = false); + bool confirmed(); -private: - Dialog* baseDialog() override; - MessageDialog* myMessageDialog{nullptr}; + private: + Dialog* baseDialog() override; + MessageDialog* myMessageDialog{nullptr}; -private: - // Following constructors and assignment operators not supported - MessageMenu() = delete; - MessageMenu(const MessageMenu&) = delete; - MessageMenu(MessageMenu&&) = delete; - MessageMenu& operator=(const MessageMenu&) = delete; - MessageMenu& operator=(MessageMenu&&) = delete; + private: + // Following constructors and assignment operators not supported + MessageMenu() = delete; + MessageMenu(const MessageMenu&) = delete; + MessageMenu(MessageMenu&&) = delete; + MessageMenu& operator=(const MessageMenu&) = delete; + MessageMenu& operator=(MessageMenu&&) = delete; }; #endif diff --git a/src/gui/MinUICommandDialog.hxx b/src/gui/MinUICommandDialog.hxx index 76f69ba6c..e56ca8457 100644 --- a/src/gui/MinUICommandDialog.hxx +++ b/src/gui/MinUICommandDialog.hxx @@ -31,7 +31,7 @@ class MinUICommandDialog : public Dialog { public: MinUICommandDialog(OSystem& osystem, DialogContainer& parent); - virtual ~MinUICommandDialog() = default; + ~MinUICommandDialog() override = default; protected: void loadConfig() override; diff --git a/src/gui/OptionsDialog.hxx b/src/gui/OptionsDialog.hxx index 001fad73b..55d4d4b0d 100644 --- a/src/gui/OptionsDialog.hxx +++ b/src/gui/OptionsDialog.hxx @@ -45,7 +45,7 @@ class OptionsDialog : public Dialog public: OptionsDialog(OSystem& osystem, DialogContainer& parent, GuiObject* boss, int max_w, int max_h, Menu::AppMode mode); - virtual ~OptionsDialog(); + ~OptionsDialog() override; private: void loadConfig() override; diff --git a/src/gui/PopUpWidget.hxx b/src/gui/PopUpWidget.hxx index c9817e6dd..a3c122509 100644 --- a/src/gui/PopUpWidget.hxx +++ b/src/gui/PopUpWidget.hxx @@ -39,7 +39,7 @@ class PopUpWidget : public Widget, public CommandSender PopUpWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, const VariantList& items, const string& label, int labelWidth = 0, int cmd = 0); - virtual ~PopUpWidget() = default; + ~PopUpWidget() override = default; void setID(uInt32 id); diff --git a/src/gui/ProgressDialog.hxx b/src/gui/ProgressDialog.hxx index 24ca54539..0ec8731b5 100644 --- a/src/gui/ProgressDialog.hxx +++ b/src/gui/ProgressDialog.hxx @@ -29,7 +29,7 @@ class ProgressDialog : public Dialog public: ProgressDialog(GuiObject* boss, const GUI::Font& font, const string& message); - virtual ~ProgressDialog() = default; + ~ProgressDialog() override = default; void setMessage(const string& message); void setRange(int begin, int end, int step); diff --git a/src/gui/R77HelpDialog.hxx b/src/gui/R77HelpDialog.hxx index 731de5e65..0e51af2c7 100644 --- a/src/gui/R77HelpDialog.hxx +++ b/src/gui/R77HelpDialog.hxx @@ -31,7 +31,7 @@ class R77HelpDialog : public Dialog { public: R77HelpDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font); - virtual ~R77HelpDialog() = default; + ~R77HelpDialog() override = default; private: void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/RomAuditDialog.hxx b/src/gui/RomAuditDialog.hxx index ebad2174d..3bc2a5969 100644 --- a/src/gui/RomAuditDialog.hxx +++ b/src/gui/RomAuditDialog.hxx @@ -37,7 +37,7 @@ class RomAuditDialog : public Dialog public: RomAuditDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h); - virtual ~RomAuditDialog(); + ~RomAuditDialog() override; private: void loadConfig() override; diff --git a/src/gui/RomInfoWidget.hxx b/src/gui/RomInfoWidget.hxx index e2ea566ca..dbf3beee1 100644 --- a/src/gui/RomInfoWidget.hxx +++ b/src/gui/RomInfoWidget.hxx @@ -33,7 +33,7 @@ class RomInfoWidget : public Widget RomInfoWidget(GuiObject *boss, const GUI::Font& font, int x, int y, int w, int h, const Common::Size& imgSize); - virtual ~RomInfoWidget() = default; + ~RomInfoWidget() override = default; void setProperties(const FilesystemNode& node, const string& md5); void clearProperties(); diff --git a/src/gui/ScrollBarWidget.hxx b/src/gui/ScrollBarWidget.hxx index 7752e8ab7..1d1b4c34a 100644 --- a/src/gui/ScrollBarWidget.hxx +++ b/src/gui/ScrollBarWidget.hxx @@ -29,7 +29,7 @@ class ScrollBarWidget : public Widget, public CommandSender public: ScrollBarWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~ScrollBarWidget() = default; + ~ScrollBarWidget() override = default; void recalc(); void handleMouseWheel(int x, int y, int direction) override; diff --git a/src/gui/SnapshotDialog.hxx b/src/gui/SnapshotDialog.hxx index 94cedff11..6c9a30118 100644 --- a/src/gui/SnapshotDialog.hxx +++ b/src/gui/SnapshotDialog.hxx @@ -35,7 +35,7 @@ class SnapshotDialog : public Dialog public: SnapshotDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h); - virtual ~SnapshotDialog(); + ~SnapshotDialog() override; private: void loadConfig() override; diff --git a/src/gui/StellaSettingsDialog.hxx b/src/gui/StellaSettingsDialog.hxx index 6f7cfe8a8..4deb620a9 100644 --- a/src/gui/StellaSettingsDialog.hxx +++ b/src/gui/StellaSettingsDialog.hxx @@ -40,7 +40,7 @@ class StellaSettingsDialog : public Dialog public: StellaSettingsDialog(OSystem& osystem, DialogContainer& parent, int max_w, int max_h, Menu::AppMode mode); - virtual ~StellaSettingsDialog(); + ~StellaSettingsDialog() override; private: void loadConfig() override; diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx index 10c197509..490c6b6a2 100644 --- a/src/gui/StringListWidget.hxx +++ b/src/gui/StringListWidget.hxx @@ -26,7 +26,7 @@ class StringListWidget : public ListWidget public: StringListWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, bool hilite = true); - virtual ~StringListWidget() = default; + ~StringListWidget() override = default; void setList(const StringList& list); bool wantsFocus() const override { return true; } diff --git a/src/gui/TabWidget.hxx b/src/gui/TabWidget.hxx index cd6547b50..1f581df5c 100644 --- a/src/gui/TabWidget.hxx +++ b/src/gui/TabWidget.hxx @@ -35,7 +35,7 @@ class TabWidget : public Widget, public CommandSender public: TabWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~TabWidget(); + ~TabWidget() override; // use Dialog::releaseFocus() when changing to another tab diff --git a/src/gui/TimeMachine.hxx b/src/gui/TimeMachine.hxx index 9854274da..e8b3be33f 100644 --- a/src/gui/TimeMachine.hxx +++ b/src/gui/TimeMachine.hxx @@ -31,7 +31,7 @@ class TimeMachine : public DialogContainer { public: explicit TimeMachine(OSystem& osystem); - virtual ~TimeMachine(); + ~TimeMachine() override; /** This dialog has an adjustable size. We need to make sure the diff --git a/src/gui/TimeMachineDialog.hxx b/src/gui/TimeMachineDialog.hxx index 283249514..a4a489b79 100644 --- a/src/gui/TimeMachineDialog.hxx +++ b/src/gui/TimeMachineDialog.hxx @@ -29,7 +29,7 @@ class TimeMachineDialog : public Dialog { public: TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int width); - virtual ~TimeMachineDialog() = default; + ~TimeMachineDialog() override = default; /** set/get number of winds when entering the dialog */ void setEnterWinds(Int32 numWinds) { _enterWinds = numWinds; } diff --git a/src/gui/UIDialog.hxx b/src/gui/UIDialog.hxx index 6ed1c655f..544f6c764 100644 --- a/src/gui/UIDialog.hxx +++ b/src/gui/UIDialog.hxx @@ -25,7 +25,7 @@ class UIDialog : public Dialog, public CommandSender public: UIDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, GuiObject* boss, int max_w, int max_h); - virtual ~UIDialog(); + ~UIDialog() override; private: void loadConfig() override; diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index ef0f850a8..7f0fd817e 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -39,7 +39,7 @@ class VideoAudioDialog : public Dialog public: VideoAudioDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h); - virtual ~VideoAudioDialog() = default; + ~VideoAudioDialog() override = default; private: void loadConfig() override; diff --git a/src/gui/WhatsNewDialog.hxx b/src/gui/WhatsNewDialog.hxx index d90edbd15..9c4154220 100644 --- a/src/gui/WhatsNewDialog.hxx +++ b/src/gui/WhatsNewDialog.hxx @@ -25,7 +25,7 @@ class WhatsNewDialog : public Dialog public: WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h); - virtual ~WhatsNewDialog() = default; + ~WhatsNewDialog() override = default; private: void add(int& ypos, const string& text); diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index b20b8b159..3add250ba 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -57,7 +57,7 @@ class Widget : public GuiObject public: Widget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); - virtual ~Widget(); + ~Widget() override; virtual int getAbsX() const override { return _x + _boss->getChildX(); } virtual int getAbsY() const override { return _y + _boss->getChildY(); } @@ -187,7 +187,7 @@ class StaticTextWidget : public Widget int x, int y, const string& text = "", TextAlign align = TextAlign::Left, ColorId shadowColor = kNone); - virtual ~StaticTextWidget() = default; + ~StaticTextWidget() override = default; void setValue(int value); void setLabel(const string& label); void setAlign(TextAlign align) { _align = align; setDirty(); } @@ -228,7 +228,7 @@ class ButtonWidget : public StaticTextWidget, public CommandSender int x, int y, int dw, int dh, const uInt32* bitmap, int bmw, int bmh, int cmd = 0, bool repeat = false); - virtual ~ButtonWidget() = default; + ~ButtonWidget() override = default; void setCmd(int cmd) { _cmd = cmd; } int getCmd() const { return _cmd; } @@ -271,7 +271,7 @@ class CheckboxWidget : public ButtonWidget public: CheckboxWidget(GuiObject* boss, const GUI::Font& font, int x, int y, const string& label, int cmd = 0); - virtual ~CheckboxWidget() = default; + ~CheckboxWidget() override = default; void setEditable(bool editable); void setFill(FillType type); @@ -333,7 +333,7 @@ class SliderWidget : public ButtonWidget const string& label = "", int labelWidth = 0, int cmd = 0, int valueLabelWidth = 0, const string& valueUnit = "", int valueLabelGap = 0, bool forceLabelSign = false); - virtual ~SliderWidget() = default; + ~SliderWidget() override = default; void setValue(int value); int getValue() const { return _value; } diff --git a/src/libretro/EventHandlerLIBRETRO.cxx b/src/libretro/EventHandlerLIBRETRO.cxx index d14f2bfd6..046839032 100644 --- a/src/libretro/EventHandlerLIBRETRO.cxx +++ b/src/libretro/EventHandlerLIBRETRO.cxx @@ -31,8 +31,10 @@ EventHandlerLIBRETRO::~EventHandlerLIBRETRO() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandlerLIBRETRO::enableTextEvents(bool enable) -{} +{ +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandlerLIBRETRO::pollEvent() -{} +{ +} diff --git a/src/libretro/EventHandlerLIBRETRO.hxx b/src/libretro/EventHandlerLIBRETRO.hxx index 08b42b1e8..3357e0997 100644 --- a/src/libretro/EventHandlerLIBRETRO.hxx +++ b/src/libretro/EventHandlerLIBRETRO.hxx @@ -34,7 +34,7 @@ class EventHandlerLIBRETRO : public EventHandler Create a new LIBRETRO event handler object */ explicit EventHandlerLIBRETRO(OSystem& osystem); - virtual ~EventHandlerLIBRETRO(); + ~EventHandlerLIBRETRO() override; private: /** diff --git a/src/libretro/FBSurfaceLIBRETRO.hxx b/src/libretro/FBSurfaceLIBRETRO.hxx index e7423efce..89809e011 100644 --- a/src/libretro/FBSurfaceLIBRETRO.hxx +++ b/src/libretro/FBSurfaceLIBRETRO.hxx @@ -33,7 +33,7 @@ class FBSurfaceLIBRETRO : public FBSurface public: FBSurfaceLIBRETRO(FrameBufferLIBRETRO& buffer, uInt32 width, uInt32 height, const uInt32* data); - virtual ~FBSurfaceLIBRETRO() { } + ~FBSurfaceLIBRETRO() override { } // Most of the surface drawing primitives are implemented in FBSurface; void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, ColorId color) override { } diff --git a/src/libretro/FrameBufferLIBRETRO.hxx b/src/libretro/FrameBufferLIBRETRO.hxx index 4ac6dbb30..a57a218d2 100644 --- a/src/libretro/FrameBufferLIBRETRO.hxx +++ b/src/libretro/FrameBufferLIBRETRO.hxx @@ -39,7 +39,7 @@ class FrameBufferLIBRETRO : public FrameBuffer Creates a new LIBRETRO framebuffer */ explicit FrameBufferLIBRETRO(OSystem& osystem); - virtual ~FrameBufferLIBRETRO() { } + ~FrameBufferLIBRETRO() override { } ////////////////////////////////////////////////////////////////////// // The following are derived from public methods in FrameBuffer.hxx diff --git a/src/libretro/OSystemLIBRETRO.hxx b/src/libretro/OSystemLIBRETRO.hxx index 8d978c497..60b1fc4e5 100644 --- a/src/libretro/OSystemLIBRETRO.hxx +++ b/src/libretro/OSystemLIBRETRO.hxx @@ -32,7 +32,7 @@ class OSystemLIBRETRO : public OSystem { public: OSystemLIBRETRO() = default; - virtual ~OSystemLIBRETRO() = default; + ~OSystemLIBRETRO() override = default; /** Determine the base directory and main configuration file from the diff --git a/src/libretro/SoundLIBRETRO.hxx b/src/libretro/SoundLIBRETRO.hxx index 7f68c0127..8bdb77fd3 100644 --- a/src/libretro/SoundLIBRETRO.hxx +++ b/src/libretro/SoundLIBRETRO.hxx @@ -29,7 +29,7 @@ class AudioSettings; #include "Sound.hxx" /** - This class implements the sound API for LIBRTRO. + This class implements the sound API for LIBRETRO. @author Stephen Anthony and Christian Speckner (DirtyHairy) */ @@ -41,11 +41,7 @@ class SoundLIBRETRO : public Sound using the object. */ SoundLIBRETRO(OSystem& osystem, AudioSettings& audioSettings); - - /** - Destructor - */ - virtual ~SoundLIBRETRO(); + ~SoundLIBRETRO() override; public: /** diff --git a/src/libretro/StellaLIBRETRO.hxx b/src/libretro/StellaLIBRETRO.hxx index b3d87725b..64bc91651 100644 --- a/src/libretro/StellaLIBRETRO.hxx +++ b/src/libretro/StellaLIBRETRO.hxx @@ -40,7 +40,6 @@ class StellaLIBRETRO { public: StellaLIBRETRO(); - virtual ~StellaLIBRETRO() = default; public: OSystemLIBRETRO& osystem() { return *myOSystem; } diff --git a/src/macos/OSystemMACOS.hxx b/src/macos/OSystemMACOS.hxx index 5a5591953..89d6638c1 100644 --- a/src/macos/OSystemMACOS.hxx +++ b/src/macos/OSystemMACOS.hxx @@ -32,7 +32,7 @@ class OSystemMACOS : public OSystem { public: OSystemMACOS() = default; - virtual ~OSystemMACOS() = default; + ~OSystemMACOS() override = default; /** Determine the base directory and main configuration file from the diff --git a/src/macos/SerialPortMACOS.hxx b/src/macos/SerialPortMACOS.hxx index 3d71d5135..12dbcf28e 100644 --- a/src/macos/SerialPortMACOS.hxx +++ b/src/macos/SerialPortMACOS.hxx @@ -30,7 +30,7 @@ class SerialPortMACOS : public SerialPort { public: SerialPortMACOS(); - virtual ~SerialPortMACOS(); + ~SerialPortMACOS() override; /** Open the given serial port with the specified attributes. diff --git a/src/unix/OSystemUNIX.hxx b/src/unix/OSystemUNIX.hxx index b2e11eab2..b562a3c3d 100644 --- a/src/unix/OSystemUNIX.hxx +++ b/src/unix/OSystemUNIX.hxx @@ -32,7 +32,7 @@ class OSystemUNIX : public OSystem { public: OSystemUNIX() = default; - virtual ~OSystemUNIX() = default; + ~OSystemUNIX() override = default; /** Determine the base directory and main configuration file from the diff --git a/src/unix/SerialPortUNIX.hxx b/src/unix/SerialPortUNIX.hxx index 7a675298e..4dec5a116 100644 --- a/src/unix/SerialPortUNIX.hxx +++ b/src/unix/SerialPortUNIX.hxx @@ -30,7 +30,7 @@ class SerialPortUNIX : public SerialPort { public: SerialPortUNIX(); - virtual ~SerialPortUNIX(); + ~SerialPortUNIX() override; /** Open the given serial port with the specified attributes. diff --git a/src/unix/r77/OSystemR77.hxx b/src/unix/r77/OSystemR77.hxx index 6ed09a4e4..58d80d80e 100644 --- a/src/unix/r77/OSystemR77.hxx +++ b/src/unix/r77/OSystemR77.hxx @@ -34,7 +34,7 @@ class OSystemR77 : public OSystem { public: OSystemR77() = default; - virtual ~OSystemR77() = default; + ~OSystemR77() override = default; /** Determine the base directory and main configuration file from the diff --git a/src/unix/r77/SettingsR77.hxx b/src/unix/r77/SettingsR77.hxx index e231a34d5..a5f58018a 100644 --- a/src/unix/r77/SettingsR77.hxx +++ b/src/unix/r77/SettingsR77.hxx @@ -33,7 +33,7 @@ class SettingsR77 : public Settings Create a new UNIX settings object */ explicit SettingsR77(); - virtual ~SettingsR77() = default; + ~SettingsR77() override = default; private: // Following constructors and assignment operators not supported diff --git a/src/windows/OSystemWINDOWS.hxx b/src/windows/OSystemWINDOWS.hxx index 786783bd3..4995f9f51 100644 --- a/src/windows/OSystemWINDOWS.hxx +++ b/src/windows/OSystemWINDOWS.hxx @@ -32,7 +32,7 @@ class OSystemWINDOWS : public OSystem { public: OSystemWINDOWS() = default; - virtual ~OSystemWINDOWS() = default; + ~OSystemWINDOWS() override = default; /** Determine the base directory and main configuration file from the diff --git a/src/windows/SerialPortWINDOWS.hxx b/src/windows/SerialPortWINDOWS.hxx index 3f8513573..adab57ce6 100644 --- a/src/windows/SerialPortWINDOWS.hxx +++ b/src/windows/SerialPortWINDOWS.hxx @@ -29,7 +29,7 @@ class SerialPortWINDOWS : public SerialPort { public: SerialPortWINDOWS(); - virtual ~SerialPortWINDOWS(); + ~SerialPortWINDOWS() override; /** Open the given serial port with the specified attributes. From e5acfdf9838602dcf9c53ea435dec3dbc6383e4b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 17 Aug 2020 17:44:34 +0200 Subject: [PATCH 006/263] enhanced CartCDF, now ignores random startup banks (partially addresses #690) --- src/emucore/Cart.hxx | 2 +- src/emucore/CartCDF.hxx | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index 5c3b65af2..94ed77874 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -354,7 +354,7 @@ class Cartridge : public Device @return Whether the startup bank(s) should be randomized */ - bool randomStartBank() const; + virtual bool randomStartBank() const; protected: // Settings class for the application diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index d2110a112..15d521b5e 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -183,6 +183,13 @@ class CartridgeCDF : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: + /** + Checks if startup bank randomization is enabled. + + @return Whether the startup bank(s) should be randomized + */ + bool randomStartBank() const override { return false; }; + /** Sets the initial state of the DPC pointers and RAM */ From cb8f6d8ccd4a2f32e708f49bf30c3f89384639df Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 17 Aug 2020 22:58:22 -0230 Subject: [PATCH 007/263] Fix compiler warning. --- src/emucore/CartCDF.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 15d521b5e..cf172b8d2 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -188,7 +188,7 @@ class CartridgeCDF : public Cartridge @return Whether the startup bank(s) should be randomized */ - bool randomStartBank() const override { return false; }; + bool randomStartBank() const override { return false; } /** Sets the initial state of the DPC pointers and RAM From 1cfe5a48e428a7a4a559a51d61fad6af1fe65f21 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 21 Aug 2020 16:04:49 -0230 Subject: [PATCH 008/263] Add support for 2600-daptor II when flashed as an AVox-USB converter. Basically, for this device we use software flow control rather than hardware CTS signal. --- Changes.txt | 4 ++-- src/emucore/AtariVox.cxx | 23 ++++++++++++++++++++--- src/emucore/AtariVox.hxx | 14 +++++++++----- src/emucore/SerialPort.hxx | 1 - src/macos/SerialPortMACOS.cxx | 13 ++++++++++--- src/macos/SerialPortMACOS.hxx | 8 ++++++++ src/unix/SerialPortUNIX.cxx | 17 +++++++++++++---- src/unix/SerialPortUNIX.hxx | 8 ++++++++ src/windows/SerialPortWINDOWS.cxx | 23 ++++++++++++++++++++++- src/windows/SerialPortWINDOWS.hxx | 8 ++++++++ 10 files changed, 100 insertions(+), 19 deletions(-) diff --git a/Changes.txt b/Changes.txt index 61b036ebc..d231d65da 100644 --- a/Changes.txt +++ b/Changes.txt @@ -34,8 +34,8 @@ one ZIP file, and distribute just that file. * Extended AtariVox support to handle flow control, so that long phrases - are no longer corrupted/cut off. Note that some USB-serial adaptors - don't support this mode, so there may still be issues with those. + are no longer corrupted/cut off. This includes properly supporting the + 2600-daptor II, which is flashable to an AVox-USB converter. * Added option to select the audio device. diff --git a/src/emucore/AtariVox.cxx b/src/emucore/AtariVox.cxx index 731232456..6040b3f6d 100644 --- a/src/emucore/AtariVox.cxx +++ b/src/emucore/AtariVox.cxx @@ -56,10 +56,27 @@ bool AtariVox::read(DigitalPin pin) switch(pin) { // Pin 2: SpeakJet READY - // CTS (Clear To Send) is sent directly to pin 2 - // We also deal with the case where devices send CTS inverted + // READY signal is sent directly to pin 2 case DigitalPin::Two: - return setPin(pin, mySerialPort->isCTS() ^ myCTSFlip); + { + // Some USB-serial adaptors support only CTS, others support only + // software flow control + // So we check the state of both then AND the results, on the + // assumption that if a mode isn't supported, then it reads as TRUE + // and doesn't change the boolean result + // Thus the logic is: + // READY_SIGNAL = READY_STATE_CTS && READY_STATE_FLOW + // Note that we also have to take inverted CTS into account + + // When using software flow control, only update on a state change + uInt8 flowCtrl = 0; + if(mySerialPort->readByte(flowCtrl)) + myReadyStateSoftFlow = flowCtrl == 0x11; // XON + + // Now combine the results of CTS and'ed with flow control + return setPin(pin, + (mySerialPort->isCTS() ^ myCTSFlip) && myReadyStateSoftFlow); + } default: return SaveKey::read(pin); diff --git a/src/emucore/AtariVox.hxx b/src/emucore/AtariVox.hxx index d868338ed..0768d66c9 100644 --- a/src/emucore/AtariVox.hxx +++ b/src/emucore/AtariVox.hxx @@ -32,7 +32,7 @@ class FilesystemNode; This code owes a great debt to Alex Herbert's AtariVox documentation and driver code. - @author B. Watson + @author B. Watson, Stephen Anthony */ class AtariVox : public SaveKey { @@ -91,7 +91,9 @@ class AtariVox : public SaveKey */ void reset() override; - string about(bool swappedPorts) const override { return Controller::about(swappedPorts) + myAboutString; } + string about(bool swappedPorts) const override { + return Controller::about(swappedPorts) + myAboutString; + } private: void clockDataIn(bool value); @@ -117,9 +119,11 @@ class AtariVox : public SaveKey // "close enough". uInt64 myLastDataWriteCycle{0}; - // Some USB-Serial adaptors either don't support CTS, or send the signal - // as inverted; we detect that when opening the port, and flip the signal - // when necessary + // When using software flow control, assume the device starts in READY mode + bool myReadyStateSoftFlow{true}; + + // Some USB-Serial adaptors send the CTS signal inverted; we detect + // that when opening the port, and flip the signal when necessary bool myCTSFlip{false}; // Holds information concerning serial port usage diff --git a/src/emucore/SerialPort.hxx b/src/emucore/SerialPort.hxx index f2ac5bf68..5525a51c7 100644 --- a/src/emucore/SerialPort.hxx +++ b/src/emucore/SerialPort.hxx @@ -43,7 +43,6 @@ class SerialPort /** Read a byte from the serial port. - NOTE: This is for potential future use; no class currently uses this. @param data Destination for the byte read from the port @return True if a byte was read, else false diff --git a/src/macos/SerialPortMACOS.cxx b/src/macos/SerialPortMACOS.cxx index 9745eceff..3a4d2530b 100644 --- a/src/macos/SerialPortMACOS.cxx +++ b/src/macos/SerialPortMACOS.cxx @@ -63,14 +63,21 @@ bool SerialPortMACOS::openPort(const string& device) return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool SerialPortMACOS::readByte(uInt8& data) +{ + if(myHandle) + return read(myHandle, &data, 1) == 1; + + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool SerialPortMACOS::writeByte(uInt8 data) { if(myHandle) - { -// cerr << "SerialPortMACOS::writeByte " << int(data) << endl; return write(myHandle, &data, 1) == 1; - } + return false; } diff --git a/src/macos/SerialPortMACOS.hxx b/src/macos/SerialPortMACOS.hxx index 12dbcf28e..3fd9595d3 100644 --- a/src/macos/SerialPortMACOS.hxx +++ b/src/macos/SerialPortMACOS.hxx @@ -40,6 +40,14 @@ class SerialPortMACOS : public SerialPort */ bool openPort(const string& device) override; + /** + Read a byte from the serial port. + + @param data Destination for the byte read from the port + @return True if a byte was read, else false + */ + bool readByte(uInt8& data) override; + /** Write a byte to the serial port. diff --git a/src/unix/SerialPortUNIX.cxx b/src/unix/SerialPortUNIX.cxx index 1105d2092..7c39b3fb9 100644 --- a/src/unix/SerialPortUNIX.cxx +++ b/src/unix/SerialPortUNIX.cxx @@ -49,7 +49,9 @@ bool SerialPortUNIX::openPort(const string& device) if(myHandle <= 0) return false; - // Open the device in nonblocking mode + // Clear buffers, then open the device in nonblocking mode + tcflush(myHandle, TCOFLUSH); + tcflush(myHandle, TCIFLUSH); fcntl(myHandle, F_SETFL, FNDELAY); struct termios termios; @@ -64,14 +66,21 @@ bool SerialPortUNIX::openPort(const string& device) return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool SerialPortUNIX::readByte(uInt8& data) +{ + if(myHandle) + return read(myHandle, &data, 1) == 1; + + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool SerialPortUNIX::writeByte(uInt8 data) { if(myHandle) - { -// cerr << "SerialPortUNIX::writeByte " << int(data) << endl; return write(myHandle, &data, 1) == 1; - } + return false; } diff --git a/src/unix/SerialPortUNIX.hxx b/src/unix/SerialPortUNIX.hxx index 4dec5a116..dbf5f3299 100644 --- a/src/unix/SerialPortUNIX.hxx +++ b/src/unix/SerialPortUNIX.hxx @@ -40,6 +40,14 @@ class SerialPortUNIX : public SerialPort */ bool openPort(const string& device) override; + /** + Read a byte from the serial port. + + @param data Destination for the byte read from the port + @return True if a byte was read, else false + */ + bool readByte(uInt8& data) override; + /** Write a byte to the serial port. diff --git a/src/windows/SerialPortWINDOWS.cxx b/src/windows/SerialPortWINDOWS.cxx index 91b6c0bb3..2772821d6 100644 --- a/src/windows/SerialPortWINDOWS.cxx +++ b/src/windows/SerialPortWINDOWS.cxx @@ -62,6 +62,14 @@ bool SerialPortWINDOWS::openPort(const string& device) dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; SetCommState(myHandle, &dcb); + + COMMTIMEOUTS commtimeouts; + commtimeouts.ReadIntervalTimeout = MAXDWORD; + commtimeouts.ReadTotalTimeoutMultiplier = 0; + commtimeouts.ReadTotalTimeoutConstant = 1; + commtimeouts.WriteTotalTimeoutMultiplier = 0; + commtimeouts.WriteTotalTimeoutConstant = 0; + SetCommTimeouts(myHandle, &commtimeouts); } else return false; @@ -69,13 +77,26 @@ bool SerialPortWINDOWS::openPort(const string& device) return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool SerialPortWINDOWS::readByte(uInt8& data) +{ + if(myHandle) + { + DWORD read; + ReadFile(myHandle, &data, 1, &read, NULL); + return read == 1; + } + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool SerialPortWINDOWS::writeByte(uInt8 data) { if(myHandle) { DWORD written; - return WriteFile(myHandle, &data, 1, &written, 0) == TRUE; + WriteFile(myHandle, &data, 1, &written, NULL); + return written == 1; } return false; } diff --git a/src/windows/SerialPortWINDOWS.hxx b/src/windows/SerialPortWINDOWS.hxx index adab57ce6..9a7aec2e6 100644 --- a/src/windows/SerialPortWINDOWS.hxx +++ b/src/windows/SerialPortWINDOWS.hxx @@ -39,6 +39,14 @@ class SerialPortWINDOWS : public SerialPort */ bool openPort(const string& device) override; + /** + Read a byte from the serial port. + + @param data Destination for the byte read from the port + @return True if a byte was read, else false + */ + bool readByte(uInt8& data) override; + /** Write a byte to the serial port. From a380671a61ce9e1213c39b828fe17e93b1d423ba Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 21 Aug 2020 21:08:45 +0200 Subject: [PATCH 009/263] added Genesis autodetection for Zeviouz --- src/emucore/ControllerDetector.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 95922051b..622f59ca1 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -121,7 +121,7 @@ bool ControllerDetector::usesJoystickButton(const ByteBuffer& image, size_t size if(port == Controller::Jack::Left) { // check for INPT4 access - const int NUM_SIGS_0 = 23; + const int NUM_SIGS_0 = 24; const int SIG_SIZE_0 = 3; uInt8 signature_0[NUM_SIGS_0][SIG_SIZE_0] = { { 0x24, 0x0c, 0x10 }, // bit INPT4; bpl (joystick games only) @@ -139,6 +139,7 @@ bool ControllerDetector::usesJoystickButton(const ByteBuffer& image, size_t size { 0xb4, 0x0c, 0x30 }, // ldy INPT4|$30,x; bmi (joystick games only) { 0xa5, 0x3c, 0x2a }, // ldy INPT4|$30; rol (joystick games only) { 0xa6, 0x3c, 0x8e }, // ldx INPT4|$30; stx (joystick games only) + { 0xa6, 0x0c, 0x8e }, // ldx INPT4; stx (joystick games only) { 0xa4, 0x3c, 0x8c }, // ldy INPT4; sty (joystick games only, Scramble) { 0xa5, 0x0c, 0x8d }, // lda INPT4; sta (joystick games only, Super Cobra Arcade) { 0xa4, 0x0c, 0x30 }, // ldy INPT4|; bmi (only Game of Concentration) @@ -392,7 +393,7 @@ bool ControllerDetector::usesGenesisButton(const ByteBuffer& image, size_t size, if(port == Controller::Jack::Left) { // check for INPT1 access - const int NUM_SIGS_0 = 18; + const int NUM_SIGS_0 = 19; const int SIG_SIZE_0 = 3; uInt8 signature_0[NUM_SIGS_0][SIG_SIZE_0] = { { 0x24, 0x09, 0x10 }, // bit INPT1; bpl (Genesis only) @@ -408,6 +409,7 @@ bool ControllerDetector::usesGenesisButton(const ByteBuffer& image, size_t size, { 0xa4, 0x39, 0x30 }, // ldy INPT1|$30; bmi (keyboard ROMS too) { 0xa5, 0x39, 0x6a }, // lda INPT1|$30; ror (Genesis only) { 0xa6, 0x39, 0x8e }, // ldx INPT1|$30; stx (Genesis only) + { 0xa6, 0x09, 0x8e }, // ldx INPT1; stx (Genesis only) { 0xa4, 0x39, 0x8c }, // ldy INPT1|$30; sty (Genesis only, Scramble) { 0xa5, 0x09, 0x8d }, // lda INPT1; sta (Genesis only, Super Cobra Arcade) { 0xa5, 0x09, 0x29 }, // lda INPT1; and (Genesis only) From 857369aad50ca034b88304b90ad3bfd52024f9db Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 23 Aug 2020 10:58:36 +0200 Subject: [PATCH 010/263] fix attempt for #692 --- src/common/PJoystickHandler.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index 1af10feac..f9c616921 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -123,8 +123,8 @@ int PhysicalJoystickHandler::add(const PhysicalJoystickPtr& stick) { StickInfo info("", stick); myDatabase.emplace(stick->name, info); - setStickDefaultMapping(stick->ID, Event::NoType, EventMode::kEmulationMode, true); - setStickDefaultMapping(stick->ID, Event::NoType, EventMode::kMenuMode, true); + setStickDefaultMapping(stick->ID, Event::NoType, EventMode::kEmulationMode); + setStickDefaultMapping(stick->ID, Event::NoType, EventMode::kMenuMode); } return stick->ID; From 4126f0e65a8b2306cf1af5defd432ed8f458f148 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 25 Aug 2020 09:52:08 +0200 Subject: [PATCH 011/263] updated event version to force initial controller mapping --- Changes.txt | 5 +++++ src/emucore/Event.hxx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Changes.txt b/Changes.txt index d231d65da..ba992d5d2 100644 --- a/Changes.txt +++ b/Changes.txt @@ -49,6 +49,11 @@ -Have fun! +6.2.1 to 6.2.2 (August 25, 2020) + + * Fixed bug in initial controller mapping. + + 6.2 to 6.2.1: (June 20, 2020) * Fixed Pitfall II ROM not working correctly. diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index 52808d77a..197f7569f 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -142,7 +142,7 @@ class Event }; // Event list version, update only if the id of existing(!) event types changed - static constexpr Int32 VERSION = 4; + static constexpr Int32 VERSION = 5; using EventSet = std::set; From 2abd94640edc2331a5c078ea90b2145a2f456199 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 26 Aug 2020 17:57:32 +0200 Subject: [PATCH 012/263] enabled "Whole Program Optimization" for release versions (~5% faster in Turbo mode) --- src/windows/Stella.vcxproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 52a8c4327..b407d547a 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -342,7 +342,7 @@ true - false + true ..\yacc;..\emucore;..\emucore\tia;..\emucore\tia\frame-manager;..\common;..\common\tv_filters;..\gui;..\debugger\gui;..\debugger;..\windows;..\cheat;..\zlib;..\libpng;%(AdditionalIncludeDirectories) BSPF_WINDOWS;WIN32;NOMINMAX;NDEBUG;SDL_SUPPORT;GUI_SUPPORT;PNG_SUPPORT;ZIP_SUPPORT;JOYSTICK_SUPPORT;DEBUGGER_SUPPORT;WINDOWED_SUPPORT;SOUND_SUPPORT;CHEATCODE_SUPPORT;%(PreprocessorDefinitions) MultiThreadedDLL @@ -432,6 +432,7 @@ CompileAsCpp NoListing $(IntDir)asm\windows\%(RelativeDir) + true SDL2.lib;SDL2main.lib;%(AdditionalDependencies) From 7a20279fe0d75197739eebf2c30f795e37e234cc Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 26 Aug 2020 15:27:41 -0230 Subject: [PATCH 013/263] Add '--enable-release' to configure script, which for now sets the Makefile to use LTO. --- Makefile | 5 +++++ configure | 14 +++++++++++--- debian/rules | 2 +- src/unix/stella.spec | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 08cfc640c..168ae178d 100644 --- a/Makefile +++ b/Makefile @@ -80,6 +80,11 @@ else endif endif +ifdef RELEASE + CXXFLAGS += -flto + LDFLAGS += -flto +endif + ####################################################################### # Misc stuff - you should never have to edit this # ####################################################################### diff --git a/configure b/configure index 4fb2cf08d..31281ec4c 100755 --- a/configure +++ b/configure @@ -26,6 +26,7 @@ _build_sqlite=no _build_static=no _build_profile=no _build_debug=no +_build_release=no # more defaults _ranlib=ranlib @@ -261,8 +262,10 @@ for ac_option in $@; do --disable-static) _build_static=no ;; --enable-profile) _build_profile=yes ;; --disable-profile) _build_profile=no ;; - --enable-debug) _build_debug=yes ;; - --disable-debug) _build_debug=false ;; + --enable-debug) _build_debug=yes ;; + --disable-debug) _build_debug=no ;; + --enable-release) _build_release=yes ;; + --disable-release) _build_release=no ;; --with-sdl-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` _sdlpath="$arg:$arg/bin" @@ -277,7 +280,7 @@ for ac_option in $@; do ZLIB_CFLAGS="-I$_prefix/include" ZLIB_LIBS="-L$_prefix/lib" ;; - --with-sqlite-prefix=*) + --with-sqlite-prefix=*) _prefix=`echo $ac_option | cut -d '=' -f 2` SQLITE_CFLAGS="-I$_prefix/include" SQLITE_LIBS="-L$_prefix/lib" @@ -925,6 +928,10 @@ if test "$_build_debug" = no ; then _build_debug= fi +if test "$_build_release" = no ; then + _build_release= +fi + echo "Creating config.mak" cat > config.mak << EOF # -------- Generated by configure ----------- @@ -958,6 +965,7 @@ DOCDIR := $_docdir DATADIR := $_datadir PROFILE := $_build_profile DEBUG := $_build_debug +RELEASE := $_build_release $_make_def_HAVE_GCC $_make_def_HAVE_CLANG diff --git a/debian/rules b/debian/rules index 35b3c2ff4..2e9b442c1 100755 --- a/debian/rules +++ b/debian/rules @@ -20,7 +20,7 @@ endif config.status: configure dh_testdir - CXXFLAGS="$(CXXFLAGS)" ./configure --prefix=/usr + CXXFLAGS="$(CXXFLAGS)" ./configure --prefix=/usr --enable-release build: build-stamp diff --git a/src/unix/stella.spec b/src/unix/stella.spec index c54cf259a..ad6819995 100644 --- a/src/unix/stella.spec +++ b/src/unix/stella.spec @@ -33,7 +33,7 @@ on your PC. %build export CXXFLAGS=$RPM_OPT_FLAGS -%configure \ +%configure --enable-release \ %if %enable_sound --enable-sound \ %else From 2d2103039466d7ee9dde1e465c695c7a34095417 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 26 Aug 2020 23:39:20 +0200 Subject: [PATCH 014/263] added delayed background color glitch developer option --- Changes.txt | 4 +++- src/emucore/Settings.cxx | 5 ++++- src/emucore/tia/TIA.cxx | 25 +++++++++++++++++++++++-- src/emucore/tia/TIA.hxx | 8 ++++++++ src/gui/DeveloperDialog.cxx | 19 +++++++++++++++++++ src/gui/DeveloperDialog.hxx | 3 +++ 6 files changed, 60 insertions(+), 4 deletions(-) diff --git a/Changes.txt b/Changes.txt index ba992d5d2..b0691039e 100644 --- a/Changes.txt +++ b/Changes.txt @@ -41,6 +41,8 @@ * Added option to display detected settings info when a ROM is loaded. + * Added another oddball TIA glitch option for delayed background color. (TODO: DOC) + * Replaced "Re-disassemble" with "Disassemble @ current line" in debugger. * Fixed bug when taking fullscreen snapshots; the dimensions were @@ -51,7 +53,7 @@ 6.2.1 to 6.2.2 (August 25, 2020) - * Fixed bug in initial controller mapping. + * Fixed a bug in initial controller mapping. 6.2 to 6.2.1: (June 20, 2020) diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 5cf836954..e9d0de8c8 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -220,6 +220,7 @@ Settings::Settings() setPermanent("dev.tia.blinvphase", "true"); setPermanent("dev.tia.delaypfbits", "true"); setPermanent("dev.tia.delaypfcolor", "true"); + setPermanent("dev.tia.delaybkcolor", "true"); setPermanent("dev.tia.delayplswap", "true"); setPermanent("dev.tia.delayblswap", "true"); setPermanent("dev.timemachine", true); @@ -659,13 +660,15 @@ void Settings::usage() const << " -dev.tia.type \n" + << " quickstep|\n" + << " indy500|heman|>\n" << " -dev.tia.plinvphase <1|0> Enable inverted HMOVE clock phase for players\n" << " -dev.tia.msinvphase <1|0> Enable inverted HMOVE clock phase for\n" << " missiles\n" << " -dev.tia.blinvphase <1|0> Enable inverted HMOVE clock phase for ball\n" << " -dev.tia.delaypfbits <1|0> Enable extra delay cycle for PF bits access\n" << " -dev.tia.delaypfcolor <1|0> Enable extra delay cycle for PF color\n" + << " -dev.tia.delaybkcolor <1|0> Enable extra delay cycle for background color\n" << " -dev.tia.delayplswap <1|0> Enable extra delay cycle for VDELP0/1 swap\n" << " -dev.tia.delayblswap <1|0> Enable extra delay cycle for VDELBL swap\n" << endl << std::flush; diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index b3a48c335..7e4cdbf04 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -285,6 +285,7 @@ bool TIA::save(Serializer& out) const out.putByte(myPFBitsDelay); out.putByte(myPFColorDelay); + out.putByte(myBKColorDelay); out.putByte(myPlSwapDelay); } catch(...) @@ -356,6 +357,7 @@ bool TIA::load(Serializer& in) myPFBitsDelay = in.getByte(); myPFColorDelay = in.getByte(); + myBKColorDelay = in.getByte(); myPlSwapDelay = in.getByte(); // Re-apply dev settings @@ -605,8 +607,13 @@ bool TIA::poke(uInt16 address, uInt8 value) case COLUBK: { value &= 0xFE; - myBackground.setColor(value); - myShadowRegisters[address] = value; + if(myBKColorDelay) + myDelayQueue.push(COLUBK, value, 1); + else + { + myBackground.setColor(value); + myShadowRegisters[address] = value; + } #ifdef DEBUGGER_SUPPORT uInt16 dataAddr = mySystem->m6502().lastDataAddressForPoke(); if(dataAddr) @@ -918,6 +925,9 @@ void TIA::applyDeveloperSettings() setPFColorDelay(custom ? mySettings.getBool("dev.tia.delaypfcolor") : BSPF::equalsIgnoreCase("quickstep", mySettings.getString("dev.tia.type"))); + setBKColorDelay(custom + ? mySettings.getBool("dev.tia.delaybkcolor") + : BSPF::equalsIgnoreCase("indy500", mySettings.getString("dev.tia.type"))); setPlSwapDelay(custom ? mySettings.getBool("dev.tia.delayplswap") : BSPF::equalsIgnoreCase("heman", mySettings.getString("dev.tia.type"))); @@ -930,6 +940,7 @@ void TIA::applyDeveloperSettings() setBlInvertedPhaseClock(false); setPFBitsDelay(false); setPFColorDelay(false); + setBKColorDelay(false); setPlSwapDelay(false); setBlSwapDelay(false); } @@ -1608,6 +1619,12 @@ void TIA::setPFColorDelay(bool delayed) myPFColorDelay = delayed ? 1 : 0; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::setBKColorDelay(bool delayed) +{ + myBKColorDelay = delayed ? 1 : 0; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::setPlSwapDelay(bool delayed) { @@ -1683,6 +1700,10 @@ void TIA::delayedWrite(uInt8 address, uInt8 value) myPlayfield.pf2(value); break; + case COLUBK: + myBackground.setColor(value); + break; + case COLUPF: myPlayfield.setColor(value); myBall.setColor(value); diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 608caf184..ada06a042 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -435,6 +435,13 @@ class TIA : public Device */ void setPFColorDelay(bool delayed); + /** + Enables/disables delayed background colors. + + @param delayed Wether to enable delayed background colors + */ + void setBKColorDelay(bool delayed); + /** Enables/disables delayed player swapping. @@ -740,6 +747,7 @@ class TIA : public Device */ uInt8 myPFBitsDelay{0}; uInt8 myPFColorDelay{0}; + uInt8 myBKColorDelay{0}; uInt8 myPlSwapDelay{0}; uInt8 myBlSwapDelay{0}; diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index 336c5e1e8..6406e33d5 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -233,6 +233,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) VarList::push_back(items, "Faulty Cosmic Ark stars", "cosmicark"); VarList::push_back(items, "Glitched Pesco", "pesco"); VarList::push_back(items, "Glitched Quick Step!", "quickstep"); + VarList::push_back(items, "Glitched Indy 500 menu", "indy500"); VarList::push_back(items, "Glitched He-Man title", "heman"); VarList::push_back(items, "Custom", "custom"); myTIATypeWidget = new PopUpWidget(myTab, font, HBORDER + INDENT, ypos - 1, @@ -271,6 +272,15 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) wid.push_back(myPFColorWidget); ypos += lineHeight + VGAP * 1; + myBackgroundLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, + "Delayed background"); + wid.push_back(myBackgroundLabel); + ypos += lineHeight + VGAP * 1; + + myBKColorWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 3, ypos + 1, "Color"); + wid.push_back(myBKColorWidget); + ypos += lineHeight + VGAP * 1; + ostringstream ss; ss << "Delayed VDEL" << ELLIPSIS << " swap for"; mySwapLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, ss.str()); @@ -644,6 +654,7 @@ void DeveloperDialog::loadSettings(SettingsSet set) myBlInvPhase[set] = devSettings ? instance().settings().getBool("dev.tia.blinvphase") : false; myPFBits[set] = devSettings ? instance().settings().getBool("dev.tia.delaypfbits") : false; myPFColor[set] = devSettings ? instance().settings().getBool("dev.tia.delaypfcolor") : false; + myBKColor[set] = devSettings ? instance().settings().getBool("dev.tia.delaybkcolor") : false; myPlSwap[set] = devSettings ? instance().settings().getBool("dev.tia.delayplswap") : false; myBlSwap[set] = devSettings ? instance().settings().getBool("dev.tia.delayblswap") : false; @@ -708,6 +719,7 @@ void DeveloperDialog::saveSettings(SettingsSet set) instance().settings().setValue("dev.tia.blinvphase", myBlInvPhase[set]); instance().settings().setValue("dev.tia.delaypfbits", myPFBits[set]); instance().settings().setValue("dev.tia.delaypfcolor", myPFColor[set]); + instance().settings().setValue("dev.tia.delaybkcolor", myBKColor[set]); instance().settings().setValue("dev.tia.delayplswap", myPlSwap[set]); instance().settings().setValue("dev.tia.delayblswap", myBlSwap[set]); } @@ -762,6 +774,7 @@ void DeveloperDialog::getWidgetStates(SettingsSet set) myBlInvPhase[set] = myBlInvPhaseWidget->getState(); myPFBits[set] = myPFBitsWidget->getState(); myPFColor[set] = myPFColorWidget->getState(); + myBKColor[set] = myBKColorWidget->getState(); myPlSwap[set] = myPlSwapWidget->getState(); myBlSwap[set] = myBlSwapWidget->getState(); @@ -909,6 +922,7 @@ void DeveloperDialog::saveConfig() instance().console().tia().setBlInvertedPhaseClock(myBlInvPhaseWidget->getState()); instance().console().tia().setPFBitsDelay(myPFBitsWidget->getState()); instance().console().tia().setPFColorDelay(myPFColorWidget->getState()); + instance().console().tia().setBKColorDelay(myBKColorWidget->getState()); instance().console().tia().setPlSwapDelay(myPlSwapWidget->getState()); instance().console().tia().setBlSwapDelay(myBlSwapWidget->getState()); } @@ -995,6 +1009,7 @@ void DeveloperDialog::setDefaults() myBlInvPhase[set] = devSettings ? true : false; myPFBits[set] = devSettings ? true : false; myPFColor[set] = devSettings ? true : false; + myBKColor[set] = devSettings ? true : false; myPlSwap[set] = devSettings ? true : false; myBlSwap[set] = devSettings ? true : false; @@ -1210,8 +1225,10 @@ void DeveloperDialog::handleTia() myMsInvPhaseWidget->setEnabled(enable); myBlInvPhaseWidget->setEnabled(enable); myPlayfieldLabel->setEnabled(enable); + myBackgroundLabel->setEnabled(enable); myPFBitsWidget->setEnabled(enable); myPFColorWidget->setEnabled(enable); + myBKColorWidget->setEnabled(enable); mySwapLabel->setEnabled(enable); myPlSwapWidget->setEnabled(enable); myBlSwapWidget->setEnabled(enable); @@ -1223,6 +1240,7 @@ void DeveloperDialog::handleTia() myBlInvPhaseWidget->setState(myBlInvPhase[SettingsSet::developer]); myPFBitsWidget->setState(myPFBits[SettingsSet::developer]); myPFColorWidget->setState(myPFColor[SettingsSet::developer]); + myBKColorWidget->setState(myBKColor[SettingsSet::developer]); myPlSwapWidget->setState(myPlSwap[SettingsSet::developer]); myBlSwapWidget->setState(myBlSwap[SettingsSet::developer]); } @@ -1233,6 +1251,7 @@ void DeveloperDialog::handleTia() myBlInvPhaseWidget->setState(false); myPFBitsWidget->setState(BSPF::equalsIgnoreCase("pesco", myTIATypeWidget->getSelectedTag().toString())); myPFColorWidget->setState(BSPF::equalsIgnoreCase("quickstep", myTIATypeWidget->getSelectedTag().toString())); + myBKColorWidget->setState(BSPF::equalsIgnoreCase("indy500", myTIATypeWidget->getSelectedTag().toString())); myPlSwapWidget->setState(BSPF::equalsIgnoreCase("heman", myTIATypeWidget->getSelectedTag().toString())); myBlSwapWidget->setState(false); } diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx index c2e88828b..f66d58378 100644 --- a/src/gui/DeveloperDialog.hxx +++ b/src/gui/DeveloperDialog.hxx @@ -115,6 +115,8 @@ class DeveloperDialog : public Dialog StaticTextWidget* myPlayfieldLabel{nullptr}; CheckboxWidget* myPFBitsWidget{nullptr}; CheckboxWidget* myPFColorWidget{nullptr}; + StaticTextWidget* myBackgroundLabel{nullptr}; + CheckboxWidget* myBKColorWidget{nullptr}; StaticTextWidget* mySwapLabel{nullptr}; CheckboxWidget* myPlSwapWidget{nullptr}; CheckboxWidget* myBlSwapWidget{nullptr}; @@ -172,6 +174,7 @@ class DeveloperDialog : public Dialog std::array myBlInvPhase; std::array myPFBits; std::array myPFColor; + std::array myBKColor; std::array myPlSwap; std::array myBlSwap; // States sets From eb3bde80d9c3dcb92d06cd4e86033b726935831d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 27 Aug 2020 14:06:16 +0200 Subject: [PATCH 015/263] documented new delayed background color glitch developer option --- Changes.txt | 2 +- docs/graphics/options_developer_tia.png | Bin 5825 -> 3659 bytes docs/index.html | 12 +++++++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Changes.txt b/Changes.txt index b0691039e..31e2254ef 100644 --- a/Changes.txt +++ b/Changes.txt @@ -41,7 +41,7 @@ * Added option to display detected settings info when a ROM is loaded. - * Added another oddball TIA glitch option for delayed background color. (TODO: DOC) + * Added another oddball TIA glitch option for delayed background color. * Replaced "Re-disassemble" with "Disassemble @ current line" in debugger. diff --git a/docs/graphics/options_developer_tia.png b/docs/graphics/options_developer_tia.png index ee3a3973c77da92ab7c8de2aee6bd670167b5092..0d819416a4141bfa3e8ec4fa604ba0a73cdb7071 100644 GIT binary patch literal 3659 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 literal 5825 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 enabled, each read or write access to the AtariVox/SaveKey EEPROM is signalled by a message. -
-dev.tia.type <standard|koolaidman|
cosmicark|pesco|quickstep|heman|custom>
+
-dev.tia.type <standard|koolaidman|cosmicark|
pesco|quickstep|indy500|heman|custom>
Set emulated TIA type.
-dev.tia.plinvphase <1|0>
@@ -2957,6 +2957,9 @@
-dev.tia.delaypfcolor <1|0>
Enable/disable playfield color delayed by one color clock (colored step borders in Quick Step!). + +
-dev.tia.delaybkcolor <1|0>
+ Enable/disable background color delayed by one color clock (stray pixels in Indy 500 menu hack).
-dev.tia.delayplswap <1|0>
Enable/disable player swap delayed by one color clock (He-Man title glitch). @@ -3650,10 +3653,13 @@ Inverted HMOVE clock...Emulates the Kool-Aid Man collision and Cosmic Ark stars glitches for the given objects. -dev.tia.plinvphase
-dev.tia.msinvphase
-dev.tia.blinvphase - Delayed PlayfieldEmulates playfield registers delayed + Delayed PlayfieldEmulates playfield register changes delayed by one color clock. This e.g. causes glitches in Pesco (stray playfield - pixel) and Quick Step! (colored step borders) + pixel) and Quick Step! (colored step borders). -dev.tia.delaypfbits
-dev.tia.delaypfcolor + Delayed BackgroundEmulates background color register changes delayed + by one color clock. This causes stray pixel in the Indy 500 menu hack. + -dev.tia.delaybkcolor Delayed VDEL... swap forEmulates a VDELP0/P1/BL swap delayed by one color clock. This e.g cause glitches in the He-Man title screen. From 61601ed6ae627b80d204af6fc0ee63416e890399 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Mon, 31 Aug 2020 10:33:37 +0200 Subject: [PATCH 016/263] initial commit for QuadTari support (see #693) --- src/common/PKeyboardHandler.cxx | 17 +++++++++ src/emucore/Console.cxx | 13 ++++--- src/emucore/Control.cxx | 2 +- src/emucore/Control.hxx | 6 ++-- src/emucore/Event.hxx | 13 +++++-- src/emucore/EventHandler.cxx | 56 ++++++++++++++++++++++++++++++ src/emucore/EventHandler.hxx | 2 +- src/gui/GameInfoDialog.cxx | 2 +- src/windows/Stella.vcxproj | 2 ++ src/windows/Stella.vcxproj.filters | 6 ++++ 10 files changed, 107 insertions(+), 12 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 7532a1632..ab4f69906 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -658,6 +658,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoyst {Event::JoystickZeroFire9, KBDK_5}, {Event::JoystickZeroFire9, KBDK_RCTRL}, {Event::JoystickZeroFire9, KBDK_KP_3}, + {Event::JoystickOneUp, KBDK_Y}, {Event::JoystickOneDown, KBDK_H}, {Event::JoystickOneLeft, KBDK_G}, @@ -665,6 +666,22 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoyst {Event::JoystickOneFire, KBDK_F}, {Event::JoystickOneFire5, KBDK_6}, {Event::JoystickOneFire9, KBDK_7}, + + {Event::JoystickTwoUp, KBDK_UP, KBDM_SHIFT}, + {Event::JoystickTwoDown, KBDK_DOWN, KBDM_SHIFT}, + {Event::JoystickTwoLeft, KBDK_LEFT, KBDM_SHIFT}, + {Event::JoystickTwoRight, KBDK_RIGHT, KBDM_SHIFT}, + {Event::JoystickTwoUp, KBDK_KP_8, KBDM_SHIFT}, + {Event::JoystickTwoDown, KBDK_KP_2, KBDM_SHIFT}, + {Event::JoystickTwoLeft, KBDK_KP_4, KBDM_SHIFT}, + {Event::JoystickTwoRight, KBDK_KP_6, KBDM_SHIFT}, + {Event::JoystickTwoFire, KBDK_SPACE, KBDM_SHIFT}, + + {Event::JoystickThreeUp, KBDK_Y, KBDM_SHIFT}, + {Event::JoystickThreeDown, KBDK_H, KBDM_SHIFT}, + {Event::JoystickThreeLeft, KBDK_G, KBDM_SHIFT}, + {Event::JoystickThreeRight, KBDK_J, KBDM_SHIFT}, + {Event::JoystickThreeFire, KBDK_F, KBDM_SHIFT}, }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 9cb5c5087..98bb7e98c 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -35,6 +35,11 @@ #include "Genesis.hxx" #include "MindLink.hxx" #include "CompuMate.hxx" +#include "AmigaMouse.hxx" +#include "AtariMouse.hxx" +#include "TrakBall.hxx" +#include "Lightgun.hxx" +#include "QuadTari.hxx" #include "M6502.hxx" #include "M6532.hxx" #include "TIA.hxx" @@ -46,10 +51,6 @@ #include "Sound.hxx" #include "Switches.hxx" #include "System.hxx" -#include "AmigaMouse.hxx" -#include "AtariMouse.hxx" -#include "TrakBall.hxx" -#include "Lightgun.hxx" #include "FrameBuffer.hxx" #include "TIASurface.hxx" #include "OSystem.hxx" @@ -927,6 +928,10 @@ unique_ptr Console::getControllerPort(const Controller::Type type, controller = make_unique(port, myEvent, *mySystem, romMd5, myOSystem.frameBuffer()); break; + case Controller::Type::QuadTari: + controller = make_unique(port, myEvent, *mySystem); + break; + default: // What else can we do? // always create because it may have been changed by user dialog diff --git a/src/emucore/Control.cxx b/src/emucore/Control.cxx index 813063c04..0dfdc79d3 100644 --- a/src/emucore/Control.cxx +++ b/src/emucore/Control.cxx @@ -125,7 +125,7 @@ string Controller::getPropName(const Type type) "AMIGAMOUSE", "ATARIMOUSE", "ATARIVOX", "BOOSTERGRIP", "COMPUMATE", "DRIVING", "GENESIS", "JOYSTICK", "KEYBOARD", "KIDVID", "MINDLINK", "PADDLES", "PADDLES_IAXIS", "PADDLES_IAXDR", "SAVEKEY", "TRAKBALL", - "LIGHTGUN" + "LIGHTGUN", "QUADTARI" }; return PROP_NAMES[int(type)]; diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx index 629a2afee..d1ed02b8b 100644 --- a/src/emucore/Control.hxx +++ b/src/emucore/Control.hxx @@ -94,7 +94,7 @@ class Controller : public Serializable AmigaMouse, AtariMouse, AtariVox, BoosterGrip, CompuMate, Driving, Genesis, Joystick, Keyboard, KidVid, MindLink, Paddles, PaddlesIAxis, PaddlesIAxDr, SaveKey, TrakBall, - Lightgun, + Lightgun, QuadTari, LastType }; @@ -178,12 +178,12 @@ class Controller : public Serializable Update the entire digital and analog pin state according to the events currently set. */ - virtual void update() = 0; + virtual void update() { }; /** Returns the name of this controller. */ - virtual string name() const = 0; + virtual string name() const { return ""; } /** Answers whether the controller is intrinsically an analog controller. diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index 197f7569f..bd4a7dae7 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -123,12 +123,17 @@ class Event ToggleFrameStats, ToggleSAPortOrder, ExitGame, SettingDecrease, SettingIncrease, PreviousSetting, NextSetting, ToggleAdaptRefresh, PreviousMultiCartRom, - // add new events from here to avoid that user remapped events get overwritten + // add new (after Version 4) events from here to avoid that user remapped events get overwritten PreviousSettingGroup, NextSettingGroup, TogglePlayBackMode, DecreaseAutoFire, IncreaseAutoFire, DecreaseSpeed, IncreaseSpeed, + JoystickTwoUp, JoystickTwoDown, JoystickTwoLeft, JoystickTwoRight, + JoystickTwoFire, + JoystickThreeUp, JoystickThreeDown, JoystickThreeLeft, JoystickThreeRight, + JoystickThreeFire, + LastType }; @@ -217,11 +222,15 @@ class Event static const Event::EventSet LeftJoystickEvents = { Event::JoystickZeroUp, Event::JoystickZeroDown, Event::JoystickZeroLeft, Event::JoystickZeroRight, Event::JoystickZeroFire, Event::JoystickZeroFire5, Event::JoystickZeroFire9, + Event::JoystickTwoUp, Event::JoystickTwoDown, Event::JoystickTwoLeft, Event::JoystickTwoRight, + Event::JoystickTwoFire }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static const Event::EventSet RightJoystickEvents = { Event::JoystickOneUp, Event::JoystickOneDown, Event::JoystickOneLeft, Event::JoystickOneRight, - Event::JoystickOneFire, Event::JoystickOneFire5, Event::JoystickOneFire9 + Event::JoystickOneFire, Event::JoystickOneFire5, Event::JoystickOneFire9, + Event::JoystickThreeUp, Event::JoystickThreeDown, Event::JoystickThreeLeft, Event::JoystickThreeRight, + Event::JoystickThreeFire }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index ed72579a6..5e3522624 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -620,6 +620,46 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) myEvent.set(Event::JoystickOneLeft, 0); break; + case Event::JoystickTwoUp: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickTwoDown, 0); + break; + + case Event::JoystickTwoDown: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickTwoUp, 0); + break; + + case Event::JoystickTwoLeft: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickTwoRight, 0); + break; + + case Event::JoystickTwoRight: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickTwoLeft, 0); + break; + + case Event::JoystickThreeUp: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickThreeDown, 0); + break; + + case Event::JoystickThreeDown: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickThreeUp, 0); + break; + + case Event::JoystickThreeLeft: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickThreeRight, 0); + break; + + case Event::JoystickThreeRight: + if(!myAllowAllDirectionsFlag && pressed) + myEvent.set(Event::JoystickThreeLeft, 0); + break; + /////////////////////////////////////////////////////////////////////////// // Audio & Video events (with global hotkeys) case Event::VolumeDecrease: @@ -2467,6 +2507,18 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::JoystickOneFire5, "P1 Booster Top Booster Button", "" }, { Event::JoystickOneFire9, "P1 Booster Handle Grip Trigger", "" }, + { Event::JoystickTwoUp, "P2 Joystick Up", "" }, + { Event::JoystickTwoDown, "P2 Joystick Down", "" }, + { Event::JoystickTwoLeft, "P2 Joystick Left", "" }, + { Event::JoystickTwoRight, "P2 Joystick Right", "" }, + { Event::JoystickTwoFire, "P2 Joystick Fire", "" }, + + { Event::JoystickThreeUp, "P3 Joystick Up", "" }, + { Event::JoystickThreeDown, "P3 Joystick Down", "" }, + { Event::JoystickThreeLeft, "P3 Joystick Left", "" }, + { Event::JoystickThreeRight, "P3 Joystick Right", "" }, + { Event::JoystickThreeFire, "P3 Joystick Fire", "" }, + { Event::PaddleZeroAnalog, "Paddle 0 Analog", "" }, { Event::PaddleZeroIncrease, "Paddle 0 Turn Left", "" }, { Event::PaddleZeroDecrease, "Paddle 0 Turn Right", "" }, @@ -2711,6 +2763,10 @@ const Event::EventSet EventHandler::JoystickEvents = { Event::JoystickZeroFire, Event::JoystickZeroFire5, Event::JoystickZeroFire9, Event::JoystickOneUp, Event::JoystickOneDown, Event::JoystickOneLeft, Event::JoystickOneRight, Event::JoystickOneFire, Event::JoystickOneFire5, Event::JoystickOneFire9, + Event::JoystickTwoUp, Event::JoystickTwoDown, Event::JoystickTwoLeft, Event::JoystickTwoRight, + Event::JoystickTwoFire, + Event::JoystickThreeUp, Event::JoystickThreeDown, Event::JoystickThreeLeft, Event::JoystickThreeRight, + Event::JoystickThreeFire, }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 4c7954c40..e1990a440 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -559,7 +559,7 @@ class EventHandler #else REFRESH_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 164 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, + EMUL_ACTIONLIST_SIZE = 174 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, MENU_ACTIONLIST_SIZE = 18 ; diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 6017c65d3..e960ab419 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -227,6 +227,7 @@ GameInfoDialog::GameInfoDialog( VarList::push_back(ctrls, "KidVid", "KIDVID"); VarList::push_back(ctrls, "Lightgun", "LIGHTGUN"); VarList::push_back(ctrls, "MindLink", "MINDLINK"); + VarList::push_back(ctrls, "QuadTari", "QUADTARI"); ypos = VBORDER; pwidth = font.getStringWidth("Paddles_IAxis"); @@ -771,7 +772,6 @@ void GameInfoDialog::updateControllerStates() myPaddleXCenter->setEnabled(enablePaddles); myPaddleYCenter->setEnabled(enablePaddles); - bool enableMouse = enablePaddles || BSPF::startsWithIgnoreCase(contrLeft, "Driving") || BSPF::startsWithIgnoreCase(contrRight, "Driving") || diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index b407d547a..71c5d6f30 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -746,6 +746,7 @@ + @@ -1775,6 +1776,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 5875efb8c..be6cc8424 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1017,6 +1017,9 @@ Source Files\gui + + Source Files\emucore + @@ -2090,6 +2093,9 @@ Header Files\emucore + + Header Files\emucore + From ef962e53ef3f42334f4ac98823afc81a97a776b5 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Mon, 31 Aug 2020 14:17:12 +0200 Subject: [PATCH 017/263] micro typo --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 65e416468..ffb2c5c55 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3624,7 +3624,7 @@ -dev.rwportbreak - Break on write to ... + Break on writes to ... A write to a read port interrupts emulation and the debugger is entered. -dev.wrportbreak From cf2922a2b18c6dcbb5a207bac102b623a8fa76a7 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 1 Sep 2020 07:52:21 +0200 Subject: [PATCH 018/263] fixes #695 (wrong RWPs) (directPokeBase must NOT be set! (partially reverts b264e7634 and 5568dd300) --- src/emucore/CartEnhanced.cxx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 633104cf3..b401da819 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -91,14 +91,12 @@ void CartridgeEnhanced::install(System& system) System::PageAccess access(this, System::PageAccessType::READ); // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens + // Note: Writes are mapped to poke() (NOT using direcPokeBase) to check for read from write port (RWP) access.type = System::PageAccessType::WRITE; for(uInt16 addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) { const uInt16 offset = addr & myRamMask; - access.directPokeBase = &myRAM[offset]; access.romAccessBase = &myRomAccessBase[myWriteOffset + offset]; access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset]; access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize]; @@ -107,7 +105,6 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM reading pages access.type = System::PageAccessType::READ; - access.directPokeBase = nullptr; for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { const uInt16 offset = addr & myRamMask; @@ -263,6 +260,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) myCurrentSegOffset[segment] = uInt32(mySize) + (ramBank << myBankShift); // Set the page accessing method for the RAM writing pages + // Note: Writes are mapped to poke() (NOT using direcPokeBase) to check for read from write port (RWP) uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myWriteOffset) & ~System::PAGE_MASK; uInt16 toAddr = (ROM_OFFSET + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; System::PageAccess access(this, System::PageAccessType::WRITE); @@ -271,7 +269,6 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) { const uInt32 offset = bankOffset + (addr & myRamMask); - access.directPokeBase = &myRAM[offset - mySize]; access.romAccessBase = &myRomAccessBase[offset]; access.romPeekCounter = &myRomAccessCounter[offset]; access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; @@ -282,7 +279,6 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) fromAddr = (ROM_OFFSET + segmentOffset + myReadOffset) & ~System::PAGE_MASK; toAddr = (ROM_OFFSET + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; access.type = System::PageAccessType::READ; - access.directPokeBase = nullptr; for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) { From 93e1d0945cddc9e42a7345d5500848003cae7dec Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 1 Sep 2020 08:01:09 +0200 Subject: [PATCH 019/263] fixed 3E+ peeks and pokes (using 3E code now) --- src/emucore/Cart3EPlus.cxx | 25 ------------------------- src/emucore/Cart3EPlus.hxx | 17 ----------------- 2 files changed, 42 deletions(-) diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 2233b0d71..41f3ef21b 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -59,28 +59,3 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value) } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 Cartridge3EPlus::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= ROM_MASK; - - if(address < 0x0040) // TIA peek - return mySystem->tia().peek(address); - - return CartridgeEnhanced::peek(peekAddress); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3EPlus::poke(uInt16 address, uInt8 value) -{ - if(CartridgeEnhanced::poke(address, value)) - return true; - - if(address < 0x0040) // TIA poke - // Handle TIA space that we claimed above - return mySystem->tia().poke(address, value); - - return false; -} diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index bdb8f85f5..d09a445ce 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -124,23 +124,6 @@ class Cartridge3EPlus: public Cartridge3E } #endif - public: - /** - Get the byte at the specified address - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: bool checkSwitchBank(uInt16 address, uInt8 value) override; From 268d152ea381115fc5497d250a90114e578ee093 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 1 Sep 2020 08:09:03 +0200 Subject: [PATCH 020/263] add missing files --- src/emucore/QuadTari.cxx | 73 ++++++++++++++++ src/emucore/QuadTari.hxx | 102 +++++++++++++++++++++++ src/emucore/module.mk | 175 ++++++++++++++++++++------------------- 3 files changed, 263 insertions(+), 87 deletions(-) create mode 100644 src/emucore/QuadTari.cxx create mode 100644 src/emucore/QuadTari.hxx diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx new file mode 100644 index 000000000..55adf8c53 --- /dev/null +++ b/src/emucore/QuadTari.cxx @@ -0,0 +1,73 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "Event.hxx" +#include "Joystick.hxx" +#include "QuadTari.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +QuadTari::QuadTari(Jack jack, const Event& event, const System& system) + : Controller(jack, event, system, Controller::Type::QuadTari) +{ + // TODO: allow multiple controller types + if(myJack == Jack::Left) + { + myFirstController = make_unique(Jack::Left, event, system); + mySecondController = make_unique(Jack::Right, event, system); // TODO: use P2 mapping + } + else + { + myFirstController = make_unique(Jack::Right, event, system); + mySecondController = make_unique(Jack::Left, event, system); // TODO: use P3 mapping + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool QuadTari::read(DigitalPin pin) +{ + // We need to override the Controller::read() method, since the QuadTari + // can switch the controller multiple times per frame + // (we can't just read 60 times per second in the ::update() method) + + if(true) // TODO handle controller switch + return myFirstController->read(pin); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTari::update() +{ + myFirstController->update(); + mySecondController->update(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool QuadTari::isAnalog() const +{ + // TODO: does this work? + return myFirstController->isAnalog() || mySecondController->isAnalog(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool QuadTari::setMouseControl( + Controller::Type xtype, int xid, Controller::Type ytype, int yid) +{ + // TODO: does this work? + myFirstController->setMouseControl(xtype, xid, ytype, yid); + mySecondController->setMouseControl(xtype, xid, ytype, yid); + + return true; +} diff --git a/src/emucore/QuadTari.hxx b/src/emucore/QuadTari.hxx new file mode 100644 index 000000000..2499c5c2a --- /dev/null +++ b/src/emucore/QuadTari.hxx @@ -0,0 +1,102 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef QUADTARI_HXX +#define QUADTARI_HXX + +#include "Control.hxx" +#include "Event.hxx" + +/** + The QuadTari controller. + + @author Thomas Jentzsch +*/ +class QuadTari: public Controller +{ + public: + /** + Create a QuadTari controller plugged into + the specified jack + + @param jack The jack the controller is plugged into + @param event The event object to use for events + @param system The system using this controller + */ + QuadTari(Jack jack, const Event& event, const System& system); + ~QuadTari() override = default; + + public: + /** + Read the value of the specified digital pin for this controller. + + @param pin The pin of the controller jack to read + @return The state of the pin + */ + bool read(DigitalPin pin) override; + + /** + Update the entire digital and analog pin state according to the + events currently set. + */ + void update() override; + + /** + Returns the name of this controller. + // TODO: Or the names of the attached controllers? + */ + string name() const override { return "QuadTari"; } + + /** + Answers whether the controller is intrinsically an analog controller. + TODO: Depends on the attached controllers. + */ + bool isAnalog() const override; + + /** + Determines how this controller will treat values received from the + X/Y axis and left/right buttons of the mouse. Since not all controllers + use the mouse the same way (or at all), it's up to the specific class to + decide how to use this data. + + In the current implementation, the left button is tied to the X axis, + and the right one tied to the Y axis. + + @param xtype The controller to use for x-axis data + @param xid The controller ID to use for x-axis data (-1 for no id) + @param ytype The controller to use for y-axis data + @param yid The controller ID to use for y-axis data (-1 for no id) + + @return Whether the controller supports using the mouse + */ + bool setMouseControl( + Controller::Type xtype, int xid, Controller::Type ytype, int yid) override; + + private: + unique_ptr myFirstController; + unique_ptr mySecondController; + + private: + // Following constructors and assignment operators not supported + QuadTari() = delete; + QuadTari(const QuadTari&) = delete; + QuadTari(QuadTari&&) = delete; + QuadTari& operator=(const QuadTari&) = delete; + QuadTari& operator=(QuadTari&&) = delete; + }; + +#endif diff --git a/src/emucore/module.mk b/src/emucore/module.mk index 71bd33847..b7d88d331 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -1,95 +1,96 @@ MODULE := src/emucore MODULE_OBJS := \ - src/emucore/AtariVox.o \ - src/emucore/Bankswitch.o \ - src/emucore/Booster.o \ - src/emucore/Cart.o \ - src/emucore/CartCreator.o \ - src/emucore/CartDetector.o \ - src/emucore/CartEnhanced.o \ - src/emucore/Cart0840.o \ - src/emucore/Cart2K.o \ - src/emucore/Cart3E.o \ - src/emucore/Cart3EPlus.o \ - src/emucore/Cart3EX.o \ - src/emucore/Cart3F.o \ - src/emucore/Cart4A50.o \ - src/emucore/Cart4K.o \ - src/emucore/Cart4KSC.o \ - src/emucore/CartAR.o \ - src/emucore/CartBUS.o \ - src/emucore/CartCDF.o \ - src/emucore/CartCM.o \ - src/emucore/CartCTY.o \ - src/emucore/CartCV.o \ - src/emucore/CartDPC.o \ - src/emucore/CartDPCPlus.o \ - src/emucore/CartE0.o \ - src/emucore/CartMNetwork.o \ - src/emucore/CartE7.o \ - src/emucore/CartE78K.o \ - src/emucore/CartEF.o \ - src/emucore/CartEFSC.o \ - src/emucore/CartBF.o \ - src/emucore/CartBFSC.o \ - src/emucore/CartDF.o \ - src/emucore/CartDFSC.o \ - src/emucore/CartF0.o \ - src/emucore/CartF4.o \ - src/emucore/CartF4SC.o \ - src/emucore/CartF6.o \ - src/emucore/CartF6SC.o \ - src/emucore/CartF8.o \ - src/emucore/CartF8SC.o \ - src/emucore/CartFA.o \ - src/emucore/CartFA2.o \ - src/emucore/CartFC.o \ - src/emucore/CartFE.o \ - src/emucore/CartMDM.o \ - src/emucore/CartSB.o \ - src/emucore/CartTVBoy.o \ - src/emucore/CartUA.o \ - src/emucore/CartWD.o \ - src/emucore/CartX07.o \ - src/emucore/CompuMate.o \ - src/emucore/Console.o \ - src/emucore/Control.o \ - src/emucore/ControllerDetector.o \ - src/emucore/DispatchResult.o \ - src/emucore/Driving.o \ - src/emucore/EventHandler.o \ - src/emucore/EmulationTiming.o \ - src/emucore/EmulationWorker.o \ - src/emucore/FrameBuffer.o \ - src/emucore/FBSurface.o \ - src/emucore/FSNode.o \ - src/emucore/Genesis.o \ - src/emucore/Joystick.o \ - src/emucore/Keyboard.o \ - src/emucore/KidVid.o \ - src/emucore/Lightgun.o \ - src/emucore/MindLink.o \ - src/emucore/M6502.o \ - src/emucore/M6532.o \ - src/emucore/MT24LC256.o \ - src/emucore/MD5.o \ - src/emucore/OSystem.o \ - src/emucore/Paddles.o \ - src/emucore/PointingDevice.o \ - src/emucore/ProfilingRunner.o \ - src/emucore/Props.o \ - src/emucore/PropsSet.o \ - src/emucore/SaveKey.o \ - src/emucore/Serializer.o \ - src/emucore/Settings.o \ - src/emucore/Switches.o \ - src/emucore/System.o \ - src/emucore/TIASurface.o \ - src/emucore/Thumbulator.o + src/emucore/AtariVox.o \ + src/emucore/Bankswitch.o \ + src/emucore/Booster.o \ + src/emucore/Cart.o \ + src/emucore/CartCreator.o \ + src/emucore/CartDetector.o \ + src/emucore/CartEnhanced.o \ + src/emucore/Cart0840.o \ + src/emucore/Cart2K.o \ + src/emucore/Cart3E.o \ + src/emucore/Cart3EPlus.o \ + src/emucore/Cart3EX.o \ + src/emucore/Cart3F.o \ + src/emucore/Cart4A50.o \ + src/emucore/Cart4K.o \ + src/emucore/Cart4KSC.o \ + src/emucore/CartAR.o \ + src/emucore/CartBUS.o \ + src/emucore/CartCDF.o \ + src/emucore/CartCM.o \ + src/emucore/CartCTY.o \ + src/emucore/CartCV.o \ + src/emucore/CartDPC.o \ + src/emucore/CartDPCPlus.o \ + src/emucore/CartE0.o \ + src/emucore/CartMNetwork.o \ + src/emucore/CartE7.o \ + src/emucore/CartE78K.o \ + src/emucore/CartEF.o \ + src/emucore/CartEFSC.o \ + src/emucore/CartBF.o \ + src/emucore/CartBFSC.o \ + src/emucore/CartDF.o \ + src/emucore/CartDFSC.o \ + src/emucore/CartF0.o \ + src/emucore/CartF4.o \ + src/emucore/CartF4SC.o \ + src/emucore/CartF6.o \ + src/emucore/CartF6SC.o \ + src/emucore/CartF8.o \ + src/emucore/CartF8SC.o \ + src/emucore/CartFA.o \ + src/emucore/CartFA2.o \ + src/emucore/CartFC.o \ + src/emucore/CartFE.o \ + src/emucore/CartMDM.o \ + src/emucore/CartSB.o \ + src/emucore/CartTVBoy.o \ + src/emucore/CartUA.o \ + src/emucore/CartWD.o \ + src/emucore/CartX07.o \ + src/emucore/CompuMate.o \ + src/emucore/Console.o \ + src/emucore/Control.o \ + src/emucore/ControllerDetector.o \ + src/emucore/DispatchResult.o \ + src/emucore/Driving.o \ + src/emucore/EventHandler.o \ + src/emucore/EmulationTiming.o \ + src/emucore/EmulationWorker.o \ + src/emucore/FrameBuffer.o \ + src/emucore/FBSurface.o \ + src/emucore/FSNode.o \ + src/emucore/Genesis.o \ + src/emucore/Joystick.o \ + src/emucore/Keyboard.o \ + src/emucore/KidVid.o \ + src/emucore/Lightgun.o \ + src/emucore/MindLink.o \ + src/emucore/M6502.o \ + src/emucore/M6532.o \ + src/emucore/MT24LC256.o \ + src/emucore/MD5.o \ + src/emucore/OSystem.o \ + src/emucore/Paddles.o \ + src/emucore/PointingDevice.o \ + src/emucore/ProfilingRunner.o \ + src/emucore/Props.o \ + src/emucore/PropsSet.o \ + src/emucore/QuadTari.o \ + src/emucore/SaveKey.o \ + src/emucore/Serializer.o \ + src/emucore/Settings.o \ + src/emucore/Switches.o \ + src/emucore/System.o \ + src/emucore/TIASurface.o \ + src/emucore/Thumbulator.o MODULE_DIRS += \ - src/emucore + src/emucore # Include common rules include $(srcdir)/common.rules From fd2d6edf4c54bebc741359a1060b37164cf559b7 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 1 Sep 2020 14:34:53 +0200 Subject: [PATCH 021/263] added QuadTari support for joysticks added autodetection for QuadTari --- Changes.txt | 2 ++ src/emucore/Control.cxx | 2 +- src/emucore/ControllerDetector.cxx | 22 ++++++++++++++++++++++ src/emucore/QuadTari.cxx | 28 +++++++++++++++++++++------- src/emucore/QuadTari.hxx | 3 +-- 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Changes.txt b/Changes.txt index 31e2254ef..eb495b099 100644 --- a/Changes.txt +++ b/Changes.txt @@ -37,6 +37,8 @@ are no longer corrupted/cut off. This includes properly supporting the 2600-daptor II, which is flashable to an AVox-USB converter. + * Added QuadTari controller support for josticks (TODO: doc, settings etc.) + * Added option to select the audio device. * Added option to display detected settings info when a ROM is loaded. diff --git a/src/emucore/Control.cxx b/src/emucore/Control.cxx index 0dfdc79d3..fb57b6278 100644 --- a/src/emucore/Control.cxx +++ b/src/emucore/Control.cxx @@ -110,7 +110,7 @@ string Controller::getName(const Type type) "AmigaMouse", "AtariMouse", "AtariVox", "BoosterGrip", "CompuMate", "Driving", "Sega Genesis", "Joystick", "Keyboard", "KidVid", "MindLink", "Paddles", "Paddles_IAxis", "Paddles_IAxDr", "SaveKey", "TrakBall", - "Lightgun" + "Lightgun", "QuadTari" }; return NAMES[int(type)]; diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 622f59ca1..2e21d8586 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -62,6 +62,10 @@ Controller::Type ControllerDetector::autodetectPort( if(isProbablySaveKey(image, size, port)) type = Controller::Type::SaveKey; + else if(isProbablyQuadTari(image, size, port)) + { + type = Controller::Type::QuadTari; + } else if(usesJoystickButton(image, size, port)) { if(isProbablyTrakBall(image, size)) @@ -693,3 +697,21 @@ bool ControllerDetector::isProbablyLightGun(const ByteBuffer& image, size_t size return false; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size, + Controller::Jack port) +{ + if(port == Controller::Jack::Left) + { + uInt8 signature[] = { 'Q', 'U', 'A', 'D', 'L' }; + + return searchForBytes(image, size, signature, 5); + } + else if(port == Controller::Jack::Right) + { + uInt8 signature[] = { 'Q', 'U', 'A', 'D', 'R' }; + + return searchForBytes(image, size, signature, 5); + } +} diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index 55adf8c53..c75c28f76 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -16,6 +16,9 @@ //============================================================================ #include "Event.hxx" +#include "System.hxx" +#include "TIA.hxx" +#include "FrameBuffer.hxx" #include "Joystick.hxx" #include "QuadTari.hxx" @@ -23,7 +26,7 @@ QuadTari::QuadTari(Jack jack, const Event& event, const System& system) : Controller(jack, event, system, Controller::Type::QuadTari) { - // TODO: allow multiple controller types + // TODO: support multiple controller types if(myJack == Jack::Left) { myFirstController = make_unique(Jack::Left, event, system); @@ -34,6 +37,9 @@ QuadTari::QuadTari(Jack jack, const Event& event, const System& system) myFirstController = make_unique(Jack::Right, event, system); mySecondController = make_unique(Jack::Left, event, system); // TODO: use P3 mapping } + // QuadTari auto detection setting + setPin(AnalogPin::Five, MIN_RESISTANCE); + setPin(AnalogPin::Nine, MAX_RESISTANCE); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -43,8 +49,11 @@ bool QuadTari::read(DigitalPin pin) // can switch the controller multiple times per frame // (we can't just read 60 times per second in the ::update() method) - if(true) // TODO handle controller switch + // If bit 7 of VBlank is not set, read first, else second controller + if(!(mySystem.tia().registerValue(VBLANK) & 0x80)) return myFirstController->read(pin); + else + return mySecondController->read(pin); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -54,20 +63,25 @@ void QuadTari::update() mySecondController->update(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string QuadTari::name() const +{ + return "QuadTari (" + myFirstController->name() + "/" + mySecondController->name() + ")"; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool QuadTari::isAnalog() const { - // TODO: does this work? - return myFirstController->isAnalog() || mySecondController->isAnalog(); + // For now, use mouse for first controller only + return myFirstController->isAnalog(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool QuadTari::setMouseControl( Controller::Type xtype, int xid, Controller::Type ytype, int yid) { - // TODO: does this work? - myFirstController->setMouseControl(xtype, xid, ytype, yid); - mySecondController->setMouseControl(xtype, xid, ytype, yid); + // Use mouse for first controller only (TODO: support multiple controller types) + myFirstController->setMouseControl(Controller::Type::Joystick, xid, Controller::Type::Joystick, yid); return true; } diff --git a/src/emucore/QuadTari.hxx b/src/emucore/QuadTari.hxx index 2499c5c2a..215ee0796 100644 --- a/src/emucore/QuadTari.hxx +++ b/src/emucore/QuadTari.hxx @@ -57,9 +57,8 @@ class QuadTari: public Controller /** Returns the name of this controller. - // TODO: Or the names of the attached controllers? */ - string name() const override { return "QuadTari"; } + string name() const override; /** Answers whether the controller is intrinsically an analog controller. From b256e69f995ea16040919cb064bd0940106e5a7b Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 2 Sep 2020 10:08:58 +0200 Subject: [PATCH 022/263] added QuadTari debugging widget (joysticks only) added mapping for 2nd QuadTari joysticks --- docs/index.html | 5 +- src/debugger/gui/JoystickWidget.cxx | 24 ++-- src/debugger/gui/JoystickWidget.hxx | 2 +- src/debugger/gui/RiotWidget.cxx | 4 + src/debugger/gui/module.mk | 163 ++++++++++++++-------------- src/emucore/Console.cxx | 1 + src/emucore/ControllerDetector.cxx | 4 +- src/emucore/ControllerDetector.hxx | 3 + src/emucore/Joystick.cxx | 44 ++++++-- src/emucore/Joystick.hxx | 9 +- src/emucore/QuadTari.cxx | 37 +++++-- src/emucore/QuadTari.hxx | 22 ++-- src/windows/Stella.vcxproj | 2 + src/windows/Stella.vcxproj.filters | 6 + 14 files changed, 195 insertions(+), 131 deletions(-) diff --git a/docs/index.html b/docs/index.html index 65e416468..53f587dce 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4221,9 +4221,10 @@ Ms Pac-Man (Stella extended codes): SaveKeyA 32K EEPROM for saving high scores, etc. (the EEPROM portion of an AtariVox). Genesis Sega Genesis controller, which can be used similar to a BoosterGrip, giving an extra button. CompuMate ¹Spectravideo CompuMate (if either left or right is set, CompuMate is used for both). - LightgunAtari XG-1 compatible Light Gun + LightgunAtari XG-1 compatible Light Gun Mindlink ¹Mindlink controller. - KidVid ¹KidVid controller, limitted suport (8, 9 and 0 start the games). + KidVid ¹KidVid controller, limited support (8, 9 and 0 start the games). + QuadTariQuadTari controller, limited support (joysticks only). diff --git a/src/debugger/gui/JoystickWidget.cxx b/src/debugger/gui/JoystickWidget.cxx index dc3b2c85d..6e9ad18dc 100644 --- a/src/debugger/gui/JoystickWidget.cxx +++ b/src/debugger/gui/JoystickWidget.cxx @@ -19,17 +19,23 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, Controller& controller) + int x, int y, Controller& controller, + bool embedded) : ControllerWidget(boss, font, x, y, controller) { - const string& label = getHeader(); - const int fontHeight = font.getFontHeight(); - int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Joystick)"); - StaticTextWidget* t; + int xpos = x, ypos = y; - t = new StaticTextWidget(boss, font, xpos, ypos+2, lwidth, - fontHeight, label, TextAlign::Left); - xpos += t->getWidth()/2 - 5; ypos += t->getHeight() + 20; + if(!embedded) + { + const string& label = getHeader(); + const int fontHeight = font.getFontHeight(); + int lwidth = font.getStringWidth("Right (Joystick)"); + StaticTextWidget* t; + + t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth, + fontHeight, label, TextAlign::Left); + xpos += t->getWidth() / 2 - 5; ypos += t->getHeight() + 20; + } myPins[kJUp] = new CheckboxWidget(boss, font, xpos, ypos, "", CheckboxWidget::kCheckActionCmd); myPins[kJUp]->setID(kJUp); @@ -55,7 +61,7 @@ JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font, myPins[kJRight]->setTarget(this); xpos -= (myPins[kJUp]->getWidth() + 5) * 2; - ypos = 30 + (myPins[kJUp]->getHeight() + 10) * 3; + ypos = myPins[kJDown]->getBottom() + font.getFontHeight() * 0.5 - 1; myPins[kJFire] = new CheckboxWidget(boss, font, xpos, ypos, "Fire", CheckboxWidget::kCheckActionCmd); myPins[kJFire]->setID(kJFire); diff --git a/src/debugger/gui/JoystickWidget.hxx b/src/debugger/gui/JoystickWidget.hxx index 1c1143b7f..1804dd2a6 100644 --- a/src/debugger/gui/JoystickWidget.hxx +++ b/src/debugger/gui/JoystickWidget.hxx @@ -25,7 +25,7 @@ class JoystickWidget : public ControllerWidget { public: JoystickWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - Controller& controller); + Controller& controller, bool embedded = false); ~JoystickWidget() override = default; private: diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index 43514e072..e1b5bf415 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -39,6 +39,7 @@ #include "AmigaMouseWidget.hxx" #include "AtariMouseWidget.hxx" #include "TrakBallWidget.hxx" +#include "QuadTariWidget.hxx" #include "RiotWidget.hxx" @@ -480,12 +481,15 @@ ControllerWidget* RiotWidget::addControlWidget(GuiObject* boss, const GUI::Font& return new KeyboardWidget(boss, font, x, y, controller); // case Controller::Type::KidVid: // TODO - implement this // case Controller::Type::MindLink: // TODO - implement this +// case Controller::Type::Lightgun: // TODO - implement this case Controller::Type::Paddles: return new PaddleWidget(boss, font, x, y, controller); case Controller::Type::SaveKey: return new SaveKeyWidget(boss, font, x, y, controller); case Controller::Type::TrakBall: return new TrakBallWidget(boss, font, x, y, controller); + case Controller::Type::QuadTari: + return new QuadTariWidget(boss, font, x, y, controller); default: return new NullControlWidget(boss, font, x, y, controller); } diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index d992ae85a..cda7666e9 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -1,89 +1,90 @@ MODULE := src/debugger/gui MODULE_OBJS := \ - src/debugger/gui/AmigaMouseWidget.o \ - src/debugger/gui/AtariMouseWidget.o \ - src/debugger/gui/AtariVoxWidget.o \ - src/debugger/gui/AudioWidget.o \ - src/debugger/gui/BoosterWidget.o \ - src/debugger/gui/Cart0840Widget.o \ - src/debugger/gui/Cart2KWidget.o \ - src/debugger/gui/Cart3EPlusWidget.o \ - src/debugger/gui/Cart3EWidget.o \ - src/debugger/gui/Cart3FWidget.o \ - src/debugger/gui/Cart4A50Widget.o \ - src/debugger/gui/Cart4KSCWidget.o \ - src/debugger/gui/Cart4KWidget.o \ - src/debugger/gui/CartARWidget.o \ - src/debugger/gui/CartBFSCWidget.o \ - src/debugger/gui/CartBFWidget.o \ - src/debugger/gui/CartBUSWidget.o \ - src/debugger/gui/CartCDFWidget.o \ - src/debugger/gui/CartCDFInfoWidget.o \ - src/debugger/gui/CartCMWidget.o \ - src/debugger/gui/CartCTYWidget.o \ - src/debugger/gui/CartCVWidget.o \ - src/debugger/gui/CartDFSCWidget.o \ - src/debugger/gui/CartDFWidget.o \ - src/debugger/gui/CartDPCPlusWidget.o \ - src/debugger/gui/CartDPCWidget.o \ - src/debugger/gui/CartE0Widget.o \ - src/debugger/gui/CartEnhancedWidget.o \ - src/debugger/gui/CartMNetworkWidget.o \ - src/debugger/gui/CartE7Widget.o \ - src/debugger/gui/CartE78KWidget.o \ - src/debugger/gui/CartEFSCWidget.o \ - src/debugger/gui/CartEFWidget.o \ - src/debugger/gui/CartF0Widget.o \ - src/debugger/gui/CartF4SCWidget.o \ - src/debugger/gui/CartF4Widget.o \ - src/debugger/gui/CartF6SCWidget.o \ - src/debugger/gui/CartF6Widget.o \ - src/debugger/gui/CartF8SCWidget.o \ - src/debugger/gui/CartF8Widget.o \ - src/debugger/gui/CartFA2Widget.o \ - src/debugger/gui/CartFAWidget.o \ - src/debugger/gui/CartFCWidget.o \ - src/debugger/gui/CartFEWidget.o \ - src/debugger/gui/CartMDMWidget.o \ - src/debugger/gui/CartRamWidget.o \ - src/debugger/gui/CartSBWidget.o \ - src/debugger/gui/CartTVBoyWidget.o \ - src/debugger/gui/CartUAWidget.o \ - src/debugger/gui/CartWDWidget.o \ - src/debugger/gui/CartX07Widget.o \ - src/debugger/gui/CartDebugWidget.o \ - src/debugger/gui/CpuWidget.o \ - src/debugger/gui/DataGridOpsWidget.o \ - src/debugger/gui/DataGridWidget.o \ - src/debugger/gui/DebuggerDialog.o \ - src/debugger/gui/DelayQueueWidget.o \ - src/debugger/gui/DrivingWidget.o \ - src/debugger/gui/FlashWidget.o \ - src/debugger/gui/GenesisWidget.o \ - src/debugger/gui/JoystickWidget.o \ - src/debugger/gui/KeyboardWidget.o \ - src/debugger/gui/PaddleWidget.o \ - src/debugger/gui/PointingDeviceWidget.o \ - src/debugger/gui/PromptWidget.o \ - src/debugger/gui/RamWidget.o \ - src/debugger/gui/RiotRamWidget.o \ - src/debugger/gui/RiotWidget.o \ - src/debugger/gui/RomListSettings.o \ - src/debugger/gui/RomListWidget.o \ - src/debugger/gui/RomWidget.o \ - src/debugger/gui/SaveKeyWidget.o \ - src/debugger/gui/TiaInfoWidget.o \ - src/debugger/gui/TiaOutputWidget.o \ - src/debugger/gui/TiaWidget.o \ - src/debugger/gui/TiaZoomWidget.o \ - src/debugger/gui/ToggleBitWidget.o \ - src/debugger/gui/TogglePixelWidget.o \ - src/debugger/gui/ToggleWidget.o \ - src/debugger/gui/TrakBallWidget.o + src/debugger/gui/AmigaMouseWidget.o \ + src/debugger/gui/AtariMouseWidget.o \ + src/debugger/gui/AtariVoxWidget.o \ + src/debugger/gui/AudioWidget.o \ + src/debugger/gui/BoosterWidget.o \ + src/debugger/gui/Cart0840Widget.o \ + src/debugger/gui/Cart2KWidget.o \ + src/debugger/gui/Cart3EPlusWidget.o \ + src/debugger/gui/Cart3EWidget.o \ + src/debugger/gui/Cart3FWidget.o \ + src/debugger/gui/Cart4A50Widget.o \ + src/debugger/gui/Cart4KSCWidget.o \ + src/debugger/gui/Cart4KWidget.o \ + src/debugger/gui/CartARWidget.o \ + src/debugger/gui/CartBFSCWidget.o \ + src/debugger/gui/CartBFWidget.o \ + src/debugger/gui/CartBUSWidget.o \ + src/debugger/gui/CartCDFWidget.o \ + src/debugger/gui/CartCDFInfoWidget.o \ + src/debugger/gui/CartCMWidget.o \ + src/debugger/gui/CartCTYWidget.o \ + src/debugger/gui/CartCVWidget.o \ + src/debugger/gui/CartDFSCWidget.o \ + src/debugger/gui/CartDFWidget.o \ + src/debugger/gui/CartDPCPlusWidget.o \ + src/debugger/gui/CartDPCWidget.o \ + src/debugger/gui/CartE0Widget.o \ + src/debugger/gui/CartEnhancedWidget.o \ + src/debugger/gui/CartMNetworkWidget.o \ + src/debugger/gui/CartE7Widget.o \ + src/debugger/gui/CartE78KWidget.o \ + src/debugger/gui/CartEFSCWidget.o \ + src/debugger/gui/CartEFWidget.o \ + src/debugger/gui/CartF0Widget.o \ + src/debugger/gui/CartF4SCWidget.o \ + src/debugger/gui/CartF4Widget.o \ + src/debugger/gui/CartF6SCWidget.o \ + src/debugger/gui/CartF6Widget.o \ + src/debugger/gui/CartF8SCWidget.o \ + src/debugger/gui/CartF8Widget.o \ + src/debugger/gui/CartFA2Widget.o \ + src/debugger/gui/CartFAWidget.o \ + src/debugger/gui/CartFCWidget.o \ + src/debugger/gui/CartFEWidget.o \ + src/debugger/gui/CartMDMWidget.o \ + src/debugger/gui/CartRamWidget.o \ + src/debugger/gui/CartSBWidget.o \ + src/debugger/gui/CartTVBoyWidget.o \ + src/debugger/gui/CartUAWidget.o \ + src/debugger/gui/CartWDWidget.o \ + src/debugger/gui/CartX07Widget.o \ + src/debugger/gui/CartDebugWidget.o \ + src/debugger/gui/CpuWidget.o \ + src/debugger/gui/DataGridOpsWidget.o \ + src/debugger/gui/DataGridWidget.o \ + src/debugger/gui/DebuggerDialog.o \ + src/debugger/gui/DelayQueueWidget.o \ + src/debugger/gui/DrivingWidget.o \ + src/debugger/gui/FlashWidget.o \ + src/debugger/gui/GenesisWidget.o \ + src/debugger/gui/JoystickWidget.o \ + src/debugger/gui/KeyboardWidget.o \ + src/debugger/gui/PaddleWidget.o \ + src/debugger/gui/PointingDeviceWidget.o \ + src/debugger/gui/PromptWidget.o \ + src/debugger/gui/QuadTariWidget.o \ + src/debugger/gui/RamWidget.o \ + src/debugger/gui/RiotRamWidget.o \ + src/debugger/gui/RiotWidget.o \ + src/debugger/gui/RomListSettings.o \ + src/debugger/gui/RomListWidget.o \ + src/debugger/gui/RomWidget.o \ + src/debugger/gui/SaveKeyWidget.o \ + src/debugger/gui/TiaInfoWidget.o \ + src/debugger/gui/TiaOutputWidget.o \ + src/debugger/gui/TiaWidget.o \ + src/debugger/gui/TiaZoomWidget.o \ + src/debugger/gui/ToggleBitWidget.o \ + src/debugger/gui/TogglePixelWidget.o \ + src/debugger/gui/ToggleWidget.o \ + src/debugger/gui/TrakBallWidget.o MODULE_DIRS += \ - src/debugger/gui + src/debugger/gui # Include common rules include $(srcdir)/common.rules diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 98bb7e98c..39ec0f0a8 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -929,6 +929,7 @@ unique_ptr Console::getControllerPort(const Controller::Type type, break; case Controller::Type::QuadTari: + // TODO: support multiple controller types controller = make_unique(port, myEvent, *mySystem); break; diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 2e21d8586..3552e0296 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -63,9 +63,7 @@ Controller::Type ControllerDetector::autodetectPort( if(isProbablySaveKey(image, size, port)) type = Controller::Type::SaveKey; else if(isProbablyQuadTari(image, size, port)) - { type = Controller::Type::QuadTari; - } else if(usesJoystickButton(image, size, port)) { if(isProbablyTrakBall(image, size)) @@ -694,7 +692,6 @@ bool ControllerDetector::isProbablyLightGun(const ByteBuffer& image, size_t size if (searchForBytes(image, size, signature[i], SIG_SIZE)) return true; } - return false; } @@ -714,4 +711,5 @@ bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size return searchForBytes(image, size, signature, 5); } + return false; } diff --git a/src/emucore/ControllerDetector.hxx b/src/emucore/ControllerDetector.hxx index be24ae09d..1e21b447f 100644 --- a/src/emucore/ControllerDetector.hxx +++ b/src/emucore/ControllerDetector.hxx @@ -121,6 +121,9 @@ class ControllerDetector static bool isProbablyLightGun(const ByteBuffer& image, size_t size, Controller::Jack port); + // Returns true if a QuadTari code pattern is found. + static bool isProbablyQuadTari(const ByteBuffer& image, size_t size, + Controller::Jack port); private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Joystick.cxx b/src/emucore/Joystick.cxx index ea0d71300..7f62335f9 100644 --- a/src/emucore/Joystick.cxx +++ b/src/emucore/Joystick.cxx @@ -19,26 +19,48 @@ #include "Joystick.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Joystick::Joystick(Jack jack, const Event& event, const System& system) +Joystick::Joystick(Jack jack, const Event& event, const System& system, bool altmap) : Controller(jack, event, system, Controller::Type::Joystick) { if(myJack == Jack::Left) { - myUpEvent = Event::JoystickZeroUp; - myDownEvent = Event::JoystickZeroDown; - myLeftEvent = Event::JoystickZeroLeft; - myRightEvent = Event::JoystickZeroRight; - myFireEvent = Event::JoystickZeroFire; + if(!altmap) + { + myUpEvent = Event::JoystickZeroUp; + myDownEvent = Event::JoystickZeroDown; + myLeftEvent = Event::JoystickZeroLeft; + myRightEvent = Event::JoystickZeroRight; + myFireEvent = Event::JoystickZeroFire; + } + else + { + myUpEvent = Event::JoystickTwoUp; + myDownEvent = Event::JoystickTwoDown; + myLeftEvent = Event::JoystickTwoLeft; + myRightEvent = Event::JoystickTwoRight; + myFireEvent = Event::JoystickTwoFire; + } myXAxisValue = Event::PaddleZeroAnalog; myYAxisValue = Event::PaddleOneAnalog; } else { - myUpEvent = Event::JoystickOneUp; - myDownEvent = Event::JoystickOneDown; - myLeftEvent = Event::JoystickOneLeft; - myRightEvent = Event::JoystickOneRight; - myFireEvent = Event::JoystickOneFire; + if(!altmap) + { + myUpEvent = Event::JoystickOneUp; + myDownEvent = Event::JoystickOneDown; + myLeftEvent = Event::JoystickOneLeft; + myRightEvent = Event::JoystickOneRight; + myFireEvent = Event::JoystickOneFire; + } + else + { + myUpEvent = Event::JoystickThreeUp; + myDownEvent = Event::JoystickThreeDown; + myLeftEvent = Event::JoystickThreeLeft; + myRightEvent = Event::JoystickThreeRight; + myFireEvent = Event::JoystickThreeFire; + } myXAxisValue = Event::PaddleTwoAnalog; myYAxisValue = Event::PaddleThreeAnalog; } diff --git a/src/emucore/Joystick.hxx b/src/emucore/Joystick.hxx index 99675c51e..ec652e98b 100644 --- a/src/emucore/Joystick.hxx +++ b/src/emucore/Joystick.hxx @@ -33,11 +33,12 @@ class Joystick : public Controller /** Create a new joystick controller plugged into the specified jack - @param jack The jack the controller is plugged into - @param event The event object to use for events - @param system The system using this controller + @param jack The jack the controller is plugged into + @param event The event object to use for events + @param system The system using this controller + @param altmap If true, use alternative mapping */ - Joystick(Jack jack, const Event& event, const System& system); + Joystick(Jack jack, const Event& event, const System& system, bool altmap = false); ~Joystick() override = default; public: diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index c75c28f76..ca7d3b81f 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -23,20 +23,32 @@ #include "QuadTari.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -QuadTari::QuadTari(Jack jack, const Event& event, const System& system) +QuadTari::QuadTari(Jack jack, const Event& event, const System& system, + const Controller::Type firstType, const Controller::Type secondType) : Controller(jack, event, system, Controller::Type::QuadTari) { // TODO: support multiple controller types - if(myJack == Jack::Left) + switch(firstType) { - myFirstController = make_unique(Jack::Left, event, system); - mySecondController = make_unique(Jack::Right, event, system); // TODO: use P2 mapping + case Controller::Type::Joystick: + myFirstController = make_unique(myJack, event, system); + break; + + default: + // TODO + break; } - else + switch(secondType) { - myFirstController = make_unique(Jack::Right, event, system); - mySecondController = make_unique(Jack::Left, event, system); // TODO: use P3 mapping + case Controller::Type::Joystick: + mySecondController = make_unique(myJack, event, system, true); // use alternative mapping + break; + + default: + // TODO + break; } + // QuadTari auto detection setting setPin(AnalogPin::Five, MIN_RESISTANCE); setPin(AnalogPin::Nine, MAX_RESISTANCE); @@ -80,8 +92,11 @@ bool QuadTari::isAnalog() const bool QuadTari::setMouseControl( Controller::Type xtype, int xid, Controller::Type ytype, int yid) { - // Use mouse for first controller only (TODO: support multiple controller types) - myFirstController->setMouseControl(Controller::Type::Joystick, xid, Controller::Type::Joystick, yid); - - return true; + // Use mouse for first controller only + if(xtype == Controller::Type::QuadTari && ytype == Controller::Type::QuadTari) + return myFirstController->setMouseControl(myFirstController->type(), xid, + myFirstController->type(), yid); + else + // required for creating the MouseControl mode list + return myFirstController->setMouseControl(xtype, xid, ytype, yid); } diff --git a/src/emucore/QuadTari.hxx b/src/emucore/QuadTari.hxx index 215ee0796..3d5d0bfb6 100644 --- a/src/emucore/QuadTari.hxx +++ b/src/emucore/QuadTari.hxx @@ -18,8 +18,8 @@ #ifndef QUADTARI_HXX #define QUADTARI_HXX -#include "Control.hxx" -#include "Event.hxx" +class Controller; +class Event; /** The QuadTari controller. @@ -28,16 +28,20 @@ */ class QuadTari: public Controller { + friend class QuadTariWidget; public: /** - Create a QuadTari controller plugged into - the specified jack + Create a QuadTari controller plugged into the specified jack - @param jack The jack the controller is plugged into - @param event The event object to use for events - @param system The system using this controller + @param jack The jack the controller is plugged into + @param event The event object to use for events + @param system The system using this controller + @param firstType The type of the first, plugged-in controller + @param secondType The type of the second, plugged-in controller */ - QuadTari(Jack jack, const Event& event, const System& system); + QuadTari(Jack jack, const Event& event, const System& system, + const Controller::Type firstType = Controller::Type::Joystick, + const Controller::Type secondType = Controller::Type::Joystick); ~QuadTari() override = default; public: @@ -62,7 +66,7 @@ class QuadTari: public Controller /** Answers whether the controller is intrinsically an analog controller. - TODO: Depends on the attached controllers. + Depends on the attached controllers. */ bool isAnalog() const override; diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 71c5d6f30..261ac76b9 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -702,6 +702,7 @@ true + true @@ -1721,6 +1722,7 @@ true + true diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index be6cc8424..6be678998 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1020,6 +1020,9 @@ Source Files\emucore + + Source Files\debugger + @@ -2096,6 +2099,9 @@ Header Files\emucore + + Header Files\debugger + From d9d519a0653d48058152a41e9c73b2be19d72ea5 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 2 Sep 2020 11:17:46 +0200 Subject: [PATCH 023/263] added missing files (again :( ) --- src/debugger/gui/QuadTariWidget.cxx | 73 +++++++++++++++++++++++++++++ src/debugger/gui/QuadTariWidget.hxx | 52 ++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 src/debugger/gui/QuadTariWidget.cxx create mode 100644 src/debugger/gui/QuadTariWidget.hxx diff --git a/src/debugger/gui/QuadTariWidget.cxx b/src/debugger/gui/QuadTariWidget.cxx new file mode 100644 index 000000000..aca263a86 --- /dev/null +++ b/src/debugger/gui/QuadTariWidget.cxx @@ -0,0 +1,73 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "OSystem.hxx" +#include "Console.hxx" +#include "TIA.hxx" +#include "QuadTari.hxx" +#include "JoystickWidget.hxx" +#include "NullControlWidget.hxx" +#include "QuadTariWidget.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +QuadTariWidget::QuadTariWidget(GuiObject* boss, const GUI::Font& font, + int x, int y, Controller& controller) + : ControllerWidget(boss, font, x, y, controller) +{ + string label = (isLeftPort() ? "Left" : "Right") + string(" (QuadTari)"); + StaticTextWidget* t = new StaticTextWidget(boss, font, x, y + 2, label); + QuadTari& qt = dynamic_cast(controller); + + x += font.getMaxCharWidth() * 2; + y = t->getBottom() + font.getFontHeight() * 1.25; + + // TODO: support multiple controller types + switch(qt.myFirstController->type()) + { + case Controller::Type::Joystick: + myFirstControl = new JoystickWidget(boss, font, x, y, *qt.myFirstController, true); + x = myFirstControl->getRight() - font.getMaxCharWidth() * 8; + break; + + default: + myFirstControl = new NullControlWidget(boss, font, x, y, *qt.myFirstController); + x += font.getMaxCharWidth() * 8; + break; + } + + switch(qt.mySecondController->type()) + { + case Controller::Type::Joystick: + mySecondControl = new JoystickWidget(boss, font, x, y, *qt.mySecondController, true); + break; + + default: + mySecondControl = new NullControlWidget(boss, font, x, y, *qt.mySecondController); + break; + } + + myPointer = new StaticTextWidget(boss, font, + x - font.getMaxCharWidth() * 5, y, " "); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariWidget::loadConfig() +{ + bool first = !(instance().console().tia().registerValue(VBLANK) & 0x80); + + myPointer->setLabel(first ? "<-" : "->"); +} diff --git a/src/debugger/gui/QuadTariWidget.hxx b/src/debugger/gui/QuadTariWidget.hxx new file mode 100644 index 000000000..cccdf1575 --- /dev/null +++ b/src/debugger/gui/QuadTariWidget.hxx @@ -0,0 +1,52 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef QUADTARI_WIDGET_HXX +#define QUADTARI_WIDGET_HXX + +#include "Control.hxx" +#include "ControllerWidget.hxx" + +class QuadTariWidget: public ControllerWidget +{ + public: + QuadTariWidget(GuiObject* boss, const GUI::Font& font, int x, int y, + Controller& controller); + ~QuadTariWidget() override = default; + + protected: + virtual string getHeader() + { + return (isLeftPort() ? "Left (" : "Right (") + string("QuadTari)"); + } + + private: + ControllerWidget* myFirstControl{nullptr}; + ControllerWidget* mySecondControl{nullptr}; + StaticTextWidget* myPointer{nullptr}; + + void loadConfig() override; + + // Following constructors and assignment operators not supported + QuadTariWidget() = delete; + QuadTariWidget(const QuadTariWidget&) = delete; + QuadTariWidget(QuadTariWidget&&) = delete; + QuadTariWidget& operator=(const QuadTariWidget&) = delete; + QuadTariWidget& operator=(QuadTariWidget&&) = delete; +}; + +#endif From 0c0289226578d7ec342d3b9bfa2c7ed4cbec4ff3 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 2 Sep 2020 12:51:31 +0200 Subject: [PATCH 024/263] added QuadTari controller switch timer --- src/emucore/QuadTari.cxx | 13 +++++++++++-- src/emucore/tia/TIA.cxx | 19 +++++++++++++++++++ src/emucore/tia/TIA.hxx | 24 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index ca7d3b81f..e249c7f14 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -61,8 +61,17 @@ bool QuadTari::read(DigitalPin pin) // can switch the controller multiple times per frame // (we can't just read 60 times per second in the ::update() method) - // If bit 7 of VBlank is not set, read first, else second controller - if(!(mySystem.tia().registerValue(VBLANK) & 0x80)) + constexpr int MIN_CYCLES = 30 * 76; // minimal cycles required for stable input switch (TODO: define cycles) + bool readFirst; + + if(mySystem.tia().dumpPortsCycles() < MIN_CYCLES) + // Random controller if read too soon after dump ports changed + readFirst = mySystem.randGenerator().next() % 2; + else + // If bit 7 of VBlank is not set, read first, else second controller + readFirst = !(mySystem.tia().registerValue(VBLANK) & 0x80); + + if(readFirst) return myFirstController->read(pin); else return mySecondController->read(pin); diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 7e4cdbf04..78a44fc55 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -523,6 +523,7 @@ bool TIA::poke(uInt16 address, uInt8 value) for (PaddleReader& paddleReader : myPaddleReaders) paddleReader.vblank(value, myTimestamp); + updateDumpPorts(value); myDelayQueue.push(VBLANK, value, Delay::vblank); @@ -1981,6 +1982,24 @@ void TIA::toggleCollBLPF() myCollisionMask ^= (CollisionMask::ball & CollisionMask::playfield); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::updateDumpPorts(uInt8 value) +{ + bool newIsDumped = value & 0x80; + + if(myArePortsDumped != newIsDumped) + { + myArePortsDumped = newIsDumped; + myDumpPortsTimestamp = myTimestamp; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int64 TIA::dumpPortsCycles() +{ + return (myTimestamp - myDumpPortsTimestamp) / 3; +} + #ifdef DEBUGGER_SUPPORT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIA::createAccessArrays() diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index ada06a042..18609f087 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -334,6 +334,13 @@ class TIA : public Device return uInt32(mySystem->cycles() - myCyclesAtFrameStart); } + /** + * Get the CPU cycles since the last dump ports change. + * + * @return The number of CPU cycles since the last dump ports change + */ + Int64 dumpPortsCycles(); + /** Answers whether the TIA is currently in being rendered (we're in between the start and end of drawing a frame). @@ -695,6 +702,13 @@ class TIA : public Device */ void applyDeveloperSettings(); + /** + * Updates the dump ports state with the time of change. + * + * @param value The value to be stored at VBLANK + */ + void updateDumpPorts(uInt8 value); + #ifdef DEBUGGER_SUPPORT void createAccessArrays(); @@ -894,6 +908,16 @@ class TIA : public Device */ uInt64 myTimestamp{0}; + /** + * The number of CPU clocks since the last dump ports state change. + */ + uInt64 myDumpPortsTimestamp{0}; + + /** + * The current dump ports state. + */ + bool myArePortsDumped{false}; + /** * The "shadow registers" track the last written register value for the * debugger. From 6c301621b3c997b63876e7fa96f7b937be4b63d4 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 2 Sep 2020 13:19:04 +0200 Subject: [PATCH 025/263] fixed build error and warning reduced QuadTari switch timer value --- src/debugger/gui/QuadTariWidget.cxx | 2 +- src/emucore/Control.hxx | 2 +- src/emucore/QuadTari.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debugger/gui/QuadTariWidget.cxx b/src/debugger/gui/QuadTariWidget.cxx index aca263a86..7a76b0524 100644 --- a/src/debugger/gui/QuadTariWidget.cxx +++ b/src/debugger/gui/QuadTariWidget.cxx @@ -30,7 +30,7 @@ QuadTariWidget::QuadTariWidget(GuiObject* boss, const GUI::Font& font, { string label = (isLeftPort() ? "Left" : "Right") + string(" (QuadTari)"); StaticTextWidget* t = new StaticTextWidget(boss, font, x, y + 2, label); - QuadTari& qt = dynamic_cast(controller); + QuadTari& qt = (QuadTari&)controller; x += font.getMaxCharWidth() * 2; y = t->getBottom() + font.getFontHeight() * 1.25; diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx index d1ed02b8b..48eb303f5 100644 --- a/src/emucore/Control.hxx +++ b/src/emucore/Control.hxx @@ -178,7 +178,7 @@ class Controller : public Serializable Update the entire digital and analog pin state according to the events currently set. */ - virtual void update() { }; + virtual void update() { } /** Returns the name of this controller. diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index e249c7f14..598b37fb8 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -61,7 +61,7 @@ bool QuadTari::read(DigitalPin pin) // can switch the controller multiple times per frame // (we can't just read 60 times per second in the ::update() method) - constexpr int MIN_CYCLES = 30 * 76; // minimal cycles required for stable input switch (TODO: define cycles) + constexpr int MIN_CYCLES = 20 * 76; // minimal cycles required for stable input switch (TODO: define cycles) bool readFirst; if(mySystem.tia().dumpPortsCycles() < MIN_CYCLES) From f5cfa1a62129bb2cbfa03259b9ea93db877d143c Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 2 Sep 2020 12:12:38 -0230 Subject: [PATCH 026/263] Fix compile warning in clang, and compile error for libretro build. --- src/debugger/gui/QuadTariWidget.cxx | 2 +- src/libretro/Makefile.common | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debugger/gui/QuadTariWidget.cxx b/src/debugger/gui/QuadTariWidget.cxx index 7a76b0524..2c605da37 100644 --- a/src/debugger/gui/QuadTariWidget.cxx +++ b/src/debugger/gui/QuadTariWidget.cxx @@ -30,7 +30,7 @@ QuadTariWidget::QuadTariWidget(GuiObject* boss, const GUI::Font& font, { string label = (isLeftPort() ? "Left" : "Right") + string(" (QuadTari)"); StaticTextWidget* t = new StaticTextWidget(boss, font, x, y + 2, label); - QuadTari& qt = (QuadTari&)controller; + QuadTari& qt = static_cast(controller); x += font.getMaxCharWidth() * 2; y = t->getBottom() + font.getFontHeight() * 1.25; diff --git a/src/libretro/Makefile.common b/src/libretro/Makefile.common index 994628725..8f2bbf81a 100644 --- a/src/libretro/Makefile.common +++ b/src/libretro/Makefile.common @@ -113,6 +113,7 @@ SOURCES_CXX := \ $(CORE_DIR)/emucore/PointingDevice.cxx \ $(CORE_DIR)/emucore/Props.cxx \ $(CORE_DIR)/emucore/PropsSet.cxx \ + $(CORE_DIR)/emucore/QuadTari.cxx \ $(CORE_DIR)/emucore/SaveKey.cxx \ $(CORE_DIR)/emucore/Serializer.cxx \ $(CORE_DIR)/emucore/Settings.cxx \ From 36aa23824a8f79791f7b8a581fd33819ae24fcef Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 2 Sep 2020 21:54:31 +0200 Subject: [PATCH 027/263] started working on multiple controller support --- docs/index.html | 127 +- src/emucore/Console.cxx | 3 +- src/emucore/ControllerDetector.cxx | 5 +- src/emucore/DefProps.hxx | 7038 ++++++++++++++-------------- src/emucore/Driving.cxx | 32 +- src/emucore/Driving.hxx | 9 +- src/emucore/OSystem.cxx | 20 +- src/emucore/Props.cxx | 20 + src/emucore/Props.hxx | 4 + src/emucore/QuadTari.cxx | 89 +- src/emucore/QuadTari.hxx | 7 +- src/gui/GameInfoDialog.cxx | 30 +- src/gui/GameInfoDialog.hxx | 4 + src/tools/PropSet.pm | 32 +- 14 files changed, 3800 insertions(+), 3620 deletions(-) diff --git a/docs/index.html b/docs/index.html index 7e506120a..699422419 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2119,17 +2119,17 @@
-center <1|0>
- Centers all windows (if possible). + Center all windows (if possible).
-windowedpos <XxY>
- Sets the window position in windowed emulator mode. + Set the window position in windowed emulator mode.
-display <number>
- Sets the display for Stella's emulator. + Set the display for Stella's emulator. @@ -2286,7 +2286,7 @@
-tia.dbgcolors <roygbp>
- Assigns the colours (R)ed, (O)range, (Y)ellow, (G)reen, (B)lue and (P)urple + Assign the colours (R)ed, (O)range, (Y)ellow, (G)reen, (B)lue and (P)urple to each graphical register P0/M0/P1/M1/PF/BL, respectively. Currently, these change be changed around to apply different colours to the respective register. @@ -2332,7 +2332,7 @@
-tv.phosphor <always|byrom>
- Determines how phosphor mode is enabled. If 'always', then the + Determine how phosphor mode is enabled. If 'always', then the ROM properties entry is ignored, and phosphor mode is always turned on. Otherwise, the ROM properties determine whether phosphor mode is used for each ROM. @@ -2354,7 +2354,7 @@
-tv.scanlines <0 - 100>
- TV effects scanline intensity, where 0 means completely off. Note: No scanlines in 1x mode snapshots. + Set TV effects scanline intensity, where 0 means completely off. Note: No scanlines in 1x mode snapshots. @@ -2364,17 +2364,17 @@
-loglevel <0|1|2>
- Indicates level of logging to perform while the application is running. Zero completely disables logging (except for serious errors), while the remaining numbers show increasingly more detail. + Indicate level of logging to perform while the application is running. Zero completely disables logging (except for serious errors), while the remaining numbers show increasingly more detail.
-logtoconsole <1|0>
- Indicates that logged output should be printed to the console/commandline as it's being collected. An internal log will still be kept, and the amount of logging is still controlled by 'loglevel'. + Indicate that logged output should be printed to the console/commandline as it's being collected. An internal log will still be kept, and the amount of logging is still controlled by 'loglevel'.
-joydeadzone <number>
- Sets the joystick axis deadzone area for analog joysticks/gamepads. + Set the joystick axis deadzone area for analog joysticks/gamepads. All values within the deadzone are treated as zero-axis values, while only those values outside are registered as valid input. Accepts a number from 0 - 29, and uses the formula @@ -2429,7 +2429,7 @@
-saport <lr|rl>
- Determines how to enumerate the Stelladaptor/2600-daptor devices in the + Determine how to enumerate the Stelladaptor/2600-daptor devices in the order they are found: 'lr' means first is left port, second is right port, 'rl' means the opposite. @@ -2475,7 +2475,7 @@
-grabmouse <1|0>
- Locks the mouse cursor in the game window in emulation mode. + Lock the mouse cursor in the game window in emulation mode. @@ -2541,7 +2541,7 @@
-listrominfo
- Prints relevant contents of the Stella ROM database, one ROM per line, + Print relevant contents of the Stella ROM database, one ROM per line, and then exit Stella. This can be used for external frontends. @@ -2553,12 +2553,12 @@
-launcherpos <XxY>
- Sets the window position in windowed ROM launcher mode. + Set the window position in windowed ROM launcher mode.
-launcherdisplay <number>
- Sets the display for the ROM launcher. + Set the display for the ROM launcher. @@ -2601,7 +2601,7 @@
-hidpi <0|1>
- Enables the HiDPI mode which scales the UI by a factor of two. + Enable the HiDPI mode which scales the UI by a factor of two. @@ -2688,13 +2688,13 @@
-dis.gfxformat <2|16>
- Sets the base to use for displaying GFX sections in the disassembler. + Set the base to use for displaying GFX sections in the disassembler.
-dis.showaddr <1|0>
- Shows/hides opcode addresses in the disassembler. + Show/hide opcode addresses in the disassembler. @@ -2704,12 +2704,12 @@
-dbg.pos <XxY>
- Sets the window position in windowed debugger mode. + Set the window position in windowed debugger mode.
-dbg.display <number>
- Sets the display for the debugger. + Set the display for the debugger. @@ -2823,15 +2823,46 @@ section for valid types. + +
-lq1 <type>
+ Set "Controller.Left1" property for QuadTari. See the Game Properties + section for valid types. + + + +
-lq2 <type>
+ Set "Controller.Left2" property for QuadTari. See the Game Properties + section for valid types. + +
-rc <type>
Set "Controller.Right" property. See the Game Properties section for valid types. + + +
-rq1 <type>
+ Set "Controller.Right1" property for QuadTari. See the Game Properties + section for valid types. + + + +
-rq2 <type>
+ Set "Controller.Right2" property for QuadTari. See the Game Properties + section for valid types. + +
-bc <type>
- Sets both "Controller.Left" and "Controller.Right" properties. + Set both "Controller.Left" and "Controller.Right" properties. + See the Game Properties section for valid types. + + + +
-aq <type>
+ Set "Controller.Left1", "Controller.Left2", "Controller.Right1" and "Controller.Right2" properties for QuadTari. See the Game Properties section for valid types. @@ -4051,7 +4082,7 @@ Ms Pac-Man (Stella extended codes): - + - + - + - + - + - + - + - + - + - + - + - +
Cart.Type:Cart.Type Indicates the bank-switching type for the game. The value of this property must be either Auto or one of the following (for more information about bank-switching see Kevin Horton's 2600 bankswitching @@ -4116,12 +4147,12 @@ Ms Pac-Man (Stella extended codes):
Cart.StartBank:Cart.StartBank Indicates which bank to use for reading the reset vector.
Display.Format:Display.Format Indicates the television format the game was designed for. The value must be Auto or one of the following. Types marked as (¹) do currently have no reliable auto-detection. A format can be enforced @@ -4138,27 +4169,27 @@ Ms Pac-Man (Stella extended codes):
Display.VCenter:Display.VCenter Indicates the offset for the vertical center of the display. The value must be n such that -20 <= n <= 20.
Display.Phosphor:Display.Phosphor Indicates whether the phosphor effect should be emulated or not. The value must be Yes or No.
Display.PPBlend:Display.PPBlend Indicates the amount of blending which will occur while using the phosphor effect. The value must be n such that 0 <= n <= 100. The default value is whatever is specified for tv.phosblend.
Cart.Sound:Cart.Sound Indicates if the game should use 1 or 2 channels for sound output. All original Atari 2600 machines supported 1 channel only, but some homebrew games have been written to take advantage of stereo @@ -4177,19 +4208,19 @@ Ms Pac-Man (Stella extended codes): - + - + - + @@ -4201,7 +4232,15 @@ Ms Pac-Man (Stella extended codes):

Console.TVType:Console.TVType Indicates the default television setting for the game. The value must be Color or BW.
Console.LeftDiff:Console.LeftDiff Indicates the default difficulty setting for the left player. The value must be A or B.
Console.RightDiff:Console.RightDiff Indicates the default difficulty setting for the right player. The value must be A or B.
- + - +
Controller.Left:
Controller.Right:
+ Controller.Left
+ Controller.Right
+
For QuadTari:
+ Controller.Left1
+ Controller.Left2
+ Controller.Right1
+ Controller.Right2
+
Indicates what type of controller the left and right player uses. The value must be either Auto or one of the following types. Types marked as (¹) do not have auto-detection yet. @@ -4224,12 +4263,12 @@ Ms Pac-Man (Stella extended codes):
LightgunAtari XG-1 compatible Light Gun
Mindlink ¹Mindlink controller.
KidVid ¹KidVid controller, limited support (8, 9 and 0 start the games).
QuadTariQuadTari controller, limited support (joysticks only).
QuadTariQuadTari controller, limited support (Joystick, Driving controller, SaveKey and AtariVox only).
Console.SwapPorts:Console.SwapPorts Indicates that the left and right ports should be swapped internally. This is used for ROMs like 'Raiders of the Lost Ark' where the Player 0 joystick is plugged into the right joystick port. @@ -4237,7 +4276,7 @@ Ms Pac-Man (Stella extended codes):
Controller.SwapPaddles:Controller.SwapPaddles Indicates that the left and right paddles in a particular port should be swapped. This is used for ROMs like 'Demons to Diamonds' where the default paddle is paddle 1, not @@ -4247,17 +4286,17 @@ Ms Pac-Man (Stella extended codes):
Controller.PaddlesXCenter:Controller.PaddlesXCenter Defines the horizontal center of the paddles (range -10..30).
Controller.PaddlesYCenter:Controller.PaddlesYCenter Defines the vertical center of the paddles (range -10..30).
Controller.MouseAxis:Controller.MouseAxis Indicates how the mouse should emulate virtual controllers. In 'Auto' mode, the system decides how to best use the mouse. Otherwise, XY indicates how to use the X/Y axis (ie, 02 is paddle0/paddle2). @@ -4275,7 +4314,7 @@ Ms Pac-Man (Stella extended codes):
7 MindLink 1
An optional second parameter (default of 100) indicates how much - of the paddle range that the mouse should emulate. + of the paddle range the mouse should emulate. @@ -4291,14 +4330,14 @@ Ms Pac-Man (Stella extended codes):

- + - + - + - + - + - + diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 39ec0f0a8..9cf1b57d2 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -929,8 +929,7 @@ unique_ptr Console::getControllerPort(const Controller::Type type, break; case Controller::Type::QuadTari: - // TODO: support multiple controller types - controller = make_unique(port, myEvent, *mySystem); + controller = make_unique(port, myOSystem, *mySystem, myProperties); break; default: diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 3552e0296..86835f54d 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -711,5 +711,8 @@ bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size return searchForBytes(image, size, signature, 5); } - return false; + + uInt8 signature[] = { 0x1B, 0x1F, 0x0B, 0x0E, 0x1E, 0x0B, 0x1C, 0x13 }; + + return searchForBytes(image, size, signature, 8); } diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx index 65f2d67ca..36e71288c 100644 --- a/src/emucore/DefProps.hxx +++ b/src/emucore/DefProps.hxx @@ -27,3525 +27,3525 @@ static constexpr uInt32 DEF_PROPS_SIZE = 3518; -static const BSPF::array2D DefProps = {{ - { "000509d1ed2b8d30a9d94be1b3b5febb", "Greg Zumwalt", "", "Jungle Jane (2003) (Greg Zumwalt) (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0060a89b4c956b9c703a59b181cb3018", "CommaVid, Irwin Gaines - Ariola", "CM-008 - 712 008-720", "Cakewalk (1983) (CommaVid) (PAL)", "AKA Alarm in der Backstube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "007d18dedc1f0565f09c42aa61a6f585", "CCE", "C-843", "Worm War I (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "008543ae43497af015e9428a5e3e874e", "Retroactive", "", "Qb (V2.09) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "00b7b4cbec81570642283e7fc1ef17af", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "00ce0bdd43aed84a983bef38fe7f5ee3", "20th Century Fox, Bill Aspromonte", "11012", "Bank Heist (1983) (20th Century Fox)", "AKA Bonnie and Clyde, Cops 'n' Robbers, Holdup, Rooring 20's", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "00ce76ad69cdc2fa36ada01ae092d5a6", "Bit Corporation", "PGP214", "Cosmic Avenger (4 Game in One) (1983) (BitCorp) (PAL)", "AKA StarMaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "00dc28b881989c39a6cf87a892bd3c6b", "CCE", "", "Krull (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "00e19ebf9d0817ccfb057e262be1e5af", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "00e55b27fe2e96354cd21b8b698d1e31", "", "", "Phoenix (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "00eaee22034aff602f899b684c107d77", "Rainbow Vision - Suntek - Sunteck Corp", "SS-001", "Time Race (1983) (Rainbow Vision) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "00f7985c20b8bdf3c557fac4d3f26775", "Aaron Curtis", "", "AStar (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "012020625a3227815e47b37fd025e480", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01293bd90a4579abb7aed2f7d440681f", "Century", "", "Snoopy (1983) (Century) (PAL)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01297d9b450455dd716db9658efb2fae", "TechnoVision - Video Technology", "TVS1002", "Save Our Ship (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "012b8e6ef3b5fd5aabc94075c527709d", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" }, - { "0164f26f6b38a34208cd4a2d0212afc3", "Coleco, Ed English", "2656", "Mr. Do! (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0173675d40a8d975763ee493377ca87d", "CBS Electronics, Ed English", "4L1751", "Roc 'n Rope (1984) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01abcc1d2d3cba87a3aa0eb97a9d7b9c", "Jone Yuan Telephonic Enterprise Co", "", "Topy (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01b09872dcd9556427761f0ed64aa42a", "Galaga Games", "", "River Raid (1984) (Galaga Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01cb3e8dfab7203a9c62ba3b94b4e59f", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01e5c81258860dd82f77339d58bc5f5c", "CCE", "", "Corrida da Matematica (CCE)", "AKA Math Gran Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01e60a109a6a67c70d3c0528381d0187", "ITT Family Games, Perry Rhodan-Serie", "554-33 383", "Fire Birds (1983) (ITT Family Games) (PAL)", "AKA Sky Alien", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "01f584bf67b0e464014a8c8b5ea470e3", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02066b17f29082412c6754c1a2d6302e", "", "", "Demo Image Series #3 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "024365007a87f213cbe8ef5f2e8e1333", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "025668e36a788e8af8ac4f1be7e72043", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (06-14-82) (Atari) (Prototype)", "Console ports are swapped", "Prototype", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "026180bf641ff17d8577c33facf0edea", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0277c449fae63f6f1c8f94dedfcf0058", "", "", "Laser Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "027a59a575b78860aed780b2ae7d001d", "CCE", "", "Pressure Cooker (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "028024fb8e5e5f18ea586652f9799c96", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "2468", "Carnival (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02811151906e477d47c135db5b1699c6", "", "", "FlickerSort Demo (Updated) (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02a5fc90a0d183f870e8eebac1f16591", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02ab2c47bc21e7feafa015f90d7df776", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02ced7ea2b7cb509748db6bfa227ebec", "Parker Brothers, Ed English, David Lamkins", "931502", "Frogger (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02cee0b140d2f1a1efcfb1d482a5c392", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02dcba28c614fec7ca25955327128abb", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD) [a]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "02e3f4ba156fb578bef7d7a0bf3400c1", "", "", "Booster (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "033e21521e0bf4e54e8816873943406d", "20th Century Fox Video Games - Sirius Software, Dan Thompson", "11020", "Earth Dies Screaming, The (1983) (20th Century Fox)", "The Day the Earth Stood Still", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "034c1434280b0f2c9f229777d790d1e1", "Telegames", "5665 A016", "Baseball (1988) (Telegames) (PAL)", "AKA Super Challenge Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0375f589f7da06d2d2be532e0d4d4b94", "", "", "Push (V0.04) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0383dc02cb82302da3d155fd108bfe3a", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug) (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "038e1e79c3d4410defde4bfe0b99cc32", "Atari, Tod Frye, Gary Shannon", "", "Aquaventure (08-12-1983) (Atari) (Prototype)", "AKA Sea Sentinel", "Unbelievably Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "039cf18b459d33b8a8fca31d06c4c244", "", "", "Demo Image Series #0 (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "03b1051c9374678363c899914412cfc5", "", "", "Incoming (30-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "03c3f7ba4585e349dd12bfa7b34b7729", "SEGA, Jeff Lorenz", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "03fbcee0bc80e31f27254aea3d920510", "Bit Corporation", "R320", "Trick Shot (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "03ff9e8a7af437f16447fe88cea3226c", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "04014d563b094e79ac8974366f616308", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "041b5e56bbc650db574bd8db3fae2696", "Thomas Jentzsch", "", "Thrust (V1.0) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "043f165f384fbea3ea89393597951512", "Spectravision - Spectravideo", "SA-202", "Planet Patrol (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0443cfa9872cdb49069186413275fa21", "M Network - INTV, Patricia Lewis Du Long, Ron Surratt", "MT4518", "BurgerTime (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "045035f995272eb2deb8820111745a07", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia)", "AKA Jungle Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "047ac3b9faea64522b7a23c4465a7aa8", "", "", "Defender (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "04856e3006a4f5f7b4638da71dad3d88", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari) (PAL)", "AKA Dog Fight", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "049626cbfb1a5f7a5dc885a0c4bb758e", "", "", "MegaMania (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "04b488d4eef622d022a0021375e7e339", "Home Vision - Gem International Corp. - VDI", "VCS83107", "Tennis (1983) (Home Vision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "04cf9e6898007024622ed6a0b295961f", "Bit Corporation", "R320", "Tennis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "04dfb4acac1d0909e4c360fd2ac04480", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "04e737c9d53cd84bfd5ee679954e4706", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "04fccc7735155a6c1373d453b110c640", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0519f395d5f7d76be813b834aa51c0be", "Atari, Ian Shepard", "CX2604", "Space War (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0546f4e6b946f38956799dd00caab3b1", "Thomas Jentzsch", "", "My Golf (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "056f5d886a4e7e6fdd83650554997d0d", "Parker Brothers, Ed Temple", "931504", "Amidar (1982) (Parker Bros) (PAL)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "056ff67dd9715fafa91fb8b0ddcc4a46", "", "", "Frisco (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05824fcbe615dbca836d061a140a50e0", "Jeffry Johnston", "", "Radial Pong - Version 9 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05aedf04803c43eb5e09dfd098d3fd01", "", "", "Keystone Kapers (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05aff8f626ef870432ae3b3d9d5aa301", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05b45ba09c05befa75ac70476829eda0", "Parker Brothers, Rex Bradford", "931507", "Star Wars - Jedi Arena (1983) (Parker Bros) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" }, - { "05c60458ec69e7fe8b1be973852d84f1", "", "", "Test (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05c765a63e61882abd1c2d627b652225", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05ccf96247af12eef59698f1a060a54f", "Otto Versand", "600273", "King Arthur (1983) (Otto Versand) (PAL)", "AKA Dragonfire (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "05d61b925d3d2474bab83f0a79bb5df1", "Eckhard Stolberg", "", "Cosmic Ark Stars (1997) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05eb4347f0ec8f4783983ca35ffd8d1b", "", "", "Qb (2.06) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "05ebd183ea854c0a1b56c218246fbbae", "Atari, Dan Hitchens", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "05f11fb2e45c4e47424d3cb25414d278", "", "", "Boring (NTSC) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "060c865c782debb047e6fd101c8923fc", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0614ed51acd027d531e7c85c4f435292", "", "", "Narnia (Glenn Saunders) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0619e1c3286bbfbace040b8c3ec5add2", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" }, - { "0651216c4a4a9c9ac5ada3013a317c72", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "06742cf522f23797157f215a1dc8a1a9", "", "", "Healthbars (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0685bd0bcb975ceef7041749a5454a48", "Piero Cavina", "", "11 Sprite Demo (Piero Cavina) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "069c17beb1e8e0557adb8539fdcf6cba", "", "", "Phantom II & Pirate (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "06b0194ce992584c365278e0d7323279", "Activision", "", "Unknown Activision Game #2 (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "06b6c5031b8353f3a424a5b86b8fe409", "Activision, Mike Lorenzen - Ariola", "EAX-023 - 711 023-720", "Oink! (1983) (Activision) (PAL)", "AKA Das Schweinchen und der Wolf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "06cfd57f0559f38b9293adae9128ff88", "Telegames", "4317 A009", "Adventures on GX-12 (1988) (Telegames) (PAL)", "AKA Adventures of Tron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "06d2f7674cea977607f74c464ce600a2", "CBS Electronics, Alex Nevelson", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "" }, - { "06db908011065e5ebb37f4e253c2a0b0", "", "", "Gopher (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "06e5dc181a8eda1c31cc7c581c68b6ef", "", "", "Tac-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "071f84d10b343c7c05ce3e32af631687", "Rainbow Vision - Suntek", "SS-019", "Curtiss (1983) (Rainbow Vision) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "072a6ea2181ca0df88ac0dedc67b239d", "", "", "Multiple Missiles Demo (19-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "073cb76b006af034fd150be3f5e0e7e6", "", "", "Mobile 48 Sprite Kernel (Bug Fixed) (10-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "073d7aff37b7601431e4f742c36c0dc1", "", "", "Bermuda (Unknown) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "074ec425ec20579e64a7ded592155d48", "Atari - Sculptured Software, Steve Aguirre", "CX26162", "Fatal Run (Ultimate Driving) (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "075069ad80cde15eca69e3c98bd66714", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE)", "AKA Bobby Vai Para Casa", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0751f342ee4cf28f2c9a6e8467c901be", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "07973be3ecfd55235bf59aa56bdef28c", "Suntek", "SS-036", "Criminal Pursuit (1983) (Suntek) (PAL)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "079fe9103515d15bc108577e234a484d", "", "", "Multi-Color Demo 0 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "07a3af1e18b63765b6807876366f5e8a", "Joe Grand", "", "SCSIcide Pre-release 2 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "07c76f2d88552d20ad2c0ed7aef406c6", "Cody Pittman", "", "Blob (Cody Pittman) (Hack)", "Hack of Halloween", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "07f42847a79e4f5ae55cc03304b18c25", "Zellers", "", "Sea Hawk (Zellers)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "07f84db31e97ef8d08dc9fa8a5250755", "Supergame", "", "Enduro (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "07f91e33e76f53bb9d2731fd5d8a35a5", "Atari", "CX2632", "Space Invaders (1978) (Atari) [t1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0805366f1b165a64b6d4df20d2c39d25", "Atari, Dan Hitchens", "CX2650", "Berzerk (1982) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08188785e2b8300983529946dbeff4d2", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" }, - { "081e2c114c9c20b61acf25fc95c71bf4", "Parker Brothers, Ed English, David Lamkins", "PB5300", "Frogger (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "082fdc8bd47fef01482ce5883c4ffdb8", "Charles Morgan", "", "Tanks DX (Charles Morgan) (Hack)", "Hack of Tanks But No Tanks", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0832fb2ee654bf9382bc57d2b16d2ffc", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "083e7cae41a874b2f9b61736c37d2ffe", "Imagic, Rob Fulop, Bob Smith", "720106-2A, IA3600P, EIX-009-04I", "Riddle of the Sphinx (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "085322bae40d904f53bdcc56df0593fc", "Parker Brothers, Dave Engman, Dawn Stockbridge", "PB5340", "Tutankham (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0856f202b18cd46e44fd1dc3b42e9bfb", "", "", "Frame Counter 1 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0866e22f6f56f92ea1a14c8d8d01d29c", "Androbot - Western Technologies, Michael Case, Lenny Carlson", "", "AndroMan on the Moon (1984) (Western Tech) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0891252ee4e307689febccf3cfd8a8ab", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0894aa7be77521f9df562be8d9555fe6", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08989fa4ff537f5dbd611aff4019521a", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08bd4c1dcc843f6a0b563d9fd80b3b11", "Quelle", "343.273 9", "Phantompanzer II (1983) (Quelle) (PAL)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08bf437d012db07b05ff57a0c745c49e", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Meteoroids (1982) (Arcadia) (Prototype)", "Suicide Mission Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "08d1b6d75206edb999252caf542a2c7f", "Larry Petit", "", "Super Home Run (2003) (Larry Petit) (Hack)", "Hack of Home Run", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08d60a58a691c7f690162850302dc0e1", "", "", "Poker Squares (V0.27) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08e5960bb52d9a3e2c9954677b5e4472", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (10-20-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08ea2fdaa22e5802c839ee7dfb0483dc", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "08f4dc6f118f7c98e2406c180c08e78e", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" }, - { "08f853e8e01e711919e734d85349220d", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0906c6e0e4bda9c10cfa4c5fc64d2f4b", "Retroactive", "", "Qb (V0.12) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "090f0a7ef8a3f885048d213faa59b2f8", "Carrere Video - Western Technologies, John Hall - Teldec - Prism", "USC1012", "M.A.D. (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "09274c3fc1c43bf1e362fda436651fd8", "Thomas Jentzsch", "", "Acid Drop (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "09388bf390cd9a86dc0849697b96c7dc", "Absolute Entertainment, Alex DeMeo", "AG-045-04, AK-045-04", "Pete Rose Baseball (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0945081a6bd00345ff3d58eb7a07330a", "", "", "Stampede (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0956285e24a18efa10c68a33846ca84d", "Dismac", "", "Viagem Espacial (Dismac)", "AKA Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0963aa9f7f6cf5a36ff700001583624e", "Franklin Cruz", "", "Space Invaders 2 (Hack) [o1]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "096649575e451508006b17e0353259a5", "Justin J. Scott", "", "Yar Vs. Yar (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "097074f24cde141fe6a0f26a10333265", "", "", "Marble Craze (V0.90) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "097936b07e0e0117b9026ae6835eb168", "Imagic, Dennis Koble", "720100-2B, IA3000P", "Trick Shot (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "09abfe9a312ce7c9f661582fdf12eab6", "Atari, Douglas Neubauer", "CX26154", "Super Football (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "09e1ecf9bd2a3030d5670dba7a65e78d", "Atari, James Andreasen", "CX2654", "Haunted House (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "09e9ba0762fd0c3cf3c2e072cff79cac", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "09f89bbfa2ab00f1964d200e12d7ced0", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0a1b98937911d621b004b1617446d124", "", "", "Hangman Pac-Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0a981c03204ac2b278ba392674682560", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "0aa208060d7c140f20571e3341f5a3f8", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Tom Sloper", "VC1009", "Towering Inferno (1982) (U.S. Games)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" }, - { "0abf64ca504a116adca80f77f85e00fb", "", "", "Cube Conquest (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0ac0d491763153fac75f5337ce32a9d6", "", "", "SPAM Image Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0acaf71e60b89f6b6eab63db6ab84510", "", "", "This Planet Sucks (Greg Troutman) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0aceb7c3bd13fe048b77a1928ed4267d", "Imagic, Bob Smith", "720102-2B, IA3201P, EIX-011-04I", "Star Voyager (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0ad9a358e361256b94f3fb4f2fa5a3b1", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari) [a]", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, - { "0adb21206de92e8aec5ef295805ebb90", "", "", "Solaris (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Solaris", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0ae3497e731ca0bf6a77b23441d9d9f9", "", "", "Analog Clock (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0af51ceb4aecc7a8fc89781ac44a1973", "Barry Laws Jr.", "", "Face Invaders Deluxe (Barry Laws Jr.) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0afe6ae18966795b89314c3797dd2b1e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0b01909ba84512fdaf224d3c3fd0cf8d", "", "", "Revenge of the Apes (Hack)", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0b1056f1091cfdc5eb0e2301f47ac6c3", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0b17ed42984000da8b727ca46143f87a", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-17-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "" }, - { "0b24658714f8dff110a693a2052cc207", "CCE", "C-815", "Seaquest (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0b33252b680b65001e91a411e56e72e9", "CCE", "C-832", "Atlantis (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0b4e793c9425175498f5a65a3e960086", "CCE", "", "Kung Fu Master (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0b55399cf640a2a00ba72dd155a0c140", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-1A, 03205", "Fathom (1983) (Imagic)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0b577e63b0c64f9779f315dca8967587", "Videospielkassette - Ariola", "PGP236", "Raketen-Angriff (Ariola) (PAL)", "AKA Missile Control", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0b8d3002d8f744a753ba434a4d39249a", "Sears Tele-Games, Robert Zdybel", "CX2619 - 49-75159", "Stellar Track (1981) (Sears)", "AKA Stella Trak", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0bf19e40d5cd8aa5afb33b16569313e6", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0bf1e354304f46c0caf8fc0f6f5e9525", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0bfabf1e98bdb180643f35f2165995d0", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "0c0392db94a20e4d006d885abbe60d8e", "", "", "Dodge Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0c336f83b0e6e3bc86c77f368448e77b", "Bit Corporation", "R320", "Circus Atari (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0c35806ff0019a270a7acae68de89d28", "Froggo", "FG1003", "Task Force (1987) (Froggo)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0c48e820301251fbb6bcdc89bd3555d9", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0c54811cf3b1f1573c9164d5f19eca65", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL)", "AKA Dragster Rennen, Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0c72cc3a6658c1abd4b735ef55fa72e4", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0c7926d660f903a2d6910c254660c32c", "Atari, Larry Kaplan", "CX2602, CX2602P", "Air-Sea Battle (1977) (Atari) (PAL)", "AKA Anti-Aircraft", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0c7bd935d9a7f2522155e48315f44fa0", "Carrere Video - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Tom Sloper - Teldec - Prism", "USC1009", "Infernal Tower (1983) (Carrere Video) (PAL)", "AKA Towering Inferno", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" }, - { "0c80751f6f7a3b370cc9e9f39ad533a7", "Atari, Carla Meninsky", "CX2610", "Warlords (1981) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "0cb7af80fd0ddef84844481d85e5d29b", "", "", "Mr. Pac-Man (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0cc8224ff1edfe458e8629e9e5fe3f5b", "Thomas Jentzsch", "", "Trick 12 (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0cdd9cc692e8b04ba8eb31fc31d72e5e", "Thomas Jentzsch", "", "Wing War (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0cebb0bb45a856b23f56d21ce7d1bc34", "20th Century Fox Video Games, Bill Aspromonte", "11131", "Crash Dive (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0cec9e46a25d338bf595a29aa2606516", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0cfdd2f3b243cac21f38a0f09f54bead", "", "", "Overhead Adventure Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d07d2c1be1a5eaaea235a533bcda781", "", "", "Scrolling Playfield 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d08558f34a47e4eaa39d01c8efb81f0", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d09cff0d28033c02c3290edfc3a5cea", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d1b3abf681a2fc9a6aa31a9b0e8b445", "Atari", "CX26163P", "Laser Blast (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d27c7f5db349b592f70f68daf5e8f3b", "", "", "Space Instigators (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d35618b6d76ddd46d2626e9e3e40db5", "", "", "X-Doom V.26 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d5af65ad3f19558e6f8e29bf2a9d0f8", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0d6b974fe58a1bdd453600401c407856", "Atari", "", "128-in-1 Junior Console (Chip 3 or 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d786a41695e5fc8cffd05a6dbb3f659", "", "", "Scrolling Playfield With Score (10-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d7e630a14856f4d52c9666040961d4d", "", "", "Wavy Line Test (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0d90a0ee73d55539b7def24c88caa651", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0db4f4150fecf77e4ce72ca4d04c052f", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0dd4c69b5f9a7ae96a7a08329496779a", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0de53160a8b54c3aa5aed8d68c970b62", "Quelle", "806.174 9", "Fuchs & Schweinchen Schlau (1983) (Quelle) (PAL)", "AKA Oink!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0dfbdadf8f1bc718e7e1bb3ccd5fef3d", "", "", "Mr. Pac-Man (New start tune) (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0e0808227ef41f6825c06f25082c2e56", "", "", "Candi (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0e08cd2c5bcf11c6a7e5a009a7715b6a", "", "", "Boing! (PD) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0e224ea74310da4e7e2103400eb1b4bf", "Atari, Peter C. Niday, Gary Shannon, Howard Scott Warshaw", "", "Mind Maze (10-10-1984) (Atari) (Prototype)", "Uses the MindLink controller", "Prototype", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "" }, - { "0e23d0ed4c33b2011ab4cc93a7619683", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0e4b2b6e014a93ef8be896823da0d4ec", "", "", "Skiing (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0e713d4e272ea7322c5b27d645f56dd0", "Home Vision - Gem International Corp. - VDI", "VCS83105", "Panda Chase (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0e7e73421606873b544e858c59dc283e", "Digivision", "", "Super Soccer (Digivision)", "AKA RealSports Soccer", "", "", "", "F8", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0e86470791b26292abe1c64545c47985", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "01 70", "", "", "", "" }, - { "0ec93f519bb769e0d9f80e61f6cc8023", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0ecdb07bf9b36ef18f3780ef48e6c709", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0eebfb60d437796d536039701ec43845", "Fabrizio Zavagli", "", "Cakewalk (Fabrizio Zavagli)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0eecb5f58f55de9db4eedb3a0f6b74a8", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0ef64cdbecccb7049752a3de0b7ade14", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0efc91e45f61023cda9d086a7d3c402f", "B.J. Best (aka bjbest60)", "", "Space Cactus Canyon (2017)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0effef4a341f8eebab65621c60c48787", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f14c03050b35d6b1d8850b07578722d", "Jeffry Johnston", "", "Radial Pong - Version 10 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f24ca5668b4ab5dfaf217933c505926", "", "", "Fantastic Voyage (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f2e09c71cc216f79d22a804152ba24b", "Bob Colbert", "", "Scroller Demo (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0f341d1f4e144e3163d9a5fc5a662b79", "", "", "RUN Platform Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "0f39fc03d579d0d93a6b729a3746843e", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f604cd4c9d2795cf5746e8af7948064", "Champ Games", "CG-02-N", "Conquest Of Mars (2010) (NTSC)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f643c34e40e3f1daafd9c524d3ffe64", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f6676b05621f80c670966e2995b227a", "", "", "Globe Trotter Demo 1 (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f738dc44437557624eb277ed7ad91c9", "", "", "Grand Prix (Unknown) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f8043715d66a4bbed394ef801d99862", "Quelle", "684.733 9", "Robin Hood (1983) (Quelle) (PAL)", "AKA Save Our Ship", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0f95264089c99fc2a839a19872552004", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0fba7d8c3520bdb681f75494e498ec36", "", "", "Gunfight 2600 - Final Run (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0fbf618be43d4396856d4244126fe7dc", "Quelle", "805.784 6", "Labyrinth (1983) (Quelle) (PAL)", "AKA Maze Craze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0fc161704c46e16f7483f92b06c1558d", "CCE", "C-853", "Spider Fighter (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0fcff6fe3b0769ad5d0cf82814d2a6d9", "Suntek", "SS-027", "Zoo Fun (1983) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0fd72a13b3b6103fc825a692c71963b4", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "0fee596b974c9d3e70b367a3671599b6", "Bit Corporation", "R320", "Name This Game (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "101ab60f4000a5d13792ef0abad5f74b", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "102672bbd7e25cd79f4384dd7214c32b", "Atari, Alan Miller - Sears", "CX2642 - 6-99814", "Hunt & Score - Memory Match (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "103e9d616328969f5d7b4e0a381b25d5", "", "", "Playfield Illustration and Logo Demo (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "103f1756d9dc0dd2b16b53ad0f0f1859", "Home Vision, Gem International Corp.", "", "Go Go Home Monster (1983) (Home Vision) (PAL)", "AKA Go Go Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "104468e44898b8e9fa4a1500fde8d4cb", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "106326c262dfd3e8eaeabd961d2a0519", "", "", "PAL-NTSC Detector (15-11-2002) (CT)[a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "106855474c69d08c8ffa308d47337269", "Atari - Sculptured Software, Adam Clayton", "CX26151", "Dark Chambers (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "107cc025334211e6d29da0b6be46aec7", "Atari, Bob Smith - Sears", "CX2648 - 49-75161", "Video Pinball (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1086ff69f82b68d6776634f336fb4857", "Activision, David Crane", "AG-009", "Bloody Human Freeway (1981) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "10958cd0a1a81d599005f1797ab0e51d", "", "", "Centipede 2k (2000) (PD) (Hack)", "Hack of Centipede", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "10a3cd14e5dcfdde6ff216a14ce7b7dd", "Atari", "CX262, CX2627P", "Human Cannonball (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "10af8728f975aa35a99d0965de8f714c", "Dinatronic", "", "Seaquest (Dinatronic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "10c47acca2ecd212b900ad3cf6942dbb", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a4]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "10c8cfd8c37522f11d47540ff024e5f9", "Canal 3 - Intellivision", "C 3016", "Demon Attack (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "10eae73a07b3da044b72473d8d366267", "Funvision - Fund. Int'l Co.", "", "Karate (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "10f0ecaf962aef1fc28abed870b01b65", "Atari, Paul Donaldson", "", "Bionic Breakthrough (06-22-1984) (Atari) (Prototype)", "Uses the Mindlink Controller", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "" }, - { "10f62443f1ae087dc588a77f9e8f43e9", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "110ac8ecaf1b69f41bc94c59dfcb8b2d", "", "", "Demon Attack (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "111029770226b319524134193886a10e", "Hozer Video Games", "", "Gunfight 2600 - One Limit Reached! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "11330eaa5dd2629052fac37cfe1a0b7d", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "113cd09c9771ac278544b7e90efe7df2", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "114c599454d32f74c728a6e1f71012ba", "Activision, Bob Whitehead - Ariola", "EAX-015, EAX-015-04I - 711 015-725", "Chopper Command (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "11bcf5c752088b5aaf86d6c7a6a11e8d", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "11e7e0d9437ec98fa085284cf16d0eb4", "", "", "Bowling (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "11f9532557e4c9569f4b242164006161", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005) (PAL)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1201c18cf00d2c236f42e4d7d8c86aa1", "", "", "Nick Bensema Demo (Nick Bensema)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "12080205f669b8e7783b976f8cf3d8bb", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "12123b534bdee79ed7563b9ad74f1cbd", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1228c01cd3c4b9c477540c5adb306d2a", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "1266b3fd632c981f3ef9bdbf9f86ce9a", "Activision, Bob Whitehead", "EAZ-034-04, EAZ-034-04I", "Private Eye (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1267e3c6ca951ff1df6f222c8f813d97", "", "", "Dragonfire (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "126f7f64b7b00e25dcf5e3710b4cf8b8", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1278f74ca1dfaa9122df3eca3c5bcaad", "Rainbow Vision - Suntek", "SS-013", "Bi! Bi! (Rainbow Vision) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1287535256bf5dff404839ac9e25c3e7", "PacManPlus", "Rev 2", "Alien Pac-Man (PacManPlus) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "12937db3d4a80da5c4452b752891252d", "Digitel", "", "Megamania (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "12bca8305d5ab8ea51fe1cfd95d7ab0e", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "12d7e0d6b187889f8d150bf7034d1db2", "", "", "Poker Squares (V0.0e) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "130c5742cd6cbe4877704d733d5b08ca", "Home Vision - Gem International Corp. - VDI", "VCS83109", "World End (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1323c45d660f5a5b6d5ea45c6c4cbe4a", "Canal 3 - Intellivision", "", "Enduro (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "133456269a03e3fdae6cddd65754c50d", "Tigervision - Software Electronics Corporation - Teldec", "7-006 - 3.60008 VG", "Springer (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "133a4234512e8c4e9e8c5651469d4a09", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "133b56de011d562cbab665968bde352b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1343de49c2a50d99176255f99f0d0234", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" }, - { "13448eb5ba575e8d7b8d5b280ea6788f", "Digivision", "", "Crackpots (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1345e972dbe08ea3e70850902e20e1a5", "Greg Troutman", "", "Dark Mage (rough beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1351c67b42770c1bd758c3e42f553fea", "Digivision", "", "Keystone Kapers (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "135708b9a7dd20576c1b66ab2a41860d", "", "", "Hangman Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13584411da0a8d431991035423fdc0dc", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1367e41858be525710eb04d0dab53505", "Kyle Pittman", "", "Zelda (2003) (Kyle Pittman) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "136f75c4dd02c29283752b7e5799f978", "Atari, Dan Hitchens - Sears", "CX2650 - 49-75168", "Berzerk (1982) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13895ef15610af0d0f89d588f376b3fe", "Tigervision, Rorke Weigandt", "7-005", "Marauder (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13a37cf8170a3a34ce311b89bde82032", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13a991bc9c2ff03753aeb322d3e3e2e5", "Funvision - Fund. International Co.", "", "Galactic (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13aa1f9ac4249947e4af61319d9a08f2", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13abc32f803165c458bb086fa57195fb", "Christian Samuel", "", "E.T. The Extra-Testical (Christian Samuel) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13ccc692f111d52fec75d83df16192e2", "Canal 3 - Intellivision", "", "Fishing Derby (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13d8326bf5648db4dafce45d25e62ddd", "", "", "Atari Logo Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "13dfb095e519a555a5b60b7d9d7169f9", "", "", "Red Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "140909d204abd6841c64cdad4d7765b4", "", "", "Moving Blue Ladder Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "14163eb2a3ddd35576bd8527eae3b45e", "", "", "Multi-Color Demo 6 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1423f560062c4f3c669d55891a2bcbe7", "CCE", "C-859", "MASH (1983) (CCE) [a]", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1428029e762797069ad795ce7c6a1a93", "", "", "Thunderground (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "143918368f4f4dfff90999188c0197c9", "", "", "Unknown Title (bin00016 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1442d1b35a6478fba22ae7dd1fcb5634", "Thomas Jentzsch", "", "Thrust (V0.2) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "148471144ccebd7f6aa9aa9215896533", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "149b543c917c180a1b02d33c12415206", "CCE", "C-857", "Superman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "14a56b493a8d9d10e94a3e100362e3a2", "Hozer Video Games", "", "Gunfight 2600 - Early Play-kernel (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "14b1e30982962c72f426e2e763eb4274", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "14c2548712099c220964d7f044c59fd9", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software)", "AKA Bubbles, Soap Suds, The Emphysema Game", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "14d365bbfaac3d20c6119591f57acca4", "", "", "Video Life (Unknown) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "14dbb3686dd31964332dc2ef0c55cad0", "", "", "Demo Image Series #15 - Three Marios (PAL) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "151c33a71b99e6bcffb34b43c6f0ec23", "Parker Brothers, Laura Nikolich", "", "Care Bears (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "151fa3218d8d7600114eb5bcd79c85cb", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-02-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "" }, - { "152c253478b009c275e18cd731b48561", "", "", "Quest (11-10-2002) (Chris Larkin)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "153f40e335e5cb90f5ce02e54934ab62", "Absolute Entertainment, Alex DeMeo", "EAZ-041-04I", "Title Match Pro Wrestling (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1542662f665d2ffaa77b4b897dd2e2af", "", "", "Starfield (V1.0) (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "155fa7f479dcba3b10b1494e236d6010", "Skyworks", "", "Tomcat (2002) (Skyworks) (PAL)", "AKA The F-14 Flight Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "157356f80c709ab675961d8b8b207e20", "", "", "Multi-Sprite Game V2.5 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "157bddb7192754a45372be196797f284", "Atari, Warren Robinett - Sears", "CX2613, 49-75154", "Adventure (1980) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "159e5cd6ccb968015f49aed5adbc91eb", "Justin J. Scott", "", "Yar's Defeat (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "15a0d59304dece2c7d0580f3ea3527f0", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (04-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "15b498199ed0ed28057bf0dbdce9b8d8", "Thomas Jentzsch", "", "Jammed (V0.2) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "15b9f5e2439bfaa08874b5184261c777", "Bit Corporation", "R320", "Space Invaders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "15bcd74f2f1f2a63e1aa93e90d2c0555", "", "", "Incoming (22-08-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "15bf2ef7583bfcbbba630847a1dc5539", "Erik Eid", "", "Euchre (Jul 15) (2002) (Eric Eid) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "15c11ab6e4502b2010b18366133fc322", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (09-19-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "15dd21c2608e0d7d9f54c0d3f08cca1f", "Data Age, J. Ray Dettling", "112-008", "Frankenstein's Monster (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "15fe28d0c8893be9223e8cb2d032e557", "", "", "Towering Inferno (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1619bc27632f9148d8480cd813aa74c3", "Thomas Jentzsch", "", "Steeple Chase (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "161ded4a85d3c78e44fffd40426f537f", "Thomas Jentzsch", "", "JtzBall (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "16229d61d7b0c89b01853660a8da22bb", "", "", "spin4a50", "", "", "", "", "4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "163e7e757e2dc44469123ff0e5daec5e", "", "", "Many Blue Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "169d4c7bd3a4d09e184a3b993823d048", "", "", "Superman (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "16cb43492987d2f32b423817cdaaf7c4", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "16cc6d1b4ddce51c767a1ba8e5ff196c", "", "", "Big - Move This Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "16d69f71bf5846639be5ff16483f0498", "Bit Corporation", "R320", "Golf (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "16e04823887c547dc24bc70dff693df4", "Atari", "CX26163P", "Tennis (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "16ee443c990215f61f7dd1e55a0d2256", "Spectravideo, David Lubar", "SA-218, SA-218C", "Bumper Bash (1983) (Spectravideo) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "" }, - { "16f494f20af5dc803bc35939ef924020", "Mark De Smet", "", "Video Simon (Mark De Smet)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "170e7589a48739cfb9cc782cbb0fe25a", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network) [fixed]", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "YES", "", "", "AUTO 55", "", "", "", "" }, - { "171cd6b55267573e6a9c2921fb720794", "Kurt Howe", "", "Adventure 34 (Kurt Howe) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "171ebf135b13ba907f462c10d88a2c25", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1733772165d7b886a94e2b4ed0f74ccd", "", "", "Boring Journey Escape (Hack)", "Hack of Journey - Escape", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1738b2e3f25ab3eef3cecb95e1d0d957", "", "", "Hangman Monkey Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "17512d0c38f448712f49f36f9d185c4e", "Retroactive", "", "Qb (Release Candidate #1) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "17515a4d0b7ea5029ffff7dfa8456671", "Piero Cavina", "", "Multi-Sprite Demo V1.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "176d3fba7d687f2b23158098e103c34a", "Zach Matley", "", "Combat AI (16-02-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "177504abd4260c4265e1338955e9fa47", "HCC Software", "", "Pitfall! (Steroids Hack)", "Hack of Pitfall! (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1782929e1c214b70fb6884f77c207a55", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "17ba72433dd41383065d4aa6dedb3d91", "", "", "SCSIcide (09-06-2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "17badbb3f54d1fc01ee68726882f26a6", "M Network - INTV - APh Technological Consulting, Hal Finney, Bruce Pedersen", "MT5659", "Space Attack (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "17bbe288c3855c235950fea91c9504e9", "Dismac", "", "Pega Ladrao (Dismac)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "17c0a63f9a680e7a61beba81692d9297", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper", "VC2004", "Picnic (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "17d000a2882f9fdaa8b4a391ad367f00", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "17ee158d15e4a34f57a837bc1ce2b0ce", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "17ee23e5da931be82f733917adcb6386", "Salu, Dennis M. Kiss", "460758", "Acid Drop (1992) (Salu) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1802cc46b879b229272501998c5de04f", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "183020a80848e06a1238a1ab74079d52", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ) (PAL)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1862fca4f98e66f363308b859b5863af", "Atari", "", "128-in-1 Junior Console (Chip 1 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18a970bea7ac4d29707c8d5cd559d03a", "", "", "Bridge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18b28b386abdadb3a700ac8fb68e639a", "Manuel Polik", "", "Gunfight 2600 (MP) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18b476a34ce5e6db2c032029873ac39b", "Bit Corporation", "R320", "Atlantis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18be8981b8201638f3ed8ae92bb4c215", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18bebbbd41c234f82b1717b1905e6027", "", "", "Space Instigators (Public Release) (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18d26111cef66dff0c8af8cf0e117843", "", "", "Tunnel Demo (Cycling Colours 2) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18dc28bc22402f21e1c9b81344b3b8c5", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "18ed63e3ce5bc3dd2d8bd188b807f1a2", "", "", "Stell-A-Sketch (Bob Colbert) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "18f299edb5ba709a64c80c8c9cec24f2", "Home Vision - Gem International Corp. - VDI", "VCS83111", "Asteroid Fire (1983) (Home Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "19098c46da0640f2b5763167dea6c716", "Andrew Wallace", "", "Laseresal 2002 (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "191449e40b0c56411c70772706f79224", "", "", "Multi-Color Demo 2 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "19162393786098d50587827588198a86", "Jone Yuan Telephonic Enterprise Co", "", "Flag Capture (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "191ac4eec767358ee3ec3756c120423a", "", "", "Checkers (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "192aa2e8c795c9e10a7913e5d41feb81", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125", "Los Angeles 1984 Games (1984) (Atari) (Prototype) (PAL)", "AKA Track and Field (Uses Track & Field Controller)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "193f060553ba0a2a2676f91d9ec0c555", "Atari, Carol Shaw", "CX2636, CX2636P", "Video Checkers (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1942bdb7abc75e412068330a9082b0ff", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" }, - { "1986f864e32e3e8d198b5becf3022257", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "199985cae1c0123ab1aef921daace8be", "", "", "Euchre (Release Candidate 2) (PAL) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "199eb0b8dce1408f3f7d46411b715ca9", "Parker Brothers, David Lamkins, Laura Nikolich", "PB5900", "Spider-Man (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "19a9d3f9fa1b1358fb53009444247aaf", "", "", "Blackjack (Unknown) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "19abaf2144b6a7b281c4112cff154904", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "19b3b807507653516985ba95da92499d", "Joe Gaucher", "", "VCS Draw Demo (Joe Gaucher)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "19d6956ff17a959c48fcd8f4706a848d", "PlayAround - J.H.M.", "202", "Burning Desire (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "19d9b5f8428947eae6f8e97c7f33bf44", "", "", "Fortress (Dual Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "19e739c2764a5ab9ed08f9095aa2af0b", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "19e761e53e5ec8e9f2fceea62715ca06", "Panda", "104", "Scuba Diver (1983) (Panda)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1a23540d91f87584a04f184304a00648", "", "", "Race Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1a613ce60fc834d4970e1e674b9196b3", "Home Vision - Gem International Corp. - VDI", "VCS83135", "Tanks War (1983) (Home Vision) (PAL)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1a624e236526c4c8f31175e9c89b2a22", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL) [a]", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1a8204a2bcd793f539168773d9ad6230", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) [no initials]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1aa7344b563c597eecfbfcf8e7093c27", "David Marli", "", "Slot Invaders (David Marli) (Hack)", "Hack of Slot Machine", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1b0f3d7af668eeea38ddd6182d8f48fb", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1b1daaa9aa5cded3d633bfcbeb06479c", "", "", "Ship Demo (V 1502) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1b22a3d79ddd79335b69c94dd9b3e44e", "Tron", "", "Moon Patrol (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1b4b06c2a14ed3ee73b7d0fd61b6aaf5", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1b5a8da0622bffcee4c5b42aed4e0ef0", "Akor", "", "TV Boy II (1992) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "1b8c3c0bfb815b2a1010bba95998b66e", "Telegames", "", "Frogs and Flies (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1b8d35d93697450ea26ebf7ff17bd4d1", "Quelle - Otto Versand", "176.764 9 - 781644", "Marineflieger (1983) (Quelle) (PAL)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1bb91bae919ddbd655fa25c54ea6f532", "Suntek", "SS-026", "Treasure Island (1983) (Suntek) (PAL)", "AKA Treasure Discovery", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1bc2427ac9b032a52fe527c7b26ce22c", "Intellivision Productions - M Network - APh Technological Consulting, Bruce Pedersen, Larry Zwick", "MT5860", "Sea Battle (1983) (M Network)", "High Seas", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1bef389e3dd2d4ca4f2f60d42c932509", "Dimax - Sinmax", "SM8001", "Space Robot (1983) (Dimax - Sinmax) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1bf503c724001b09be79c515ecfcbd03", "", "", "Bumper Bash (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1bfae770e089fa81412d04eb299f4c3f", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (NTSC) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1c3f3133a3e5b023c77ecba94fd65995", "CCE", "C-830", "Planet Patrol (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1c5796d277d9e4df3f6648f7012884c4", "Rainbow Vision - Suntek", "SS-012", "Hey! Stop! (1983) (Rainbow Vision) (PAL)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1c666ba5aac19b81671357e76062989b", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL60) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1c6eb740d3c485766cade566abab8208", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1c85c0fc480bbd69dc301591b6ecb422", "CCE", "", "Super Box (CCE)", "AKA RealSports Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1c8c42d1aee5010b30e7f1992d69216e", "PlayAround - J.H.M.", "205", "Gigolo (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1cad3b56cc0e6e858554e46d08952861", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1cafa9f3f9a2fce4af6e4b85a2bbd254", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "1cca2197d95c5a41f2add49a13738055", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "1cf59fc7b11cdbcefe931e41641772f6", "SEGA", "005-01", "Buck Rogers - Planet of Zoom (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1d1d2603ec139867c1d1f5ddf83093f1", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari) (4K)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1d284d6a3f850bafb25635a12b316f3d", "CCE", "", "H.E.R.O. (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1d2a28eb8c95da0d6d6b18294211839f", "", "", "Fishing Derby (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1d4e0a034ad1275bc4d75165ae236105", "20th Century Fox Video Games, Mark Klein", "11034", "Pick Up (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1d5eac85e67b8cff1377c8dba1136929", "", "", "Chronocolor Donkey Kong Sideways (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1d6ed6fe9dfbde32708e8353548cbb80", "Jone Yuan Telephonic Enterprise Co", "", "Super Challenge Baseball (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1d72cc6ee466a4af1b27587b900ed430", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1da2da7974d2ca73a823523f82f517b3", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1db3bc4601f22cf43be7ce015d74f59a", "", "", "Ship Demo (V 10) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1e060a8025512ad2127e3da11e212ccc", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (3 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1e0ef01e330e5b91387f75f700ccaf8f", "Quelle - Otto Versand", "686.561 2 - 781627", "Mein Weg (1983) (Quelle) (PAL)", "AKA Challenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1e1290ea102e12d7ac52820961457e2b", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-15-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1e272d09c0e55f5ef14fcb76a735f6d7", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1e31b3a48865ba98d4d1aa5205115983", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1e587ca91518a47753a28217cd4fd586", "Telesys, Jim Rupp, Jack Woodman", "1001", "Coco Nuts (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1e750000af77cc76232f4d040f4ab060", "Jone Yuan Telephonic Enterprise Co", "", "Raft Rider (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1e85f8bccb4b866d4daa9fcf89306474", "Atari, Lou Harp", "CX26122", "Sinistar (02-13-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1e89f722494608d6ea15a00d99f81337", "", "", "River Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" }, - { "1ea1abcd2d3d3d628f59a99a9d41b13b", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1ea980574416bfd504f62575ba524005", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1ec57bbd27bdbd08b60c391c4895c1cf", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (09-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1ec5bef77b91e59313cba205f15b06d7", "", "", "Overhead Adventure Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1ede4f365ce1386d58f121b15a775e24", "Parker Brothers, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1ee2cfc7d0333b96bd11f7f3ec8ce8bc", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1ee9c1ba95cef2cf987d63f176c54ac3", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1ef04e7e508296a8d9eb61cc7dae2e5d", "SOLID Corp. (D. Scott Williamson)", "CX2655-069", "Star Castle 2600 (SolidCorp) [069]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1f21666b8f78b65051b7a609f1d48608", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1f2ae0c70a04c980c838c2cdc412cf45", "Atari - GCC", "CX2698", "Rubik's Cube (1984) (Atari)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1f349dd41c3f93c4214e5e308dccb056", "", "", "Virtual Pet Demo 2 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1f40eefc7447336ae6cd8ffa5eb325be", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1f562b89d081e36d58e6fc943512ec05", "", "", "Hangman Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1f5a2927a0b2faf87540b01d9d7d7fd1", "Pet Boat", "", "Tennis (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1f60e48ad98b659a05ce0c1a8e999ad9", "", "", "Mondo Pong V2 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "01", "", "", "", "" }, - { "1f773a94d919b2a3c647172bbb97f6b4", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (07-11-1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1fa58679d4a39052bd9db059e8cda4ad", "Imagic, Dan Oliver", "720118-1A, 03208", "Laser Gates (1983) (Imagic)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1fa7a42c2c7d6b7a0c6a05d38c7508f4", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-04-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "1fa86282403fa35d103ab88a9d603c31", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare) (PAL60)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "1fab68fd67fe5a86b2c0a9227a59bb95", "20th Century Fox Video Games - Videa, Lee Actor", "", "Lasercade (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "200309c8fba0f248c13751ed4fc69bab", "Jeffry Johnston", "", "Radial Pong - Version 1 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2008c76deba5953201ef75a09b2ff7dc", "", "", "Fortress (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "200a9d2a7cb4441ce4f002df6aa47e38", "", "", "Doomzerk (PD) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2016726db38ad6a68b4c48ba6fe51557", "Piero Cavina, Erik Mooney", "", "INV 2 (Piero Cavina, Erik Mooney)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "203049f4d8290bb4521cc4402415e737", "Tigervision, Robert H. O'Neil - Teldec", "7-007 - 3.60005 VG", "Polaris (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "203abb713c00b0884206dcc656caa48f", "Imagic, Bob Smith", "720114-1A, 03207, IZ-001-04", "Moonsweeper (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "203b1efc6101d4b9d83bb6cc1c71f67f", "Quelle", "685.996 1", "Teller-Jonglieren! (1983) (Quelle) (PAL)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "205070b6a0d454961dd9196a8e81d877", "", "", "Hangman Monkey Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2058cf3fefad4d2bc03ed817cedddcd4", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2091af29b4e7b86914d79d9aaa4cbd20", "CBS Electronics - Woodside Design Associates, Harley H. Puthuff Jr.", "4L1802", "Donkey Kong Junior (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "20ae62fb69c6cc6e8098cca8cd080487", "Zirok", "", "Tennis (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "20d4457ba22517253fcb62967af11b37", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "20dca534b997bf607d658e77fbb3c0ee", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1002", "Fire Fly (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "20edcc3aa6c189259fa7e2f044a99c49", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "211774f4c5739042618be8ff67351177", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "211f76dff0b7dad3f6fcac9d938ee61a", "JSK", "", "Custer's Viagra (JSK) (Hack) [a]", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "211fbbdbbca1102dc5b43dc8157c09b3", "Apollo", "AP-2009", "Final Approach (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2124cf92978c46684b6c39ccc2e33713", "", "", "Sea Monster (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "21299c8c3ac1d54f8289d88702a738fd", "K-Tel Vision", "", "Spider Maze (1982) (K-Tel Vision)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "212d0b200ed8b45d8795ad899734d7d7", "Atari, Richard Maurer, Christopher H. Omarzu - Coca Cola", "", "Pepsi Invaders (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "213e5e82ecb42af237cfed8612c128ac", "Sancho - Tang's Electronic Co.", "TEC006", "Forest (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2162266b906c939b35c84ff9a0f50ad1", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "2179dfd7edee76efafe698c1bc763735", "", "", "Yellow Submarine (Cody Pittman) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "217b1452881264ac75126bf77b8d0db8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "218b76f5a4142dc2ea9051a768583d70", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "218c0fe53dfaaa37f3c823f66eafd3fc", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "21a96301bb0df27fde2e7eefa49e0397", "Data Age", "DA1003", "Sssnake (1982) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "21b09c40295c2d7074a83ae040f22edf", "", "", "Marble Craze (V0.90) (Easy Version) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "21d2c435bcccde7792d82844b3cf60f4", "Atari - GCC, Doug Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "21d7334e406c2407e69dbddd7cec3583", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2228c67d25e507603d4873d3934f0757", "", "", "Fu Kung! (V0.10) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "22319be7a640af5314ec3c482cceb676", "", "", "Joustpong (05-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2240655247d6de1c585564004a853ab7", "", "", "Fu Kung! (V0.17) (07-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "225522777dc7155627808bde0c1d0ef0", "", "", "This Planet Sucks Demo 1 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "22675cacd9b71dea21800cbf8597f000", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "227532d82505c3c185a878273c285d5f", "", "", "Hangman Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "22abbdcb094d014388d529352abe9b4b", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype) [a]", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "22b22c4ce240303012e8a9596ae8d189", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "22f6b40fc82110d68e50a1208ae0bb97", "", "", "Purple Bar Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2319922df4d0c820b3e5f15faa870cc3", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2327456f86d7e0deda94758c518d05b3", "Digitel", "", "Mr. Postman (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2351d26d0bfdee3095bec9c05cbcf7b0", "", "", "Warring Worms (19-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2353725ec98e0f0073462109e886efd7", "Champ Games", "CG-03-P", "Scramble (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "235436ab0832370e73677c9c6f0c8b06", "", "", "Beast Invaders (Double Shot) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2365e1534d67f94d8670394ab99150ce", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "ATARIMOUSE", "", "", "", "", "", "", "YES", "" }, - { "23d445ea19a18fb78d5035878d9fb649", "CBS Electronics - JWDA, Sylvia Day, Todd Marshall, Henry Will IV", "4L1818, 4L1819, 4L1820, 4L1821", "Mouse Trap (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "23e4ca038aba11982e1694559f3be10f", "", "", "Big Dig (V3) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "23fad5a125bcd4463701c8ad8a0043a9", "CCE", "C-840", "Stone Age (1983) (CCE)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "A", "A", "", "YES", "", "", "", "", "", "", "", "", "YES", "" }, - { "240bfbac5163af4df5ae713985386f92", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2432f33fd278dea5fe6ae94073627fcc", "CBS Electronics, Tom DiDomenico", "4L2477, 4L2482, 4L2485, 4L4171", "Blueprint (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2434102f30eeb47792cf0825e368229b", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24385ba7f5109fbe76aadc0a375de573", "CCE", "", "Xevious (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2447e17a4e18e6b609de498fe4ab52ba", "CCE", "", "Super Futebol (CCE)", "AKA RealSports Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "244c6de27faff527886fc7699a41c3be", "", "", "Matt Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2450dfa1df70d12b60683185775efed8", "Jeffry Johnston", "", "Radial Pong - Version 7 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24544ee5d76f579992d9522e9b238955", "Carrere Video - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper - Teldec - Prism", "USC2004", "Picnic (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "245f07c8603077a0caf5f83ee6cf8b43", "Home Vision - Thomas Jentzsch", "", "Parachute (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24759be31e8fe55d2829fd86bdf3181f", "Hozer Video Games", "", "Gunfight 2600 - Worst Nightmare... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "247fa1a29ad90e64069ee13d96fea6d6", "CCE", "C-867", "Radar (1983) (CCE)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "248668b364514de590382a7eda2c9834", "CBS Electronics, Richard K. Balaska Jr., Bob Curtiss, Alex Leavens, Alex Nevelson", "", "Kick-Man (01-08-82) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2496d404bfc561a40a80bea6a69695c3", "CCE", "C-1007", "Jungle Hunt (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24ad538291eb5f5cac4b9998f3b851c3", "", "", "Gunfight 2600 - This time it's your decission! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24aff972d58990f9b88a6d787c796f1e", "CBS Electronics", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf (1982) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24b5f4bbdb853eca38ea0cae2dfe73a1", "", "", "Home Run (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "24b9adac1b4f85b0bac9bf9b9e180906", "Angelino", "", "Space 2002 (Angelino) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24d018c4a6de7e5bd19a36f2b879b335", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "24d9a55d8f0633e886a1b33ee1e0e797", "Thomas Jentzsch", "", "Dragon Defender (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "24df052902aa9de21c2b2525eb84a255", "Imagic, Dennis Koble", "720000-100, 720100-1B, IA3000, IA3000C", "Trick Shot (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "24fbf8250a71611e40ef18552e61b009", "", "", "Movable Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2516f4f4b811ede4ecf6fbeb5d54a299", "Quelle", "701.134 9", "Schiessbude (1983) (Quelle) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2517827950fee41a3b9de60275c8aa6a", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25265d0e7f88b3026003809f25ee025e", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25472dfdeef6a42581a231d631d6b04d", "", "", "Gunfight 2600 - Design thoughts (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25710bde8fa181b0c5cf0846b983bec1", "", "", "Demo Image Series #15 - Three Marios (NTSC) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "257bc3b72a6b5db3fd0d47619125b387", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) [a]", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "", "", "", "BOOSTERGRIP", "BOOSTERGRIP", "", "", "", "", "", "", "", "" }, - { "25a21c47afe925a3ca0806876a2b4f3f", "Quelle", "685.640 5", "Der kleine Baer (1983) (Quelle) (PAL)", "AKA Frostbite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25b52bf8dd215bcbd59c9abdb55c44f8", "Atari - GCC, Betty Ryan Tylko, Doug Macrae", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25b6dc012cdba63704ea9535c6987beb", "Avalon Hill, Jean Baer, Bill Hood", "5004002", "Shuttle Orbiter (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25bb080457351be724aac8a02021aa92", "CBS Electronics", "4L1784, 4L1786, 4L1787, 4L2277", "Zaxxon (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25d4be3309b89583c6b39d9f93bf654f", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25e73efb9a6edf119114718bd2f646ba", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25f2e760cd7f56b88aac88d63757d41b", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25f879ff678130fea615ac418e7943f1", "Activision, Garry Kitchen", "EAX-025", "Keystone Kapers (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "25f9cf703575c5d63048c222f5463758", "", "", "Multi-Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "260c787e8925bf3649c8aeae5b97dcc0", "Thomas Jentzsch", "", "Hell Driver (Thomas Jentzsch)", "NTSC Conversion, joystick ports swapped", "Homebrew", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "262ccb882ff617d9b4b51f24aee02cbe", "Atari, Douglas Neubauer", "CX26154, CX26154P", "Super Football (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "265a85f66544eaf95fda06c3d9e48abf", "", "", "Tunnel Demo (Cycling Colours) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "265c74a956500bd31efd24adc6d5ccf6", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2683d29a282dd059535ac3bb250f540d", "", "", "Space Treat (12-01-2003) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "268f46038e29301568fa9e443e16e960", "Atarius Maximum", "", "Pitfall Unlimited (Atarius Maximus) (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "26bc2bdf447a17376aea7ef187ff6e44", "", "", "Amanda Invaders (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "26f4f8b098609164effef7809e0121e1", "", "", "Oystron (V2.7) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "270229c6d5578446e6a588492e4e5910", "", "", "Space Invaders 2 (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2712e91f6f1dc55e90e2b14b27c042ac", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "271bfd5dc2673d382019f1fb6cab9332", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "273ce50db5a0d6da7ea827a54f44dee9", "", "", "Island Flyer Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "274d17ccd825ef9c728d68394b4569d2", "Playaround - J.H.M.", "202", "Bachelorette Party (1982) (Playaround)", "AKA Bachelor Party, Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "AUTO 65", "", "", "YES", "" }, - { "277c7281ac945b8331e2e6fcad560c11", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "277cca62014fceebb46c549bac25a2e3", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "277fa4b9a6bb7a8dcea2c5f38a4c25f0", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari) (Prototype)", "AKA Football II", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "278155fc9956e9b6ef2359eb238f7c7f", "", "", "Donkey Kong Junior (Unknown) (Hack)", "Hack of Donkey Kong Junior", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2783006ee6519f15cbc96adae031c9a9", "Telegames", "", "Night Stalker (1989) (Telegames) (PAL) [a]", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "278531cc31915747018d22145823d2c9", "", "", "Defender MegaDrive (PAL) (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "278f14887d601b5e5b620f1870bc09f6", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "27a5d2d0c74c8e4b2c05b94c9f098eea", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL60) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "27baecd618e7e53dc11f2a9c559f529d", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "27c4c2af4b46394bb98638af8e0f6e9d", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "27c6a2ca16ad7d814626ceea62fa8fb4", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "27f9e2e1b92af9dc17c6155605c38e49", "CCE", "", "Nightmare (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2808dc745ff4321dc5c8122abef6711f", "Retroactive", "", "Qb (2.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "28148a52b1955ce12c7a74d3a3e620a4", "CCE", "", "Freeway (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "281ff9bd0470643853de5cbd6d9e17f5", "Eckhard Stolberg", "", "Cubis (EM) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2823364702595feea24a3fbee138a243", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp) (PAL)", "AKA Bobby geht Heim", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2825f4d068feba6973e61c84649489fe", "", "", "Boom Bang (Unknown) (PAL)", "AKA Crackpots", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "282a77841cb3d33af5b56151acba770e", "Otto Versand", "311388", "Black Hole (1983) (Otto Versand) (PAL)", "AKA Cosmic Ark (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "283cb03ee031c842beabdad1aa4e7dbc", "Bit Corporation", "R320", "Demon Attack (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "283dee88f295834c4c077d788f151125", "Retroactive", "", "Qb (2.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "284ca61b2407bdba3938048b0a559015", "Atari, Tod Frye", "CX2695", "Xevious (05-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2854e5dfb84173fafc5bf485c3e69d5a", "Canal 3 - Intellivision", "C 3004", "Moon Patrol (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2880c6b59bd54b153174676e465167c7", "Tron", "", "Donkey Kong Jr. (Tron)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "28a2bea8f84936cb2e063f857414cda0", "Thiago Paiva", "", "Mega Mania Raid (1999) (Thiago Paiva) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "28a4cd87fb9de4ee91693a38611cb53c", "", "", "Skeleton (V1.1) (NTSC) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "28d5df3ed036ed63d33a31d0d8b85c47", "Bit Corporation", "PG204", "Open, Sesame! (1983) (BitCorp) (PAL)", "AKA Sesam, Offne Dich", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2903896d88a341511586d69fcfc20f7d", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "291bcdb05f2b37cdf9452d2bf08e0321", "Atari", "CX26163P", "32 in 1 Game Cartridge (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "291cc37604bc899e8e065c30153fc4b9", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "291dd47588b9158beebe4accc3a093a6", "Atari", "", "32 in 1 Console ROM (02-10-1989) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "292a0bb975b2587f9ac784c960e1b453", "", "", "Qb (05-02-2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "292f2446a0325b7b423e88a2ebfeb5a0", "", "", "Cube Conquest (Non Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "29396db58406084e416032c372734a3e", "", "", "Gunfight 2600 - Fixed Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2942680c47beb9bf713a910706ffabfe", "", "", "Blue Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "294762000e853b4319f9991c1ced5dfc", "", "", "T.F. Space Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "295f3679bdf91ca5e37da3f787b29997", "", "", "Exorcise (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "29630a20d356fb58685b150bfa8f00c3", "M Network, Kevin Miller", "MT5687", "International Soccer (1982) (Mattel) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "297236cb9156be35679f83c4e38ee169", "Exus Corporation", "", "Video Reflex (1983) (Exus) [no roman numbers]", "AKA Foot Craz (no roman numbers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "297c405afd01f3ac48cdb67b00d273fe", "Atari - GCC, Ava-Robin Cohen", "CX26123, CX26123P", "Jr. Pac-Man (1986) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2982e655dffc89d218a0a3072cfc6811", "", "", "Mini Golf 812631 (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "298387b0637173d2002770a649b4fbca", "", "", "S.I.PLIX 2 (Hack) [a]", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "29843f43b81f3736bf35c00b1bb88fb2", "Gray Games & AtariAge", "", "E.T. Book Cart (NTSC)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" }, - { "29949f893ef6cb9e8ecb368b9e99eee4", "Erik Eid", "", "Euchre (Alpha) (NTSC) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "29dfa26b7988af9984d617708e4fc6e2", "", "", "Boulderdash Demo (05-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2a0ba55e56e7a596146fa729acf0e109", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2a10053fd08664c7cfbbb104386ed77f", "", "", "Alpha Demo - The Beta Demo (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2a1b454a5c3832b0240111e7fd73de8a", "Tigervision, Bill Hogue", "7-011", "Miner 2049er Volume II (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2a2f46b3f4000495239cbdad70f17c59", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2a33e21447bf9e13dcfed85077ff6b40", "", "", "Backwards Cannonball v2 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2a360bc85bf22de438651cf92ffda1de", "Bit Corporation", "PGP213", "Spy Vs. Spy (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2a9f9001540c55a302befd8e9d54b47b", "Atari, Dan Hitchens", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2aa5e56d36c2e58b6f2856109f2099a9", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2aba6a1b01a5859e96d6a66d2286772f", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2abc3d46b3f2140160759e2e10bc86d9", "", "", "Gunfight 2600 - Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2ac3a08cfbf1942ba169c3e9e6c47e09", "Activision, Dan Kitchen", "EAK-046-04B", "Fighter Pilot (1988) (Activision) (PAL)", "AKA Tomcat - The F-14 Fighter Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2ae700c9dba843a68dfdca40d7d86bd6", "TechnoVision - Thomas Jentzsch", "", "Pharaoh's Curse (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2aeedcc6eb1602efb77161b0cef832ab", "SOLID Corp. (D. Scott Williamson)", "CX2655-025", "Star Castle 2600 (SolidCorp) [025]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2b1589c7e1f394ae6a1c046944f06688", "Carrere Video - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC2003", "Eggomania (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, - { "2b27eb194e13f3b38d23c879cc1e3abf", "Quelle", "402.272 9", "Super-Ferrari (1983) (Quelle) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2b42da79a682ed6e2d735facbf70107e", "", "", "DKjr Improved (Hack)", "Hack of Donkey Kong Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2b430c00dc79e495762ac59b2f9b4fcd", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2b71a59a53be5883399917bf582b7772", "Greg Troutman", "", "Dark Mage (final beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2ba02f509a4991aa176ba8d9e540df3d", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2bb0a1f1dee5226de648eb5f1c97f067", "Robby", "", "Enduro (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2bb9f4686f7e08c5fcc69ec1a1c66fe7", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2bc26619e31710a9884c110d8430c1da", "Atari, Bob Whitehead", "CX2652, CX2652P", "Casino (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "2bc6c53b19e0097a242f22375a6a60ff", "", "", "Droid Demo 2 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2bee7f226d506c217163bad4ab1768c0", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2bf34b6ad7d2317a2d0808b3fb93571b", "", "", "Easy Playfield Graphics (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c0dc885d5ede94aa664bf3081add34e", "", "", "Earth Dies Screaming, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c29182edf0965a7f56fe0897d2f84ba", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (08-18-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c2aea31b01c6126c1a43e10cacbfd58", "Paul Slocum", "", "Synthcart (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2c3b2843295c9d6b16996971180a3fe9", "HES - Activision", "", "Sports Action Pak - Enduro, Ice Hockey, Fishing Derby, Dragster (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c3b9c171e214e9e46bbaa12bdf8977e", "Bit Corporation", "R320", "Othello (32 in 1) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c45c3eb819a797237820a1816c532eb", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c8835aed7f52a0da9ade5226ee5aa75", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c8c11295d8613f875b7bcf5253ab9bb", "Fabrizio Zavagli", "", "Kool Aid Man (PAL Conversion) (16-11-2002) (Fabrizio Zavagli) (PAL60)", "PAL60 Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2c9fadd510509cc7f28f1ccba931855f", "", "", "Hangman Invader Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2ca6445204ffb7686ddee3e33ba64d5b", "Alex Herbert", "", "AtariVox Test ROM", "Uses the AtariVox controller", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "" }, - { "2cb42cf62b2f25f59f909b5447821b14", "Atari, Christopher H. Omarzu - Children's Computer Workshop", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "2cc3049b7feb8e92f1870f1972629757", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype) [stack pointer fix]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2cccc079c15e9af94246f867ffc7e9bf", "PlayAround - J.H.M.", "203", "Jungle Fever (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2cefa695df2ed020899a7df7bb1e3a95", "Manuel Polik, Fabrizio Zavagli", "", "A-Team (2002) (Manuel Polik) (Hack)", "Hack of A-Team", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2cf20f82abcae2decff88db99331e071", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2cfb188c1091cc7ec2a7e60064d2a758", "", "", "Space Invaders Hack Demo (2003) (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d15b092e8350912ec4b2e5e750fa1c6", "Wizard Video Games, Bob Davis, Robert H. O'Neil", "", "Texas Chainsaw Massacre, The (1982) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d16a8b59a225ea551667be45f554652", "Quelle", "802.744 3", "Der Geheimkurier (1983) (Quelle) (PAL)", "AKA Mr. Postman", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d1cf85fbc732856bf76470cd4060f4a", "", "", "Daredevil (V1) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d2c5f0761e609e3c5228766f446f7f8", "Atari - Axlon, Steve DeFrisco", "CX26170, CX26170P", "Secret Quest (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d33a44e82f88d05f6c50577218c0cae", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d38a96f92952b301eefdf25a5e6976b", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y_Inverted) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d405da70af82b20a6b3ecc3d1d2c4ec", "Genus", "", "Pitfall (Genus)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d6388a8389f1d59108fd169c3356d79", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d63b452f897818c52b3fceeb080a4d0", "HES - Absolute Entertainment", "", "Pete Rose Baseball (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d6741cda3000230f6bbdd5e31941c01", "CBS Electronics - VSS", "80110", "Targ (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d69a5f23784f1c2230143292a073b53", "", "", "Qb (Fixed background animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2d6da0eb85eabc93270e5bb8a466ca51", "", "", "Sprite Demo 7 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d76c5d1aad506442b9e9fb67765e051", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo) [no opening scene]", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d9e5d8d083b6367eda880e80dfdfaeb", "QDI, Mike Montana, Rich Montana - Selchow & Righter", "87", "Glib (1983) (QDI)", "AKA Video Word Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2d9e65959808a6098c16c82a59c9d9dc", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2dbc92688f9ba92a7e086d62be9df79d", "", "", "How to Draw a Playfield (1997) (Jim Crawford) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2dbdca3058035d2b40c734dcf06a86d9", "Thomas Jentzsch", "", "Asteroids DC+ (Thomas Jentzsch) (Hack)", "Uses the Joystick (left) or Driving (right) Controller", "Hack", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "58", "", "", "YES", "" }, - { "2dcf9ce486393cd36ca0928cd53b96cb", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2de41a11c6767e54a5ee9ebaffec72af", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL60)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" }, - { "2dfec1615c49501fefc02165c81955e6", "", "", "Song (05-11-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2e0aed5bb619edcefa3fafb4fbe7c551", "", "", "Qb (2.06) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2e2acef8513edcca991e7e5149412e11", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2e3728f3086dc3e71047ffd6b2d9f015", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2e5b184da8a27c4d362b5a81f0b4a68f", "Atari", "", "Rabbit Transit (08-29-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2e663eaa0d6b723b645e643750b942fd", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2e7e9c6dcfcceaffc6fa73f0d08a402a", "CCE", "C-818", "Star Voyager (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2e82a1628ef6c735c0ab8fa92927e9b0", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2e842c2ee22e9dad9df16eed091315c4", "HES", "701-157", "2 Pak Special - Moto-cross, Boom Bang (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2eaf8fa9e9fdf1fcfc896926a4bdbf85", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 39 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2ec6b045cfd7bc52d9cdfd1b1447d1e5", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2eda6a49a49fcb2b674ea9e160b6a617", "Kyle Pittman", "", "Rambo in Afghanistan (Kyle Pittman) (Hack)", "Hack of Riddle of the Sphinx", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2ef36341d1bf42e02c7ea2f71e024982", "", "", "Space Invaders (Explosion Hack)", "Hack of Space Invaders (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2f0546c4d238551c7d64d884b618100c", "SEGA, Jeff Lorenz", "", "Ixion (1984) (SEGA) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2f0a8bb4e18839f9b1dcaa2f5d02fd1d", "CCE", "", "Super Futebol (CCE) [a]", "AKA RealSports Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2f11ba54609777e2c6a5da9b302c98e8", "Atari - GCC", "CX2676", "Centipede (1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2f16663b01591539624d0ef52934a17d", "M Network", "", "Rocky and Bullwinkle", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2f2f9061398a74c80420b99ddecf6448", "Rentacom - Brazil", "", "Bobby Is Going Home (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2f66ebf037321ed0442ac4b89ce22633", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 2) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2f7772879a1ed04f660aa9d77a86a4bd", "", "", "Yars' Revenge (Genesis)", "Genesis controller (C is zorlon cannon)", "Hack of Yars' Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "2f77f015fc880b05f28e84156f989a0c", "", "", "Plane Demo (Gonzalo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2f7949f71076db42480d3f5036b4a332", "", "", "Name This Game (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "2facd460a6828e0e476d3ac4b8c5f4f7", "Sancho - Tang's Electronic Co.", "", "Words-Attack (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3025bdc30b5aec9fb40668787f67d24c", "", "", "Demo Image Series #14 - Two Marios (4K Interleaved Chronocolour Vertical Movement) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "303242c239474f2d7763b843de58c1c3", "CCE", "", "Laser Blast (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "304512528a5530a9361e8a231ed9a6de", "Thomas Jentzsch", "", "River Raid Plus (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "30512e0e83903fc05541d2f6a6a62654", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari)", "AKA Capture the Flag", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "30516cfbaa1bc3b5335ee53ad811f17a", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3051b6071cb26377cd428af155e1bfc4", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "10", "", "", "", "" }, - { "30685b9b6ebd9ba71536dd7632a1e3b6", "Dactari - Milmar", "", "Tennis (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3091af0ef1a61e801f4867783c21d45c", "CCE", "C-862", "Crackpots (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "30997031b668e37168d4d0e299ccc46f", "", "", "John K Harvey's Equalizer (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "30c92c685224dc7a72b9bbe5eb62d004", "", "", "Hangman Monkey Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "30e012e8d50330c8972f126b8e913bc4", "", "", "Indy 500 (Hack) [a2]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "", "", "", "", "" }, - { "30e0ab8be713208ae9a978b34e9e8e8c", "Atari, Mike Lorenzen", "CX2630, CX2630P", "Circus Atari (1980) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, - { "30f0b49661cfcfd4ec63395fab837dc3", "SEGA, Jeff Lorenz - Teldec", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3105967f7222cc36a5ac6e5f6e89a0b4", "SEGA, Jeff Lorenz", "011-01, 011-02", "Spy Hunter (1984) (SEGA)", "Uses Joystick Coupler (Dual Control Module)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "310ba30e25ea8957e58180b663503c0c", "Ed Federmeyer", "", "Sound X6 (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31235a27b065c2863048fa84db330dc6", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "313243fc41e49ef6bd3aa9ebc0d372dd", "", "", "Fast Food (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31512cdfadfd82bfb6f196e3b0fd83cd", "Tigervision", "7-004", "River Patrol (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3177cc5c04c1a4080a927dfa4099482b", "Atari - Imagineering, Alex DeMeo", "CX26135", "RealSports Boxing (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "317a4cdbab090dcc996833d07cb40165", "Goliath - Hot Shot", "83-312", "Missile War (1983) (Goliath) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "318046ae3711c05fd16e479b298e5fcc", "Retroactive", "", "Qb (V2.08) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "318a9d6dda791268df92d72679914ac3", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "319a142aab6260842ab616382848c204", "", "", "Marble Craze (05-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31bb9b8ceed46cb3e506777a9e65f3ce", "Bit Corporation", "", "4 Game in One Light Green (1983) (BitCorp) (PAL)", "Phantom UFO, Ice Hockey, Cosmic Avenger, Spy Vs. Spy", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31c5fd55a39db5ff30a0da065f86c140", "Dactari - Milmar", "", "Enduro (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31d08cb465965f80d3541a57ec82c625", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31df1c50c4351e144c9a378adb8c10ba", "Quelle", "687.463 0", "Die Ratte und die Karotten (1983) (Quelle) (PAL)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31e518debba46df6226b535fa8bd2543", "Atari, Douglas 'Solaris' Neubauer, Mimi Nyden", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Solaris Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31f4692ee2ca07a7ce1f7a6a1dab4ac9", "Atari, Alan Miller", "CX2642", "Game of Concentration (1980) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "31fcbce1cfa6ec9f5b6de318e1f57647", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "32199271dc980eb31a2cc96e10a9e244", "", "", "Radial Pong - Version 12 (Jeffry Johnston) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "321c3451129357af42a375d12afd4450", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "32244e55ce6ec6bfbd763f33384bdc2e", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3225676f5c0c577aeccfaa7e6bedd765", "CCE", "C-1002", "Pole Position (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "322b29e84455aa41e7cc9af463bffa89", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (06-25-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "324cb4a749bcac4f3db9da842b85d2f7", "Dennis Debro", "", "Climber 5 (01-05-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "327468d6c19697e65ab702f06502c7ed", "Charles Morgan", "", "Aster-Hawk (2002) (Charles Morgan) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3276c777cbe97cdd2b4a63ffc16b7151", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3278158e5c1f7eb5c5d28ccfd7285250", "Dactari - Milmar", "", "Megamania (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "327fe8cf94f3a45c35a840a453df1235", "", "", "Spice Girls Rule Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "328949872e454181223a80389d03c122", "", "", "Home Run (Unknown) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "32ae78abbb5e677e2aabae5cc86cec29", "Atari, Christopher H. Omarzu, Courtney Granner", "CX26112", "Good Luck, Charlie Brown (04-18-1984) (Atari) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "32d1260ea682e1bb10850fa94c04ec5f", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "32dcd1b535f564ee38143a70a8146efe", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "32e65d1e4dfcbcd9b57fee72cafe074c", "", "", "Eckhard Stolberg's Scrolling Text Demo 3 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "32ecb5a652eb73d287e883eea751d99c", "Dactar - Milmar", "", "Bowling (Dactar - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "32f4e47a71601ab06cfb59e1c6a0b846", "Ed Federmeyer", "", "Sound X (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3316ee2f887e9cb9b54dd23c5b98c3e2", "", "", "Texas Golf (miniature Gold Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "331938989f0f33ca39c10af4c09ff640", "Zach Matley", "", "Combat - Tank AI (19-04-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "332f01fd18e99c6584f61aa45ee7791e", "", "", "X'Mission (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3347a6dd59049b15a38394aa2dafa585", "Parker Brothers - JWDA, Henry Will IV", "PB5760", "Montezuma's Revenge (1984) (Parker Bros)", "Featuring Panama Joe", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "335793736cbf6fc99c9359ed2a32a49d", "", "", "Analog Clock (V0.0) (20-01-2003) (AD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "335a7c5cfa6fee0f35f5824d1fa09aed", "SEGA - Beck-Tech, Steve Beck, Phat Ho - Teldec", "006-01 - 3.60105 VG", "Congo Bongo (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3367eeba3269aa04720abe6169767502", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "336ea20d38f98926919d4b4651d1a03f", "Omegamatrix", "", "Omega Race (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3391f7c4c656793f92299f4187e139f7", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a4]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "33cac5e767a534c95d292b04f439dc37", "Jone Yuan Telephonic Enterprise Co", "", "Tapeworm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "33d68c3cd74e5bc4cf0df3716c5848bc", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "33ed6dfac4b9ea2f81f778ceddbb4a75", "Activision", "", "River Raid (1982) (SpkSoft) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "340f546d59e72fb358c49ac2ca8482bb", "Sancho - Tang's Electronic Co.", "TEC003", "Skindiver (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "34340c8eecd1e557314789cc6477e650", "Joe Grand", "", "SCSIcide Pre-release 4 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "345488d3b014b684a181108f0ef823cb", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "345758747b893e4c9bdde8877de47788", "CBS Electronics, Joseph Biel", "4L1802, 4L1803, 4L1804, 4L2278", "Venture (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "345769d085113d57937198262af52298", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "346555779a2d51b48833463b5433472f", "Thomas Jentzsch", "", "Thrust (V0.1) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "348615ffa30fab3cec1441b5a76e9460", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL) [fixed]", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "34b269387fa1aa5a396636f5ecdd63dd", "", "", "Marble Craze (mc7_23) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "34c808ad6577dbfa46169b73171585a3", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype)", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "34ca2fcbc8ba4a0b544acd94991cfb50", "Atari, Robert C. Polaro", "", "Dukes of Hazzard (1980) (Atari) (Prototype) (4K)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "34e37eaffc0d34e05e40ed883f848b40", "Retroactive", "", "Qb (2.15) (Retroactive) (Stella)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "34f4b1d809aa705ace6e46b13253fd3b", "Aaron Bergstrom", "", "Nothern Alliance (Aaron Bergstrom) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "34fd4fcb40ff5babce67f8b806d5969c", "", "", "Boxing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "350e0f7b562ec5e457b3f5af013648db", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "35156407e54f67eb1f625450d5c093e1", "", "", "Mouse Trap (Genesis)", "Genesis controller (C changes to dog)", "Hack of Mouse Trap", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "35163b56f4a692a232ae96ad3e23310f", "Retroactive", "", "Qb (2.12) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3545eb3b8b1e7dc19f87d231ab0b1d4c", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3556e125681aea864e17b09f3f3b2a75", "", "", "Incoming (2 Player Demo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3576037c9281656655fa114a835be553", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3577e19714921912685bb0e32ddf943c", "TechnoVision - Video Technology", "TVS1003", "Pharaoh's Curse (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "35ae903dff7389755ad4a07f2fb7400c", "", "", "Colored Wall Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "35b10a248a7e67493ec43aeb9743538c", "Dor-x", "", "Defender (Dor-x) (Hack)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "35b43b54e83403bb3d71f519739a9549", "Parker Brothers, Dave Engman, Isabel Garret", "", "McDonald's (06-06-1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "35be55426c1fec32dfb503b4f0651572", "Men-A-Vision", "", "Air Raid (Men-A-Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "35fa32256982774a4f134c3347882dff", "Retroactive", "", "Qb (V0.05) (Macintosh) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "360ba640f6810ec902b01a09cc8ab556", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (06-15-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "360c0dcb11506e73bd0b77207c81bc62", "Digitel", "", "Enduro (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3619786f6a32efc1e4a262d5aca8a070", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3624e5568368929fabb55d7f9df1022e", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36306070f0c90a72461551a7a4f3a209", "U.S. Games Corporation - JWDA, Roger Booth, Sylvia Day, Ron Dubren, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC1007", "Name This Game (1983) (U.S. Games)", "AKA Octopussy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36547bc6faa5132b87504e18d088e1d7", "", "", "Cosmic Swarm (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "367411b78119299234772c08df10e134", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3685060707df27d4091ba0ea2dc4b059", "", "", "PezZerk - PezMan in Ghost Manor (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "368d88a6c071caba60b4f778615aae94", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36a701c60a9f9768d057bc2a83526a80", "", "", "Cube Conquest (Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "36b20c427975760cb9cf4a47e41369e4", "Coleco - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "2451", "Donkey Kong (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36c29ceee2c151b23a1ad7aa04bd529d", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1986) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36c31bb5daeb103f488c66de67ac5075", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" }, - { "36c993dc328933e4dd6374a8ffe224f4", "Gameworld, J. Ray Dettling", "133-007", "Bermuda Triangle (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36e47ed74968c365121eab60f48c6517", "Quelle", "343.373 7", "Master Builder (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36edef446ab4c2395666efc672b92ed0", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "36f9a953ebdd9a8be97ccf27a2041903", "", "", "Chinese Character Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "37252757a79dc5b174e3c03d6ea0bdcb", "", "", "Sky Diver (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "372bddf113d088bc572f94e98d8249f5", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb) (PAL)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "373b8a081acd98a895db0cb02df35673", "", "", "Demo Image Series #5 - Boofly (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3750f2375252b6a20e4628692e94e8b1", "Dismac", "", "Ases do Ar (Dismac)", "AKA Sky Jinks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "37527966823ee9243d34c7da8302774f", "", "", "Word Zapper (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "376944889dcfa96c73d3079f308e3d32", "Retroactive", "", "Qb (0.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3783f12821b88b08814da8adb1a9f220", "", "", "Mission Survive (PAL) (Genesis)", "Genesis controller (C is vertical fire)", "Hack of Mission Survive)", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "378a62af6e9c12a760795ff4fc939656", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "378c118b3bda502c73e76190ca089eef", "Atari, Alan Miller", "CX2662P", "Hangman (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "37ab3affc7987995784b59fcd3fcbd31", "", "", "Sprite Test (29-11-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "37b98344c8e0746c486caf5aaeec892a", "K-Tel Vision", "6", "Spider Maze (1982) (K-Tel Vision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "37e828675d556775ae8285c0caf7d11c", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby) (Genesis)", "Genesis controller (C throws cookie)", "New Release", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" }, - { "37f42ab50018497114f6b0f4f01aa9a1", "", "", "Droid Demo 2-M (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "37fd7fa52d358f66984948999f1213c5", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a2]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "384db97670817103dd8c0bbdef132445", "Atari - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "384f5fbf57b5e92ed708935ebf8a8610", "20th Century Fox Video Games, John W.S. Marvin", "11009", "Crypts of Chaos (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3856b9425cc0185ed770376a62af0282", "Kyle Pittman", "", "Yellow Submarine (Kyle Pittman) (Hack)", "Hack of Bermuda Triangle", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "386ff28ac5e254ba1b1bac6916bcc93a", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "3882224adbd0ca7c748b2a1c9b87263e", "Atari, Tod Frye", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3889351c6c2100b9f3aef817a7e17a7a", "CCE", "", "Dolphin (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3897744dd3c756ea4b1542e5e181e02a", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (05-05-1983) (Atari) (Prototype)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "38bd172da8b2a3a176e517c213fcd5a6", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "38c362dcd5cad5a62e73ae52631bd9d8", "Jake Patterson", "", "Baubles (14-11-2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "38cf93eacfb2fa9a2c5e39059ff35a74", "Greg Zumwalt", "", "WacMan (2003) (Greg Zumwalt) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "38de7b68379770b9bd3f7bf000136eb0", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "391764720140c432aec454a468f77a40", "Video Game Program", "", "Miss Pack Man (Video Game Program) (PAL)", "AKA Ms. Pac-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "392d34c0498075dd58df0ce7cd491ea2", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "392f00fd1a074a3c15bc96b0a57d52a1", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, - { "393948436d1f4cc3192410bb918f9724", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "393e41ca8bdd35b52bf6256a968a9b89", "U.S. Games Corporation - Western Technologies, John Hall", "VC1012", "M.A.D. (1983) (U.S. Games)", "AKA Missile Intercept, Mutually Assured Destruction", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3947eb7305b0c904256cdbc5c5956c0f", "Jone Yuan Telephonic Enterprise Co", "", "Lilly Adventure (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "396f7bc90ab4fa4975f8c74abe4e81f0", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "3974e2d1f614fbd3a092533ecae2e84d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "39790a2e9030751d7db414e13f1b6960", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "39a6a5a2e1f6297cceaa48bb03af02e9", "", "", "Pitfall 2 Plus (Hack)", "Hack of Pitfall 2", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "39b94d41bd3b01c12b4054c1a8733783", "SOLID Corp. (D. Scott Williamson)", "CX2655-016", "Star Castle 2600 (SolidCorp) [016]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "39c78d682516d79130b379fa9deb8d1c", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "39d36366ae7e6dfd53393fb9ebab02a0", "CCE", "C-811", "River Raid (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "39da69ff9833f8c143f03b6e0e7a996b", "Charles Morgan", "", "Ventrra Invaders 2002 (Charles Morgan) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "39fe316952134b1277b6a81af8e05776", "Robby", "18", "River Raid (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3a10562937a766cbbb77203d029b00e1", "Carrere Video - JWDA, Garry Kitchen, Paul Willson - Teldec - Prism", "USC1002", "Sneak 'n Peek (1983) (Carrere Video) (PAL)", "AKA Der Unsichtbare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3a2e2d0c6892aa14544083dfb7762782", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3a35d7f1dc2a33565c8dca52baa86bc4", "", "", "Rubik's Cube Demo 2 (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3a51a6860848e36e6d06ffe01b71fb13", "Retroactive", "", "Qb (2.07) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3a521b7e29123b2d38e34e3ff8dc255c", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3a526e6a1f9fe918af0f2ce997dfea73", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3a53963f053b22599db6ac9686f7722f", "", "", "Word Zapper (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3a771876e4b61d42e3a3892ad885d889", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3aad0ef62885736a5b8c6ccac0dbe00c", "Dynacom", "", "Atlantis (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3ab5d138e26d88c8190e7cc629a89493", "", "", "Phased Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3ac6c50a8e62d4ce71595134cbd8035e", "Absolute Entertainment, Dan Kitchen", "AK-046-04", "Tomcat (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3ad3dc799211ccd424d7c6d454401436", "Probe 2000 - NAP", "", "Power Lords (1983) (Probe) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3ad58b53a1e972396890bd86c735e78d", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 36 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b040ed7d1ef8acb4efdeebebdaa2052", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b097a7ed5bd2a84dc3d3ed361e9c31c", "", "", "Interleaved ChronoColour Demo (PAL) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b10106836565e5db28c7823c0898fbb", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b2c32fcd331664d037952bcaa62df94", "Xonox", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b5751a8d20f7de41eb069f76fecd5d7", "", "", "Eckhard Stolberg's Scrolling Text Demo 4 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b64a00ce147c3c29f7f8f8e531d08d8", "", "", "This Planet Sucks (16K) (Greg Troutman)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b69f8929373598e1752f43f8da61aa4", "Apollo - Games by Apollo - RCA Video Jeux", "AP-2006", "Infiltrate (1921) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3b6dba1a24bb2893bd3bd0593f92016b", "CBS Electronics / Thomas Jentzsch", "", "Omega Race JS (TJ)", "Hack of Omega Race (CBS Electronics)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b76242691730b2dd22ec0ceab351bc6", "M Network - INTV, Connie Goldman, Joe King, Patricia Lewis Du Long, Gerald Moore, Mike Sanders, Jossef Wagner", "MT4319", "Masters of the Universe (1983) (M Network)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3b80b8f52a0939e16b5059f93a3fc19a", "V007", "", "Virtual Pet (V007) (after Demo 2) (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b86a27132fb74d9b35d4783605a1bcb", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b8aacf5f5638492b926b5124de19f18", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1981) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b91c347d8e6427edbe942a7a405290d", "Parker Brothers", "PB5350", "Sky Skipper (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b9480bb6fb1e358c9c0a64e86945aee", "", "", "Title Match Pro Wrestling (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3b966bf3c2ca34ac6ca1de4cf6383582", "", "", "Double-Height 6-Digit Score Display (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3bb9793c60c92911895cf44530846136", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c21a89bc38d8cd0b010a2916bcff5c2", "", "", "Colony 7 - CX-22 Hack v0.4 (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" }, - { "3c3a2bb776dec245c7d6678b5a56ac10", "", "", "Unknown Title (bin00003) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c4223316c835ceaad619651e25df0f9", "", "", "Defender (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c4a6f613ca8ba27ce9e43c6c92a3128", "", "", "Qb (V0.04) (Non-Lax Version) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3c57748c8286cf9e821ecd064f21aaa9", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c72ddaf41158fdd66e4f1cb90d4fd29", "Dismac", "", "Comando Suicida (Dismac)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c7a7b3a0a7e6319b2fa0f923ef6c9af", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c7a96978f52b2b15426cdd50f2c4048", "", "", "Overhead Adventure Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c82e808fe0e6a006dc0c4e714d36209", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3c853d864a1d5534ed0d4b325347f131", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3c8e57a246742fa5d59e517134c0b4e6", "Parker Brothers, Rex Bradford, Sam Kjellman", "PB5050", "Star Wars - The Empire Strikes Back (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3ca51b5c08f5a0ecfb17d0c1ec6d0942", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (09-28-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3caa902ac0ce4509308990645876426a", "Atari - GCC, Dave Payne", "CX2669, CX2669P", "Vanguard (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3cbdf71bb9fd261fbc433717f547d738", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE) (PAL)", "AKA Bobby Vai Para Casa", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3cdd91e1c28d28e856c0063d602da166", "", "", "Stell-A-Sketch (03-11-1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3d1e83afdb4265fa2fb84819c9cfd39c", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco)", "AKA Smurf, Smurf Action", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d2367b2b09c28f1659c082bb46a7334", "Imagic, Dennis Koble", "720103-2A, IA3203P, EIX-010-04I", "Atlantis (1982) (Imagic) (PAL)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d2652cbea462a886a41791dd7c8d073", "", "", "Ritorno dei frattelli di Mario (Mario Bros Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d48b8b586a09bdbf49f1a016bf4d29a", "Video Game Cartridge - Ariola", "TP-606", "Hole Hunter (Video Game Cartridge)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d6fc7a19be76d808aa233415cb583fc", "CCE", "C-833", "Target Practice (1983) (CCE)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d7749fb9c2f91a276dfe494495234c5", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d7aad37c55692814211c8b590a0334c", "Atari, Dan Oliver", "", "Telepathy (1983) (Atari) (Prototype)", "Uses both left joystick and right Mindlink controllers (press Fire on respective controller to begin)", "Prototype", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "78", "", "", "", "" }, - { "3d8a2d6493123a53ade45e3e2c5cafa0", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d934bb980e2e63e1ead3e7756928ccd", "Activision, Steve Cartwright - Ariola", "EAX-017, EAX-017-04I - 711 017-720", "MegaMania (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3d9c2fccf8b11630762ff00811c19277", "", "", "Challenge of.... Nexar, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3da7cc7049d73d34920bb73817bd05a9", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3dfb7c1803f937fadc652a3e95ff7dc6", "Dimax - Sinmax", "SM8001", "Space Robot (Dimax - Sinmax)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3e03086da53ecc29d855d8edf10962cb", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "4L1751, 4L1752, 4L1753, 4L2275", "Gorf (1982) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3e1682ddaec486d8b6b90b527aaa0fc4", "Thomas Jentzsch", "", "Robot City (V0.12) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3e22c7eaf6459b67388602e4bebbb3a8", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL) (4K)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3e33ac10dcf2dff014bc1decf8a9aea4", "Spectravideo - Video Games Industries Corporation, Michael Schwartz - Ralston Purina", "", "Chase the Chuckwagon (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3e49da621193d2611a4ea152d5d5ca3a", "", "", "Atari Logo Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3e4b1137433cc1e617b5508619e13063", "", "", "Asteroids (Genesis)", "Genesis controller (C is hyperspace)", "Hack of Asteroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3e5ca1afaa27c5da3c54c9942fec528b", "", "", "2600 Digital Clock (Demo 2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3e6dab92009d6034618cb6b7844c5216", "", "", "Ed Invaders (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3e7d10d0a911afc4b492d06c99863e65", "VGS", "", "Super Tenis (VGS)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3e88cca5b860d0bd8947479e74c44284", "Atari, Lou Harp", "CX26122", "Sinistar (01-23-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3e899eba0ca8cd2972da1ae5479b4f0d", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3e90cf23106f2e08b2781e41299de556", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3eae062a9b722bda1255d474a87eca5c", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3eb1e34a4f0eec36f12e7336badcecf2", "Jake Patterson", "", "Baubles (V0.001) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3eb21313ea5d5764c5ed9160a5a55a83", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3ec12372ca3e870b11ca70edc7ec26a4", "CommaVid, John Bronstein", "CM-002", "Video Life (1981) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3eccf9f363f5c5de0c8b174a535dc83b", "", "", "Plaque Attack (Unknown) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3ef9573536730dcd6d9c20b6822dbdc4", "Atari, Larry Wagner, Bob Whitehead", "CX2645, CX2645P", "Video Chess (1979) (Atari) (PAL)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f01bd6d059396f495a4cde7de0ab180", "", "", "Qb (Special Edition) (NTSC) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "3f039981255691d3859d04ef813a1264", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) [a]", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f251c50aa7237e61a38ab42315ebed4", "Thomas Jentzsch", "", "Ikari Warriors (1990) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f3ad2765c874ca13c015ca6a44a40a1", "CCE", "C-862", "Crackpots (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f540a30fdee0b20aed7288e4a5ea528", "Atari - GCC", "CX2670", "Atari Video Cube (1983) (Atari)", "AKA Atari Cube, Video Cube", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f58f972276d1e4e0e09582521ed7a5b", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f5a43602f960ede330cd2f43a25139e", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f6938aa6ce66e6f42e582c1eb19b18c", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f6dbf448f25e2bd06dea44248eb122d", "", "5687 A279", "Soccer (1988) (Telegames)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f75a5da3e40d486b21dfc1c8517adc0", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f9431cc8c5e2f220b2ac14bbc8231f4", "", "", "Colors Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f96eb711928a6fac667c04ecd41f59f", "Bit Corporation", "PGP218", "Rodeo Champ (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3f9cb1aba8ec20e2c243ae642f9942bf", "", "", "New Questions (1998) (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3fd1f9d66a418c9f787fc5799174ddb7", "Aaron Curtis", "", "AStar (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3fd53bfeee39064c945a769f17815a7f", "CCE", "", "Sea Hawk (CCE)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3fe43915e5655cf69485364e9f464097", "CCE", "C-863", "Fisher Price (1983) (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "3ff5165378213dab531ffa4f1a41ae45", "Otto Versand", "311377", "Pygmy (1983) (Otto Versand) (PAL)", "AKA Lock 'n' Chase (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4026ad38ba5ce486e88383dc27d7a46f", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "402b1ca3c230a60fb279d4a2a10fa677", "", "", "3-D Tic-Tac-Toe (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "402d876ec4a73f9e3133f8f7f7992a1e", "Alex Herbert", "", "Man Goes Down (2006) (A. Herbert) (Prototype)", "Uses AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "" }, - { "405f8591b6941cff56c9b392c2d5e4e5", "Telegames", "", "Star Strike (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4066309eb3fa3e7a725585b9814bc375", "", "", "Multi Ball Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4066d7d88ec4a2c656127a67fa52dcf1", "", "", "Overhead Adventure Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "407a0c6cc0ff777f67b669440d68a242", "Erik Eid", "", "Euchre (Alpha) (PAL) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4093382187f8387e6d011883e8ea519b", "", "", "Go Go Home (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "40aa851e8d0f1c555176a5e209a5fabb", "", "", "Euchre (More for less) (NTSC) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "40b1832177c63ebf81e6c5b61aaffd3a", "Atari, Peter C. Niday", "", "Rubik's Cube 3-D (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "40b59249e05135bca33861e383735e9e", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "40d8ed6a5106245aa79f05642a961485", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "40d9f5709877ecf3dd1184f9791dd35e", "Dactari - Milmar", "", "Skiing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "40e12c008037a323a1290c8fa4d2fe7f", "", "", "Skeleton (NTSC) (06-09-2002) (Eric Ball)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "40eb4e263581b3dfec6dd8920b68e00f", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Seawolf 3 (03-23-1981) (Sears) (Prototype) (PAL)", "Submarine Commander Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "413c925c5fdcea62842a63a4c671a5f2", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4153dd2beed648e9dc082140ebe8e836", "Thomas Jentzsch", "", "Coke Zero (v1.0) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "415c11fcac66bbd2ace2096687774b5a", "", "", "Fu Kung! (V0.00) (07-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4181087389a79c7f59611fb51c263137", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (06-24-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "41810dd94bd0de1110bedc5092bef5b0", "Funvision - Fund. International Co.", "", "Dragon Treasure (Funvision)", "AKA Dragonfire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "41818738ab1745e879024a17784d71f5", "CCE", "C-832", "Atlantis (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4189adfc1b30c121248876e3a1a3ac7e", "Eric Ball", "", "Skeleton (Complete) (06-09-2002) (Eric Ball)", "", "New Release", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4191b671bcd8237fc8e297b4947f2990", "Exus Corporation", "", "Video Jogger (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "41b554c6970b18670acc7b6baef8ed2e", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "41c4e3d45a06df9d21b7aae6ae7e9912", "CCE", "C-826", "Grand Prix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "41f252a66c6301f1e8ab3612c19bc5d4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (1983) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4209e9dcdf05614e290167a1c033cfd2", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid) [higher sounds]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "42249ec8043a9a0203dde0b5bb46d8c4", "CCE", "", "Resgate Espacial (CCE)", "AKA Moonsweeper", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4233eb824c2b4811abef9b6d00355ae9", "Retroactive", "", "Qb (V0.10) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4251b4557ea6953e88afb22a3a868724", "Thomas Jentzsch", "", "Robot City (V1.1) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "425ee444a41d218598893d6b6e03431a", "Thomas Jentzsch", "", "Invaders Demo (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4279485e922b34f127a88904b31ce9fa", "", "", "Enduro (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "428b2d36f5d716765460701f7016ac91", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "42ae81ae8ac51e5c238639f9f77d91ae", "", "", "Multi-Sprite Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "42b2c3b4545f1499a083cfbc4a3b7640", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC2003", "Eggomania (1982) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, - { "42b3ab3cf661929bdc77b621a8c37574", "Robby", "", "Volleyball (Robby)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "42b5e3a35b032f033809afb0ea28802d", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (03-12-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "42cdd6a9e42a3639e190722b8ea3fc51", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "42dcc02777b0bcfacd85aeb61d33558a", "", "", "Human Cannonball (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "42e0ec5ab8f5deba53e4169ff2a5efbe", "", "", "Atari Logo Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4311a4115fb7bc68477c96cf44cebacf", "", "", "Challenge (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4326edb70ff20d0ee5ba58fa5cb09d60", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "435fd469f088468c4d66be6b5204d887", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "438968a26b7cfe14a499f5bbbbf844db", "", "", "Raft Rider (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "43adf60ebdd6b5a0fae21594ecf17154", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "43c6cfffeddab6b3787357fed9d44529", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11111", "M.A.S.H (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "43f33c6dfdeaf5138ce6e6968ad7c5ce", "Jeffry Johnston", "", "Radial Pong - Version 11 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "43f8459d39fb4eddf9186d62722ff795", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "442602713cb45b9321ee93c6ea28a5d0", "", "", "Demon Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4427f06085bb4c22ff047027f7acecc2", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros) (Prototype)", "Uses the Paddle Controllers (swapped)", "Prototype", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" }, - { "442b7863683e5f084716fda050474feb", "Eckhard Stolberg", "", "Frame Timed Sound Effects-EM (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4431428a7500c96fc0e2798a5dbd36d6", "", "", "Kangaroo (Genesis)", "Genesis controller (B is punch, C is jump)", "Hack of Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4474b3ad3bf6aabe719a2d7f1d1fb4cc", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4476c39736090dabac09f6caf835fc49", "", "", "Text Screen (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "448c2a175afc8df174d6ff4cce12c794", "Activision, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a2]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "44e9c4a047c348dbeb7ace60f45484b4", "", "", "Moon Patrol Arcade (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "44f71e70b89dcc7cf39dfd622cfb9a27", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "45027dde2be5bdd0cab522b80632717d", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "45040679d72b101189c298a864a5b5ba", "20th Century Fox Video Games - Sirius Software, David Lubar", "11022", "SpaceMaster X-7 (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4543b7691914dfd69c3755a5287a95e1", "CommaVid, Irwin Gaines", "CM-005", "Mines of Minos (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "456453a54ca65191781aef316343ae00", "", "", "Full Screen Bitmap (3-D Green) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4565c1a7abce773e53c75b35414adefd", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "457b03cd48ff6d895795ef043c6b0f1e", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "457e7d4fcd56ebc47f5925dbea3ee427", "Carrere Video - JWDA, Garry Kitchen - Teldec - Prism", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "457f4ad2cda5f4803f122508bfbde3f5", "", "", "Canyon Bomber (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "458883f1d952cd772cf0057abca57497", "", "", "Fishing Derby (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "45a095645696a217e416e4bd2baea723", "Digivision", "", "Snoopy (Digivision)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "45a4f55bb9a5083d470ad479afd8bca2", "CommaVid, Joseph Biel", "", "Frog Demo (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "45beef9da1a7e45f37f3f445f769a0b3", "Atari, Suki Lee", "CX2658", "Math Gran Prix (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "45c4413dd703b9cfea49a13709d560eb", "Jone Yuan Telephonic Enterprise Co", "", "Challenge of.... Nexar, The (Jone Yuan) (Hack)", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "45cb0f41774b78def53331e4c3bf3362", "Carrere Video - JWDA, Roger Booth, Sylvia Day, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC1007", "Octopus (1983) (Carrere Video) (PAL)", "AKA Name This Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4605a00f5b44a9cbd5803a7a55de150e", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-03-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "461029ab23800833e9645be3e472d470", "", "", "Combat TC (v0.1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "46258bd92b1f66f4cb47864d7654f542", "Zellers", "", "Turmoil (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "463dd4770506e6c0ef993a40c52c47be", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "463e66ad98806a49106cffa49c08e2ed", "", "", "Interlace Game Demo (01-09-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "467340a18158649aa5e02a4372dcfccd", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4689081b7363721858756fe781cc7713", "", "", "Oystron (V2.6) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "468f2dec984f3d4114ea84f05edf82b6", "Tigervision - Teldec", "7-011 - 3.60015 VG", "Miner 2049er Volume II (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4690fdb70c86604bb35da26696818667", "", "", "Euchre (Release Candidate) (NTSC) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "469473ff6fed8cc8d65f3c334f963aab", "Atari, Bruce Poehlman, Gary Stark", "", "Dune (07-10-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "46c021a3e9e2fd00919ca3dd1a6b76d8", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "46c43fdcbce8fde3a91ebeafc05b7cbd", "", "", "Invaders Demo (PAL) (2001) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "46dc526773808c8b9bb2111f24e5704c", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "46e9428848c9ea71a4d8f91ff81ac9cc", "Telegames", "", "Astroblast (1988) (Telegames) (PAL)", "Can also use left joystick", "", "", "", "", "", "", "", "", "PADDLES", "", "YES", "", "", "AUTO 55", "", "", "", "" }, - { "4702d8d9b48a332724af198aeac9e469", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "470878b9917ea0348d64b5750af149aa", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "471f7bdc933e8db0e44aa3dde2dd92af", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "47464694e9cce07fdbfd096605bf39d4", "Activision, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "47585c047802dd9af888b998fb921f32", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4767356fa0ed3ebe21437b4473d4ee28", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (04-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "47711c44723da5d67047990157dcb5dd", "CCE", "", "Ice Hockey (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "47911752bf113a2496dbb66c70c9e70c", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari) (PAL)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "4799a40b6e889370b7ee55c17ba65141", "Konami", "RC 100-X 02", "Pooyan (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "47aad247cce2534fd70c412cb483c7e0", "Rainbow Vision - Suntek", "SS-010", "Mafia (1983) (Rainbow Vision) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "47abfb993ff14f502f88cf988092e055", "Zellers", "", "Inca Gold (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "47aef18509051bab493589cb2619170b", "", "", "Stell-A-Sketch (Bob Colbert) (PD)", "Uses Driving, Joystick, or Amiga/Atari ST Mouse Controllers", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "47b82d47e491ac7fdb5053a88fccc832", "Atari Freak 1, Franklin Cruz", "", "Asteroid 2 (Atari Freak 1) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "47cd61f83457a0890de381e478f5cf5f", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-2A, 13205", "Fathom (1983) (Imagic) (PAL)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "481d20ec22e7a63e818d5ef9679d548b", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "481f9a742052801cc5f3defb41cb638e", "Jeffry Johnston", "", "Radial Pong - Version 4 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "48287a9323a0ae6ab15e671ac2a87598", "Zellers", "", "Laser Volley (Zellers)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4834b7b28ea862227ac7e40053fb52a5", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "48411c9ef7e2cef1d6b2bee0e6055c27", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "484b0076816a104875e00467d431c2d2", "Atari", "CX26150", "Q-bert (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4857f8bb88bb63c640d3ea5aac7f5d6d", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (08-12-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4868a81e1b6031ed66ecd60547e6ec85", "Eric Mooney", "", "Invaders by Erik Mooney (V2.1) (1-3-98) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "487193a7b7fe57a1bbc2f431f628bd5f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4884b1297500bd1243659e43c7e7579e", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (10-24-1991) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4892b85c248131d6a42c66a4163a40d0", "Canal 3 - Intellivision", "", "Tac-Scan (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "48bcf2c5a8c80f18b24c55db96845472", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "48e5c4ae4f2d3b62b35a87bca18dc9f5", "Quelle", "476.774 5", "Bobby geht nach Hause (1983) (Quelle) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "48f18d69799a5f5451a5f0d17876acef", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4901c05068512828367fde3fb22199fe", "Imagic, Rob Fulop", "720101-2B, IA3200P, EIX-006-04I", "Demon Attack (1982) (Imagic) (PAL)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4904a2550759b9b4570e886374f9d092", "Parker Brothers, Charlie Heath", "931506", "Reactor (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "490e3cc59d82f85fae817cdf767ea7a0", "", "", "Berzerk (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "490eed07d4691b27f473953fbea6541a", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "49366f41aa7a54baf263426e99ce4312", "", "", "POP-MDM-Test (PAL) (63 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "493daaf9fb1ba450eba6b8ed53ffb37d", "", "", "3-D Corridor Demo (27-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "493de059b32f84ab29cde6213964aeee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "493e90602a4434b117c91c95e73828d1", "Telegames", "", "Lock 'n' Chase (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4947c9de2e28b2f5f3b0c40ce7e56d93", "", "", "3-D Corridor Demo 2 (29-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "494cda91cc640551b4898c82be058dd9", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "49571b26f46620a85f93448359324c28", "", "", "Save Our Ship (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "497c811026367c08fd838c9c59e5041d", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "497f3d2970c43e5224be99f75e97cbbb", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4981cefe5493ea512284e7f9f27d1e54", "Home Vision - Gem International Corp. - VDI", "VCS83136", "Cosmic War (1983) (Home Vision) (PAL)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4999b45be0ab5a85bac1b7c0e551542b", "CCE", "", "Double Dragon (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "499b612f6544ae71d4915aa63e403e10", "Atari, Carol Shaw", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "49f2cef5269fd06218be9f9474c74f8d", "Rentacom", "", "Time Pilot (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4a196713a21ef07a3f74cf51784c6b12", "Jone Yuan Telephonic Enterprise Co", "", "Frogs and Flies (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4a2fe6f0f6317f006fd6d4b34515448b", "", "", "Warring Worms (Midwest Classic Edition) (08-06-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4a45c6d75b1ba131f94a9c13194d8e46", "", "", "How to Draw a Playfield II (Joystick Hack) (1997) (Eric Bacher) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4a5fddf89801336637ac8e57a7c9a881", "Amiga", "1125", "Power Play Arcade Video Game Album IV (1984) (Amiga) (Prototype)", "Atlantis, Cosmic Ark, Dragonfire", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4a6be79310f86f0bebc7dfcba4d74161", "", "", "Demolition Herby (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4a7eee19c2dfb6aeb4d9d0a01d37e127", "Hozer Video Games", "", "Crazy Valet (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4a8c743396b8ad69d97e6fd3dd3e3132", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4a9009620038f7f30aaeb2a00ae58fde", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4ab2ebd95a8f861ea451abebdad914a5", "Nukey Shay, Thomas Jentzsch", "PAL conversion (F6)", "Montezuma's Revenge (PAL) (Genesis)", "Genesis controller (B jumps left, C jumps right)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4ab4af3adcdae8cdacc3d06084fc8d6a", "Nick Bensema", "", "Sucky Zepplin (Nick Bensema) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4abb4c87a4c5f5d0c14ead2bb36251be", "Atari - Imagineering, Alex DeMeo", "CX26135, CX26135P", "RealSports Boxing (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4ac9f40ddfcf194bd8732a75b3f2f214", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (12-29-1982) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4ae8c76cd6f24a2e181ae874d4d2aa3d", "", "", "Flash Gordon (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4af4103759d603c82b1c9c5acd2d8faf", "Imagic, Bob Smith", "720114-2A, 13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4afa7f377eae1cafb4265c68f73f2718", "Ed Fries", "", "Halo 2600 (2010) (Ed Fries)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4afe528a082f0d008e7319ebd481248d", "", "", "Multi-Color Demo 1 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4b143d7dcf6c96796c37090cba045f4f", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4b205ef73a5779acc5759bde3f6d33ed", "", "", "Berzerk (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4b27f5397c442d25f0c418ccdacf1926", "Atari, Warren Robinett", "CX2613, 49-75154", "Adventure (1980) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4b379b885e2694f992c6cc932f18327f", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4b71197153d651480830638cb6a03249", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4b753a97aee91e4b3e4e02f5e9758c72", "Glenn Saunders, Roger Williams", "", "Asymmetric Reflected Playfield (Glenn Saunders)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4b94fd272785d7ec6c95fb7279d0f522", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (12-03-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "4b9581c3100a1ef05eac1535d25385aa", "", "", "IQ 180 (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4baada22435320d185c95b7dd2bcdb24", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4bcc7f6ba501a26ee785b7efbfb0fdc8", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4bdae9246d6ee258c26665512c1c8de3", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4bdf54a454470ba015a217a8f5e61320", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" }, - { "4c030667d07d1438f0e5c458a90978d8", "Retroactive", "", "Qb (V2.03) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4c0fb2544ae0f8b5f7ae8bce7bd7f134", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c205f166157154df2f1ef60d87e552f", "", "", "Single-Scanline Positioning Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c39a2c97917d3d71739b3e21f60bba5", "", "", "Whale (Sub Scan Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c462b2b6fb0a19a1437eb2c3dc20783", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c4ce802cbfd160f7b3ec0f13f2a29df", "", "", "Beta Demo (V1.1) (26-09-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c606235f4ec5d2a4b89139093a69437", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4c6afb8a44adf8e28f49164c84144bfe", "CCE", "C-806", "Mission 3,000 A.D. (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c8832ed387bbafc055320c05205bc08", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c8970f6c294a0a54c9c45e5e8445f93", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4c9307de724c36fd487af6c99ca078f2", "Imagic, Brad Stewart", "720106-1A, IA3409", "Sky Patrol (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4ca0959f846d2beada18ecf29efe137e", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666, CX2666P", "RealSports Volleyball (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4ca73eb959299471788f0b685c3ba0b5", "Activision, Steve Cartwright", "AX-031", "Frostbite (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4ca90ba45eced6f5ad560ea8938641b2", "", "", "Hangman Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4cabc895ea546022c2ecaa5129036634", "Funvision - Fund. International Co.", "", "Ocean City (Funvision)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4cd796b5911ed3f1062e805a3df33d98", "Tigervision - Software Electronics Corporation - Teldec", "7-006", "Springer (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d06f72cc3d8934579c11ff8f375c260", "Bit Corporation", "R320", "Bowling (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d0a28443f7df5f883cf669894164cfa", "", "", "Beast Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d2cef8f19cafeec72d142e34a1bbc03", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d38e1105c3a5f0b3119a805f261fcb5", "Bit Corporation", "PGP212", "Phantom UFO (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Spider Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d502d6fb5b992ee0591569144128f99", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (11-21-1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d5f6db55f7f44fd0253258e810bde21", "Fabrizio Zavagli", "", "Betterblast (Fabrizio Zavagli) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d7517ae69f95cfbc053be01312b7dba", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d77f291dca1518d7d8e47838695f54b", "Data Age", "DA1004", "Airlock (1982) (Data Age)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4d8396deeabb40b5e8578276eb5a8b6d", "Otto Versand", "781698", "Volleyball (1983) (Otto Versand) (PAL)", "AKA RealSports Volleyball (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4dbd7e8b30e715efc8d71d215aec7fe7", "Bit Corporation", "R320", "Air Raiders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4dbf47c7f5ac767a3b07843a530d29a5", "Ric Pryor", "", "Breaking News (2002) (Ric Pryor) (Hack)", "Hack of Bump 'n' Jump", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4dcc7e7c2ec0738e26c817b9383091af", "", "", "Unknown Title (bin00026 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4dd6c7ab9ef77f2b4950d8fc7cd42ee1", "Retroactive", "", "Qb (V2.04) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4df6124093ccb4f0b6c26a719f4b7706", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, - { "4df9d7352a56a458abb7961bf10aba4e", "", "", "Racing Car (Unknown)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "4e01d9072c500331e65bb87c24020d3f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4e02880beeb8dbd4da724a3f33f0971f", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL)", "AKA Flap!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4e15ddfd48bca4f0bf999240c47b49f5", "Avalon Hill, Jean Baer, Jim Jacob", "5001002", "Death Trap (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4e2c884d04b57b43f23a5a2f4e9d9750", "", "", "Baby Center Animation (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4e37992a37ea36489283f7eb90913bbc", "Kris", "", "Hangman Ghost Halloween (Kris) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4e4895c3381aa4220f8c2795d6338237", "", "", "Backwards Cannonball v1 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4e66c8e7c670532569c70d205f615dad", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4e86866d9cde738d1630e2e35d7288ce", "Supergame", "", "River Raid III (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4e99ebd65a967cabf350db54405d577c", "Coleco", "2663", "Time Pilot (1983) (Coleco) [b1]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4eb4fd544805babafc375dcdb8c2a597", "Inspirational Video Concepts, Steve Shustack", "321430", "Red Sea Crossing (1983) (Inspirational Video Concepts)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4edb251f5f287c22efc64b3a2d095504", "Atari", "", "Atari VCS Point-of-Purchase ROM (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4f0071946e80ca68edfdccbac86dcce0", "", "", "Virtual Pet Demo 1 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4f2d47792a06da224ba996c489a87939", "HES - Activision", "223", "Super Action Pak - Pitfall, Barnstorming, Grand Prix, Laser Blast (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4f32b24869d8c1310fecf039c6424db6", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (12-15-82) (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4f618c2429138e0280969193ed6c107e", "Activision, Alan Miller", "AZ-028, AG-028-04", "Robot Tank (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4f634893d54e9cabe106e0ec0b7bdcdf", "Retroactive", "", "Qb (2.14) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4f64d6d0694d9b7a1ed7b0cb0b83e759", "20th Century Fox Video Games, John Russell", "11016", "Revenge of the Beefsteak Tomatoes (1983) (20th Century Fox)", "AKA Revenge of the Cherry Tomatoes", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4f6702c3ba6e0ee2e2868d054b00c064", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen - Ariola", "EAZ-033 - 711 033-725", "Space Shuttle (1983) (Activision) (PAL)", "A Journey Into Space, Eine Reise ins All", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4f781f0476493c50dc578336f1132a67", "", "", "Indy 500 (Unknown) (PAL) (4K)", "Uses Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" }, - { "4f7b07ec2bef5ccffe06403a142f80db", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4f82d8d78099dd71e8e169646e799d05", "", "", "Miniature Golf (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4f89b897444e7c3b36aed469b8836839", "Atari", "CX26190", "BMX Air Master (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4fae08027365d31c558e400b687adf21", "", "", "Qb (V2.17) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "4faeb04b1b7fb0fa25db05753182a898", "", "", "2600 Digital Clock (V x.xx) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4fbe0f10a6327a76f83f83958c3cbeff", "CCE", "C-816", "Keystone Kappers (1983) (CCE)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "4fc1b85b8074b4b9436d097900e34f29", "John K. Harvey", "", "John K. Harvey's Equalizer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "50200f697aeef38a3ce31c4f49739551", "Mystique - American Multiple Industries, Joel H. Martin", "", "Custer's Revenge (1982) (Mystique) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "502044b1ac111b394e6fbb0d821fca41", "", "", "Hangman Invader 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "502168660bfd9c1d2649d415dc89c69d", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "504688d49a41bf03d8a955512609f3f2", "Thomas Jentzsch", "", "SWOOPS! (v0.94) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "50568c80ac61cab789d9923c9b05b68e", "Ebivision", "", "Merlin's Walls - Standard Edition (1999) (Ebivision)", "Image rotated 90 degrees CW", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5069fecbe4706371f17737b0357cfa68", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo) (PAL)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5079bfbc7b8f5770f84215ed2e3bdd1b", "Omegamatrix (2012)", "", "Genesis Button Tester", "", "Homebrew", "", "", "", "", "", "", "", "GENESIS", "GENESIS", "", "", "", "", "", "", "", "" }, - { "50a410a5ded0fc9aa6576be45a04f215", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "50c7edc9f9dc0369abcdab3b4efeb5e9", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "50ef88f9a5e0e1e6b86e175362a27fdb", "", "", "Multi-Sprite Game V2.4 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "512e874a240731d7378586a05f28aec6", "Tigervision, Rorke Weigandt - Teldec", "7-005", "Marauder (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5131ab3797fe8c127e3e135b18b4d2c8", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "514f911ecff2be5eeff2f39c49a9725c", "Parker Brothers", "931510", "Sky Skipper (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "515046e3061b7b18aa3a551c3ae12673", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "516ffd008057a1d78d007c851e6eff37", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "517592e6e0c71731019c0cebc2ce044f", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "517923e655755086a3b72c0b17b430e6", "Tron", "", "Super Tennis (Tron)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5188fee071d3c5ef0d66fb45c123e4a5", "Gameworld", "133-001", "Encounter at L-5 (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, - { "519f007c0e14fb90208dbb5199dfb604", "Amiga - Video Soft", "", "Depth Charge (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "51c1ddc9d6d597f71fb7efb56012abec", "Bit Corporation", "R320", "Lock 'n' Chase (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "51de328e79d919d7234cf19c1cd77fbc", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "51e390424f20e468d2b480030ce95d7b", "Video Game Program", "", "Fire Bird (Video Game Program) (PAL)", "AKA Phoenix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "51f15b39d9f502c2361b6ba6a73464d4", "", "", "Amanda Invaders (PD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "51f211c8fc879391fee26edfa7d3f11c", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "521f4dd1eb84a09b2b19959a41839aad", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "522b27a8afeb951b5a5a667f8d1a46a1", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "522c9cf684ecd72db2f85053e6f6f720", "Rainbow Vision - Suntek", "SS-008", "Year 1999, The (1983) (Rainbow Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "52385334ac9e9b713e13ffa4cc5cb940", "CCE", "C-804", "Open, Sesame! (1983) (CCE)", "AKA Abre-te, Sesamo!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "523f5cbb992f121e2d100f0f9965e33f", "Joe Grand", "", "SCSIcide (1.30) (CGE 2001 Release) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" }, - { "524693b337f7ecc9e8b9126e04a232af", "", "", "Euchre (19-08-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5256f68d1491986aae5cfdff539bfeb5", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-26-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "525ea747d746f3e80e3027720e1fa7ac", "Activision, Garry Kitchen - Ariola", "EAZ-032 - 771 032-712", "Pressure Cooker (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "525f2dfc8b21b0186cff2568e0509bfc", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "52615ae358a68de6e76467e95eb404c7", "", "", "DJdsl-wopd (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "528400fad9a77fd5ad7fc5fdc2b7d69d", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "52a0003efb3b1c49fcde4dbc2c685d8f", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K) [a]", "", "", "", "", "2K", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "52b448757081fd9fabf859f4e2f91f6b", "", "", "Worm War I (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "52bae1726d2d7a531c9ca81e25377fc3", "", "", "Space Instigators (V1.8 Fixed) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "52e1954dc01454c03a336b30c390fb8d", "Retroactive", "", "Qb (2.14) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "52e9db3fe8b5d336843acac234aaea79", "", "", "Fu Kung! (V0.11) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5305f69fbf772fac4760cdcf87f1ab1f", "Jone Yuan Telephonic Enterprise Co", "", "Ski Run (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5324cf5b6dc17af4c64bf8696c39c2c1", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (8K)", "AKA Lost City of Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "533661e9bccd8a9f80ce3765f282c92f", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5336f86f6b982cc925532f2e80aa1e17", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "PB5060", "Star Wars - Death Star Battle (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "534e23210dd1993c828d944c6ac4d9fb", "M Network, Stephen Tatsumi, Jane Terjung - Kool Aid", "MT4648", "Kool-Aid Man (1983) (M Network)", "AKA Kool Aid Pitcher Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5355f80cacf0e63a49cbf4ade4e27034", "Christian Samuel", "", "Cute Dead Things House (Christian Samuel) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5360693f1eb90856176bd1c0a7b17432", "", "", "Oystron (V2.85) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "536bf56baa70acb17113884ac41f2820", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "537ed1e0d80e6c9f752b33ea7acbe079", "", "", "A-VCS-tec Challenge (beta 5) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5385cf2a04de1d36ab55c73174b84db0", "Paul Slocum", "", "Combat Rock (PD) (Hack)", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "539d26b6e9df0da8e7465f0f5ad863b7", "Atari, Carol Shaw - Sears", "CX2636 - 49-75156", "Video Checkers (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "539f3c42c4e15f450ed93cb96ce93af5", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "53b66f11f67c3b53b2995e0e02017bd7", "CCE", "C-1005", "Super Tennis (1983) (CCE)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "53bd1c7c972ae634c912331a9276c6e3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "53d181cde2e0219b5754caad246fcb66", "", "", "Missile Demo (1998) (Ruffin Bailey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "53e03df47e76329b701641f8bdc206f5", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "53f147b9746fdc997c62f3dd67888ee5", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "540075f657d4b244a1f74da1b9e4bf92", "Bit Corporation", "PGP230", "Festival (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5409d20c1aea0b89c56993aec5dc5740", "", "", "Carnival Shooter (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "541cac55ebcf7891d9d51c415922303f", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "5428cdfada281c569c74c7308c7f2c26", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "542c6dd5f7280179b51917a4cba4faff", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5438e84b90e50a5362f01cc843b358d4", "Arcadia Corporation, Scott Nelson", "3 AR-4300", "Fireball (1982) (Arcadia) (Prototype)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "543b4b8ff1d616fa250c648be428a75c", "Warren Robinett", "", "Adventure (1978) (Warren Robinett) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "545048ccb045f9efc6cf2b125cd0dfa8", "Arcadia Corporation, Stephen Harland Landrum, Jon Leupp", "AR-4201", "Sword of Saros (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "54785fa29e28aae6038929ba29d33d38", "", "", "Poker Squares (V0.19) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "54836a8f23913e9a77c7f2665baf36ac", "Bit Corporation", "PG204", "Open, Sesame! (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5494b9ee403d9757f0fd1f749e80214a", "Larry Petit", "", "Xenophobe Arcade (2003) (Larry Petit) (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "54a1c1255ed45eb8f71414dadb1cf669", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "54bafc299423f5a50b8bc3a797914706", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp) (PAL)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "54da3b0b3f43f5b37911c135b9432b49", "", "", "Halloween III Revision (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "54f7efa6428f14b9f610ad0ca757e26c", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "551a64a945d7d6ece81e9c1047acedbc", "Matthias Jaap", "", "Coffee Cup Soccer (Matthias Jaap) (Hack)", "Hack of Pele's Soccer", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5524718a19107a04ec3265c93136a7b5", "Thomas Jentzsch", "", "RealSports Basketball (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "553dbf9358cfd2195e2fa0e08b01fb6a", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (07-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "554fd5775ca6d544818c96825032cf0d", "Atari - Roklan, Bob Curtiss", "", "Firefox (06-01-83) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "557e893616648c37a27aab5a47acbf10", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (01-16-1990) (Atari) (Prototype) (PAL)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "559317712f989f097ea464517f1a8318", "Panda", "100", "Space Canyon (1983) (Panda)", "AKA Space Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "55949cb7884f9db0f8dfcf8707c7e5cb", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "55ace3c775f42eb46f08bb1dca9114e7", "", "", "Shadow Keep (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "55ef6ab2321ca0c3d369e63d59c059c8", "", "", "Pitfall! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "55ef7b65066428367844342ed59f956c", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "56210a3b9ea6d5dd8f417a357ed8ca92", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype) [bad dump]", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "56300ed31fef018bd96768ccc982f7b4", "HES - Activision", "559", "Rad Action Pak - Kung-Fu Master, Freeway, Frostbite (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5641c0ff707630d2dd829b26a9f2e98f", "Joystik", "", "Motocross (Joystik)", "AKA Motocross Racer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5643ee916f7dc760148fca4db3aa7d10", "", "", "Moon Patrol (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5678ebaa09ca3b699516dba4671643ed", "Coleco, Sylvia Day, Henry Will IV", "2459", "Mouse Trap (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "568371fbae6f5e5b936af80031cd8888", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "56f72247eb9ebfd33bfd0cca23ab7ef4", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "571c6d9bc71cb97617422851f787f8fe", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "572d0a4633d6a9407d3ba83083536e0f", "Funvision - Fund. International Co.", "", "Busy Police (Funvision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "575c0fb61e66a31d982c95c9dea6865c", "", "", "Blackjack (Unknown) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "57939b326df86b74ca6404f64f89fce9", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "579baa6a4aa44f035d245908ea7a044d", "Jess Ragan", "", "Galaxian Enhanced Graphics (Jess Ragan) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "57a66b6db7efc5df17b0b0f2f2c2f078", "Retroactive", "", "Qb (V2.08) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "57c5b351d4de021785cf8ed8191a195c", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "5835a78a88f97acea38c964980b7dbc6", "", "", "Cosmic Creeps (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "5846b1d34c296bf7afc2fa05bbc16e98", "Atari - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "58513bae774360b96866a07ca0e8fd8e", "Mystique - American Multiple Industries, Joel H. Martin", "1001", "Custer's Revenge (1982) (Mystique)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "585600522b1f22f617652c962e358a5d", "", "", "Multi-Sprite Game V2.2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "585f73010e205ae5b04ee5c1a67e632d", "", "", "Daredevil (V3) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5864cab0bc21a60be3853b6bcd50c59f", "", "", "Commando Raid (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "58746219d8094edff869f0f5c2aeaad5", "Jone Yuan Telephonic Enterprise Co", "", "Bowling (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5894c9c0c1e7e29f3ab86c6d3f673361", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision)", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "589c73bbcd77db798cb92a992b4c06c3", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "58a82e1da64a692fd727c25faef2ecc9", "CCE", "C-824", "Jaw Breaker (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "58c396323ea3e85671e34c98eb54e2a4", "Brian Watson", "", "Color Tweaker (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "58d331c23297ed98663d11b869636f16", "", "", "Fu Kung! (V0.09) (26-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "58e313e2b5613b2439b5f12bb41e3eef", "", "", "Cube Conquest (Demo Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "590ac71fa5f71d3eb29c41023b09ade9", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (01-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "59135f13985b84c4f13cc9e55eec869a", "", "", "Multi-Sprite Game V2.0 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "594437a35603c3e857b5af75b9718b61", "HES - Activision", "", "Robot Tank (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "594dbc80b93fa5804e0f1368c037331d", "Telesys, Alex Leavens", "", "Bouncin' Baby Bunnies (1983) (Telesys) (Prototype)", "AKA Baby Boom Boom, Bouncing Baby Monkeys", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5961d259115e99c30b64fe7058256bcf", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "59734e1cc41822373845a09c51e6ba21", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "598a4e6e12f8238b7e7555f5a7777b46", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "599cbf919d47a05af975ad447df29497", "Jake Patterson", "", "Baubles (V0.002) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "59b70658f9dd0e2075770b07be1a35cf", "Thomas Jentzsch", "", "Surfer's Paradise (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "59d33e00c07665395209c1e55da0b139", "", "", "Imagic Selector ROM (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "59e53894b3899ee164c91cfa7842da66", "Data Age", "", "Survival Run (1983) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "59e96de9628e8373d1c685f5e57dcf10", "PlayAround - J.H.M.", "204", "Beat 'Em & Eat 'Em (1982) (PlayAround)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "59f596285d174233c84597dee6f34f1f", "CCE", "C-811", "River Raid (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a0ff99ba10bd26d542e1d6f59f56850", "Champ Games", "CG-04-P", "Super Cobra Arcade (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "5a17e30e6e911e74ccd7b716d02b16c6", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a272012a62becabcd52920348c7c60b", "Star Game", "", "Pitfall (Star Game)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a2f2dcd775207536d9299e768bcd2df", "Otto Versand", "781698", "Flippern (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a4205aeedd3b0588f973f38bbd9dfd4", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a5390f91437af9951a5f8455b61cd43", "Retroactive", "", "Qb (0.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "5a6febb9554483d8c71c86a84a0aa74e", "CCE", "C-1003", "Donkey Kong Jr (1983) (CCE)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a734779d797ccef25dc8acfa47244c7", "", "", "Oh No! (Version 2) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a80b857eb8b908ab477ec4ef902edc8", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a81ad4e184050851e63c8e16e3dac77", "Jone Yuan Telephonic Enterprise Co", "Hack", "Sky Diver (Jone Yuan) (Hack)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a8afe5422abbfb0a342fb15afd7415f", "Atari - Bobco, Robert C. Polaro", "CX26155", "Sprint Master (1988) (Atari)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a93265095146458df2baf2162014889", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5a9685c4d51a6c1d6a9544946d9e8dc3", "AtariAge", "", "Grandma's Revenge (AtariAge)", "Can use Driving Controller in right port", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "", "" }, - { "5a9d188245aff829efde816fcade0b16", "CCE", "C-808", "Phantom Tank (1983) (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5acf9865a72c0ce944979f76ff9610f0", "", "", "Dodge Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5ae73916fa1da8d38ceff674fa25a78a", "CCE", "", "Barnstorming (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5aea9974b975a6a844e6df10d2b861c4", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5af9cd346266a1f2515e1fbc86f5186a", "SEGA", "002-01", "Sub-Scan (1983) (SEGA)", "AKA Subterfuge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b124850de9eea66781a50b2e9837000", "PlayAround - J.H.M.", "205", "Bachelor Party (1982) (PlayAround)", "Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "AUTO 65", "", "", "YES", "" }, - { "5b574faa56836da0866ba32ae32547f2", "", "", "Tomb Raider 2600 [REV 03] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b5d04887922b430de0b7b2a21f9cd25", "", "", "Omega Race (Genesis)", "Genesis controller (B is thrust, C is fire)", "Hack of Omega Race", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b6f5bcbbde42fc77d0bdb3146693565", "", "", "Seaquest (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b7ea6aa6b35dc947c65ce665fde624b", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b85e987e2b1618769d97ba9182333d0", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b92a93b23523ff16e2789b820e2a4c5", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "AG-039-04", "Kung-Fu Master (1987) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b98e0536c3f60547dd708ae22adb04b", "Ben Hudman", "", "Donkey Kong Gingerbread Man (Ben Hudman) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5b9c2e0012fbfd29efd3306359bbfc4a", "HES", "", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5babe0cad3ec99d76b0aa1d36a695d2f", "Coleco - Individeo, Ed Temple", "2654", "Looping (1983) (Coleco) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5bba254e18257e578c245ed96f6b003b", "", "", "Music Effects Demo (21-01-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "5bbab3f3e4b47e3e23f9820765dbb45c", "", "", "Pitfall! (says 1985) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5bbb75b49b2bccef9c91ff84bb249c80", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5bc9998b7e9a970e31d2cb60e8696cc4", "Jack Kortkamp", "", "Borgwars Asteroids (2003) (Jack Kortkamp) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "5bcc83677d68f7ef74c1b4a0697ba2a8", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (16K)", "", "", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5bd79139a0c03b63f6f2cf00a7d385d2", "Marc de Smet", "", "An Exercise In Minimalism (V1) (1999) (Marc de Smet) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5be03a1fe7b2c114725150be04b38704", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5c0227ad63300670a647fcebf595ea37", "Josh", "", "Battle for Naboo (Josh) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5c0520c00163915a4336e481ca4e7ef4", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a1]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5c19f6da638c4c7c1f98d09e63df43e4", "Canal 3 - Intellivision", "", "Cosmic Ark (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5c1b1aa78b7609d43c5144c3b3b60adf", "", "", "Demo Image Series #8 - Two Marios (Different Interlacing) (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5c3a6d27c026f59a96b7af91e8b1bf26", "PlayAround - J.H.M.", "", "PlayAround Demo (PlayAround) (1982)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5c618a50dfa23daac97ba459b9ff5206", "Steve Engelhardt", "", "Berzerk Renegade (2002) (Steve Engelhardt) (Hack)", "Hack of Room of Doom", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "5c73693a89b06e5a09f1721a13176f95", "", "", "Wavy Line Test 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5c86e938e0845b9d61f458539e9a552b", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5cbd7c31443fb9c308e9f0b54d94a395", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5ce98f22ade915108860424d8dde0d35", "", "", "Hangman Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5ced13931c21ef4fc77d3fe801a1cbfa", "CCE", "C-828", "Missile Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d0e8a25cbd23e76f843c75a86b7e15b", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-07-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d132d121aabc5235dd039dfc46aa024", "", "", "Basketball (208 in 1) (Unknown) (PAL) (Hack)", "Console ports are swapped", "Hack", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "5d25df9dc2cde746ceac48e834cf84a7", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "EAZ-033", "Space Shuttle (1983) (Activision) (SECAM)", "A Journey Into Space", "", "", "", "FE", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d2cc33ca798783dee435eb29debf6d6", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d7293f1892b66c014e8d222e06f6165", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a1]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d799bfa9e1e7b6224877162accada0d", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d8f1ab95362acdf3426d572a6301bf2", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ) (PAL)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d8fb14860c2f198472b233874f6b0c9", "", "", "Boing! (PD) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5d9592756425192ec621d2613d0e683d", "CCE", "C-839", "Misterious Thief, A (1983) (CCE) [a]", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5da8fd0b5ed33a360bff37f8b5d0cd58", "Tron", "", "Pole Position (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5dae540347cf0a559962d62604ecf750", "Canal 3 - Intellivision", "", "Freeway (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5db9e5bf663cad6bf159bc395f6ead53", "Goliath - Hot Shot", "83-212", "Time Race (1983) (Goliath) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5dccf215fdb9bbf5d4a6d0139e5e8bcb", "Froggo", "FG1009", "Sea Hunt (1987) (Froggo)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5de8803a59c36725888346fdc6e7429d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5df32450b9fbcaf43f9d83bd66bd5a81", "Eric Ball", "", "Atari Logo Playfield Demo (2001) (Eric Ball) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5df559a36347d8572f9a6e8075a31322", "Digivision", "", "Enduro (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5e0c37f534ab5ccc4661768e2ddf0162", "Telegames - VSS, Ed Salvo", "5667 A106", "Glacier Patrol (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5e1b4629426f4992cf3b2905a696e1a7", "Activision - Bobco, Robert C. Polaro", "AK-049-04", "Rampage! (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5e1b7a6078af428ef056fe85a37a95ca", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5e1cd11a6d41fc15cf4792257400a31e", "Philip R. Frey", "", "Return of Mario Bros (Philip R. Frey) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5e201d6bfc520424a28f129ee5e56835", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5e2495d43b981010304af55efed1e798", "Jone Yuan Telephonic Enterprise Co", "", "Math Gran Prix (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5e43c0391f7412ae64fae6f3742d6ee9", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.27)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "DRIVING", "", "", "", "", "", "", "", "" }, - { "5e99aa93d0acc741dcda8752c4e813ce", "", "", "2600 Digital Clock (V b2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5ec73ac7d2ac95ac9530c6d33e713d14", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (2 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5eeb81292992e057b290a5cd196f155d", "Wizard Video Games - VSS, Ed Salvo", "008", "Texas Chainsaw Massacre, The (1983) (Wizard Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5ef303b9f0aa8cf20720c560e5f9baa1", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f1b7d5fa73aa071ba0a3c2819511505", "CCE", "", "Cosmic Commuter (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f2b4c155949f01c06507fb32369d42a", "Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f316973ffd107f7ab9117e93f50e4bd", "", "", "Commando Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f39353f7c6925779b0169a87ff86f1e", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari) [a]", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f46d1ff6d7cdeb4b09c39d04dfd50a1", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f4ebf8a1e5f5f7b9ff3e3c6affff3e6", "Bit Corporation", "R320", "Donkey Kong (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f560837396387455c9dcb05cdd4b053", "Canal 3 - Intellivision", "", "Eggomania (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, - { "5f681403b1051a0822344f467b05a94d", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "5f708ca39627697e859d1c53f8d8d7d2", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f73e7175474c1c22fb8030c3158e9b3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f786b67e05fb9985b77d4beb35e06ee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari) (PAL)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f7ae9a7f8d79a3b37e8fc841f65643a", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f7de62a408b9de3a1168898298fd31d", "", "", "Super Cobra (Genesis)", "Genesis controller (B is bomb, C is laser)", "Hack of Super Cobra", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5f950a2d1eb331a1276819520705df94", "20th Century Fox Video Games - Micro Computer Technologies, Jim Collas", "", "Heart Like a Wheel (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "5f9b62350b31be8bd270d9a241cbd50e", "Telegames", "5658 A088", "Football (1988) (Telegames) (PAL)", "AKA Super Challenge Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5faffe1c4c57430978dec5ced32b9f4a", "Dactari - Milmar", "", "Volleyball (Dactari - Milmar)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "5fb71cc60e293fe10a5023f11c734e55", "", "", "This Planet Sucks (Fix) (27-12-2002) (Greg Troutman)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "600d48eef5c0ec27db554b7328b3251c", "", "", "Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6015a9cef783e97e98a2aa2cf070ae06", "Thomas Jentzsch", "", "Battlezone TC (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Battlezone", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "60358edf0c2cc76b1e549e031e50e130", "Manuel Polik", "", "Cyber Goth Galaxian (Manuel Polik) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "603c7a0d12c935df5810f400f3971b67", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6041f400b45511aa3a69fab4b8fc8f41", "Apollo, Ban Tran", "AP-2010", "Wabbit (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "604e09724555807c28108049efe34a13", "", "", "Sokoban (01-01-2003) (Adam Wozniak)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6058e40ce79d7434c7f7477b29abd4a5", "", "", "Rubik's Cube Demo (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "605dcb73d22f4efdb90ef9da2f290f7c", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "605fd59bfef88901c8c4794193a4cbad", "Data Age", "", "Secret Agent (1983) (Data Age) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, - { "606c2c1753051e03c1f1ac096c9d2832", "Jone Yuan Telephonic Enterprise Co", "", "Crackpots (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6076b187a5d8ea7a2a05111c19b5d5cd", "", "", "Fu Kung! (V0.14) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "60a61da9b2f43dd7e13a5093ec41a53d", "VentureVision, Dan Oliver", "VV2001", "Rescue Terra I (1982) (VentureVision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "60bbd425cb7214ddb9f9a31948e91ecb", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "60cd61a2dfccb0e2736434f9792c1672", "Amiga - Video Soft, Frank Ellis, Jerry Lawson", "2110", "3-D Havoc (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "60d304582d33e2957b73eb300a7495bb", "", "", "Jam Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "60e0ea3cbe0913d39803477945e9e5ec", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "PADDLES_IAXDR", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "613abf596c304ef6dbd8f3351920c37a", "", "", "Boring Pac-Man (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6141c095d0aee4e734bebfaac939030a", "Rainbow Vision - Suntek", "SS-017", "Mariana (1983) (Rainbow Vision) (PAL)", "AKA Seaquest", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61426cee013306e7f7367534ab124747", "", "", "One Blue Bar Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "615a3bf251a38eb6638cdc7ffbde5480", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61621a556ad3228f0234f5feb3ab135c", "", "", "Fu Kung! (V0.05 Cuttle Card Compattle Revision) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61631c2f96221527e7da9802b4704f93", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision) [different logo]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61719a8bdafbd8dab3ca9ce7b171b9e2", "", "", "Enduro (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61728c6cfb052e62a9ed088c5bf407ba", "", "", "Sprite Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "619de46281eb2e0adbb98255732483b4", "", "", "Time Warp (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61baadddc2c8f6e5faa57d4d0f285462", "", "", "208-in-1 MDM-Test (PAL) (127 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "61dbe94f110f30ca4ec524ae5ce2d026", "CCE", "C-820", "Space Invaders (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61e0f5e1cc207e98704d0758c68df317", "Star Game", "007", "Tennis (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "61ef8c2fc43be9a04fe13fdb79ff2bd9", "", "", "Gas Gauge Demo - Revisited (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6205855cc848d1f6c4551391b9bfa279", "", "", "Euchre (Release Candidate 2) (NTSC) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6238ac888871fec301d1b9fc4fc613c9", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "624e0a77f9ec67d628211aaf24d8aea6", "Panda", "108", "Sea Hawk (1983) (Panda)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "626d67918f4b5e3f961e4b2af2f41f1d", "Atari", "50008", "Diagnostic Test Cartridge 2.0 (1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6272f348a9a7f2d500a4006aa93e0d08", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "62899430338e0538ee93397867d85957", "Gameworld", "133-004", "Airlock (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "62921652f6634eb1a0940ed5489c7e18", "", "", "SCSIcide (V1.09) (2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" }, - { "62992392ea651a16aa724a92e4596ed6", "Eric Mooney", "", "Invaders by Erik Mooney (Beta) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "62d1f50219edf9a429a9f004c19f31b3", "JWDA, Todd Marshall", "", "Euro Gen (02-01-83) (JWDA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "62ee2b8f59e9cd6285bbdb674a952e8b", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype)", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "62f74a2736841191135514422b20382d", "", "", "Pharaoh's Curse (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "YES", "" }, - { "62ffd175cac3f781ef6e4870136a2520", "", "", "2600 Digital Clock (V x.xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63166867f75869a3592b7a94ea62d147", "", "", "Indy 500 (Hack) [a1]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "", "", "", "", "" }, - { "6333ef5b5cbb77acd47f558c8b7a95d3", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (8K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6337927ad909aa739d6d0044699a916d", "Jeffry Johnston", "", "Radial Pong - Version 2 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6339d28c9a7f92054e70029eb0375837", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6342afe9c9ad1b6120b8f6fb040d0926", "", "", "Move a Blue Blob Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6354f9c7588a27109c66905b0405825b", "Thomas Jentzsch", "", "Amidar DS (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6358f7f8bf0483402a080efccf250d61", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (Prototype)", "AKA Termite", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "635cc7a0db33773959d739d04eff96c2", "", "", "Minesweeper (V.90) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6362396c8344eec3e86731a700b13abf", "Panda", "109", "Exocet (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "637efac676ff063f2fbb0abff77c4fa5", "", "", "Noize Maker Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63811ed69bdbc35c69d8aa7806c3d6e9", "Atari", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "638cc82ea96f67674595ba9ae05da6c6", "Rainbow Vision - Suntek", "SS-011", "Super Ferrari (1983) (Rainbow Vision) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63a6eda1da30446569ac76211d0f861c", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63a7445b1d3046d3cdcdbd488dca38d9", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63c5fef3208bb1424d26cf1ab984b40c", "", "", "Analog Clock (V0.1) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63c7395d412a3cd095ccdd9b5711f387", "Eric Ball", "ELB005", "Skeleton+ (PAL)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63d6247f35902ba32aa49e7660b0ecaa", "", "", "Space War (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63e42d576800086488679490a833e097", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63e783994df824caf289b69a084cbf3e", "David Marli", "", "Fat Albert (David Marli) (Hack)", "Hack of Fast Food", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "63e9e612bbee31045f8d184a4e53f8ec", "ATARITALIA", "", "Moby Blues (2002) (ATARITALIA) (Hack)", "Hack of Mario Bros", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "640a08e9ca019172d612df22a9190afb", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "64198bb6470c78ac24fcf13fe76ab28c", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "643e6451eb6b8ab793eb60ba9c02e000", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL) [different tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "645bf7f9146f0e4811ff9c7898f5cd93", "Xonox - K-Tel Software - VSS, Robert Weatherby", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6468d744be9984f2a39ca9285443a2b2", "Atari, Ed Logg, Carol Shaw", "CX26163P", "Reversi (32 in 1) (1988) (Atari) (PAL)", "AKA Othello", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "647162cceb550fd49820e2206d9ee7e8", "", "", "Skeleton (NTSC) (2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "64b8e19c767191ccdc97acc6904c397b", "Jeffry Johnston", "", "Radial Pong - Version 6 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "64ca518905311d2d9aeb56273f6caa04", "CCE", "", "Cubo Magico (CCE)", "AKA Cubicolor", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "64d43859258dc8ca54949e9ff4174202", "Thomas Jentzsch", "", "Lilly Adventure (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "64fab9d15df937915b1c392fc119b83b", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (05-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "650df778c6ce22d3fd1a7c33c565bcc3", "Atari - GCC, Betty Ryan Tylko, Douglas B. Macrae", "CX2694", "Pole Position (1983) (Atari)", "Genesis controller (B is high gear, C is low gear, left difficulty switch swaps gear buttons)", "Hack of Pole Position", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" }, - { "651d2b6743a3a18b426bce2c881af212", "CCE", "C-812", "Pac Man (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6522717cfd75d1dba252cbde76992090", "Home Vision - Gem International Corp. - VDI", "VCS83102", "War 2000 (1983) (Home Vision) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6538e454b0498ad2befe1ef0f87815c0", "Joe Grand", "", "SCSIcide (v1.2) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" }, - { "65490d61922f3e3883ee1d583ce10855", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "65562f686b267b21b81c4dddc129d724", "", "", "Euchre (28-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "655c84e5b951258c9d20f0bf2b9d496d", "", "", "2600_2003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "656dc247db2871766dffd978c71da80c", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1981) (Sears)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "AUTO 60", "", "", "", "" }, - { "6588d192d9a8afce27b44271a2072325", "Bit Corporation", "R320", "Basketball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "65917ae29a8c9785bb1f2acb0d6aafd0", "", "", "Junkosoft One Year Demo (1999) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6596b3737ae4b976e4aadb68d836c5c7", "Digivision", "", "Defender (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "659a20019de4a23c748ec2292ea5f221", "Retroactive", "", "Qb (V2.05) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "65a6f1255fe22468a8bf84ff28a4d289", "Akor", "", "Super TV Boy (1995) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "65b106eba3e45f3dab72ea907f39f8b4", "Christian Software Development - HomeComputer Software, Dan Schafer, Glenn Stohel, Jon Tedesco - Sparrow", "GCG 1001T", "Music Machine, The (1983) (Sparrow)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "65ba1a4c643d1ab44481bdddeb403827", "Quelle", "876.013 4", "Katastrophen-Einsatz (1983) (Quelle) (PAL)", "AKA M.A.S.H.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "65bd29e8ab1b847309775b0de6b2e4fe", "Coleco, Ed English", "2667", "Roc 'n Rope (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "65c6406f5af934590097c8c032ebb482", "", "", "Three Hugger (Pave Demo) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6604f72a966ca6b2df6a94ee4a68eb82", "", "", "MegaMania (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "662eca7e3d89175ba0802e8e3425dedb", "", "", "Hangman Pac-Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66362890eb78d6ea65301592cce65f5b", "", "", "Euchre (13-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "663ef22eb399504d5204c543b8a86bcd", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "4L1720, 4L1721, 4L1722, 4L2276", "Wizard of Wor (1982) (CBS Electronics) (PAL)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" }, - { "664d9bfda6f32511f6b4aa0159fd87f5", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6651e2791d38edc02c5a5fd7b47a1627", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (04-05-1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "665b8f8ead0eef220ed53886fbd61ec9", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66706459e62514d0c39c3797cbf73ff1", "Video Gems", "VG-05", "Treasure Below (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6672de8f82c4f7b8f7f1ef8b6b4f614d", "Videospielkassette - Ariola", "PGP237", "Angeln I (Ariola) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "667a70b028f581d87648693b873bc962", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "668dc528b7ea9345140f4fcfbecf7066", "Gakken", "001", "Pooyan (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6697f177847c70505824422e76aad586", "", "", "Tennis (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "669840b0411bfbab5c05b786947d55d4", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66b89ba44e7ae0b51f9ef000ebba1eb7", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (01-18-1983) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66b92ede655b73b402ecd1f4d8cd9c50", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66bc1bef269ea59033928bac2d1d81e6", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "66c2380c71709efa7b166621e5bb4558", "Parker Brothers, Dave Engman, Dawn Stockbridge", "931509", "Tutankham (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66c4e0298d4120df333bc2f3e163657e", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66f49b3248791b9803fa3e2f4165d072", "Bit Corporation", "R320", "Football (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "66fcf7643d554f5e15d4d06bab59fe70", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6706a00f9635508cfeda20639156e66e", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "672012d40336b403edea4a98ce70c76d", "", "", "Spider Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "675ae9c23fa1aae376cea86cad96f9a5", "", "", "Poker Squares (V0.25) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "67631ea5cfe44066a1e76ddcb6bcb512", "", "", "Termool (Unknown) (PAL)", "AKA Turmoil", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "67684a1d18c85ffa5d82dab48fd1cb51", "Tigervision, Warren Schwader - Teldec", "7-003", "Threshold (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "678c1d71a1616d9d022f03d8545b64bb", "", "", "Demo Image Series #11 - Donald And Mario (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "67931b0d37dc99af250dd06f1c095e8d", "CommaVid, Irwin Gaines", "CM-004", "Room of Doom (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "679d30c7886b283cbe1db4e7dbe5f2a6", "Colin Hughes", "", "Puzzle (Colin Hughes) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "679e910b27406c6a2072f9569ae35fc8", "Data Age", "DA1002", "Warplock (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 40", "", "", "YES", "" }, - { "67bd3d4dc5ac6a42a99950b4245bdc81", "Retroactive", "", "Qb (2.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "67c05ae94bf8b83a666c3ae2c4bc14de", "Atari", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "67cdde4176e0447fc45a71e0a1cdd288", "Telegames - VSS, Ed Salvo", "5665 A016", "Glacier Patrol (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "67ce6cdf788d324935fd317d064ed842", "Retroactive", "", "Qb (V2.09) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "67cf913d1df0bf2d7ae668060d0b6694", "", "", "Hangman Monkey 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "67f90d74fd0b72fdc6d9b92436780ea9", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6803fa7c2c094b428b859a58dc1dd06a", "Retroactive", "", "Qb (0.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6805734a0b7bcc8925d9305b071bf147", "Bit Corporation", "PGP229", "Kung Fu (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Karate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "681206a6bde73e71c19743607e96c4bb", "", "", "Casino (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6833c26f385e866f3a0fa0dff311216e", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "683bb0d0f0c5df58557fba9dffc32c40", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "683dc64ef7316c13ba04ee4398e2b93a", "Ed Federmeyer", "", "Edtris (1995) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "68449e4aaba677abcd7cde4264e02168", "", "", "Horizonal Color Bars Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6847ce70819b74febcfd03e99610243b", "", "", "Ruby Runner 4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "68489e60268a5e6e052bad9c62681635", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "68597264c8e57ada93be3a5be4565096", "Data Age", "DA1005", "Bugs (1982) (Data Age)", "Uses the Paddle Controllers", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, - { "685e9668dc270b6deeb9cfbfd4d633c3", "CommaVid, Irwin Gaines - Ariola", "CM-004 - 712 004-720", "Room of Doom (1982) (CommaVid) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "68760b82fc5dcf3fedf84376a4944bf9", "CCE", "C-860", "Laser Gate (1983) (CCE)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "687c23224e26f81c56e431c24faea36d", "", "", "Qb (Simple Background Animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "68878250e106eb6c7754bc2519d780a0", "CCE", "C-809", "Squirrel (1983) (CCE)", "AKA Snail Against Squirrel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "68ac69b8e1ba83af8792f693f5ae7783", "Digivision", "", "Fathon (Digivision)", "AKA Fathom", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "68c80e7e1d30df98a0cf67ecbf39cc67", "Hozer Video Games", "", "Gunfight 2600 - One Step Forward & Two Steps Back (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "68c938a2a2b45c37db50509f1037fe6e", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "68cd2adc6b1fc9a1f263ab4561112f30", "Thomas Jentzsch", "", "Boulderdash Demo (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "68feb6d6ff63e80df1302d8547979aec", "", "", "Starfield Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "690a6049db78b9400c13521646708e9c", "King Tripod Enterprise Co.", "SS - 007", "Space Raid (King Tripod) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6913c90002636c1487538d4004f7cac2", "Atari - CCW", "CX26131", "Monster Cise (1984) (Atari) (Prototype)", "Uses the Keypad Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "691d67910b08b63de8631901d1887c1f", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "692202772d8b38ccf85a90c8003a1324", "", "", "Zi - The Flie Buster (2002) (Fernando Mora) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "693137592a7f5ccc9baae2d1041b7a85", "", "", "Qb (V2.02) (Stella) (2001) (Retroactive) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6936aa6763835f62ac13d1aaa79b9f91", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6979f30204149be3e227558cffe21c1d", "Atari", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6982854657a2cc87d712f718e402bf85", "Zellers", "", "Earth Attack (Zellers)", "AKA Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "69877da5caded48315e3e45882a303d5", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "698f569eab5a9906eec3bc7c6b3e0980", "SpkLeader", "", "Demons! (2003) (SpkLeader) (Hack)", "Hack of Phoenix", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "69974dd5d6420b90898cde50aec5ef39", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "69df0411d4d176e558017f961f5c5849", "CCE", "C-831", "Cosmic Ark (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "69e79b1352b9ee1754bbe63b4a7062c3", "Barry Laws Jr.", "", "Pink Floyd - The Wall (2003) (Barry Laws Jr.) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "69ebf910ab9b63e5b8345f016095003b", "", "", "Maze Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "69edfb4e1810a523311b3e250fc1e275", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "69fac82cd2312dd9ce5d90e22e2f070a", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a03c28d505bab710bf20b954e14d521", "", "", "Pressure Gauge 2 Beta (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a07836c382195dd5305ce61d992aaa6", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo) (Prototype)", "Uses the Paddle Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "6a091b8ffeacd0939850da2094b51564", "", "", "Vertically Scrolling Playfield (02-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a222c26bcece3a510ddda21398f72c6", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a2c68f7a77736ba02c0f21a6ba0985b", "Atari, Larry Wagner, Bob Whitehead", "", "Computer Chess (07-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a3b0c33cf74b1e213a629e3c142b73c", "Cody Pittman", "", "Cory The Interviewer (Cody Pittman) (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a76d5f0ed721639474aa9bbde69ebf0", "", "", "Play Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6a82b8ecc663f371b19076d99f46c598", "Activision, Larry Miller - Ariola", "EAX-026, EAX-026-04B, EAX-026-04I - 711 026-725", "Enduro (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a882fb1413912d2ce5cf5fa62cf3875", "Video Game Cartridge - Ariola", "TP-605", "Dragon Defender (Ariola) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6a8c6940d3be6fd01274363c4d4b298e", "", "", "Spy Hunter (Genesis)", "Genesis controller (C is oil/smoke)", "Hack of Spy Hunter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a9b30ca46b0dba9e719f4cbd340e01c", "", "", "Frostbite (Unknown) (PAL) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6a9e0c72fab92df70084eccd9061fdbd", "CCE", "C-835", "Beany Bopper (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6aa66e9c3eea76a0c40ef05513497c40", "", "", "Hangman Ghost Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6ac3fd31a51730358708c7fdc62487f8", "Matthias Jaap", "", "PC Invaders (Matthias Jaap) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6aca52e11b597ab84b33d5252e1cd9d1", "Bit Corporation", "R320", "Tac-Scan (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, - { "6ae4dc6d7351dacd1012749ca82f9a56", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125, CX26127", "Track and Field (1984) (Atari)", "Uses the Track & Field Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b01a519b413f8cfa2f399f4d2841b42", "", "", "Aphex Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b1fc959e28bd71aed7b89014574bdc2", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b4eb5b3df80995b8d9117cb7e9aeb3c", "Gameworld, J. Ray Dettling", "133-006", "Journey Escape (1983) (Gameworld) (PAL)", "AKA Rock 'n' Roll Escape", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6b683be69f92958abe0e2a9945157ad5", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Steven B. Sidley, Tom Sloper", "VC2007", "Entombed (1983) (U.S. Games)", "Released as Name That Game for a contest (winning name was Entombed)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6b6ca32228ae352b4267e4bd2cddf10c", "", "", "Pac-Man 4 (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b71f20c857574b732e7a8e840bd3cb2", "", "", "Frostbite (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b72b691ea86f61438ed0d84c4d711de", "", "", "Fishing Derby (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b75f8fa4fd011a6698c58315f83d2ac", "Thomas Jentzsch", "", "Sprintmaster DC (TJ)", "Uses the Driving Controllers, Hack of Sprintmaster (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" }, - { "6b7a56b6ac2ca4bf9254474bf6ed7d80", "", "", "Horizonal Color Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b7e1c11448c4d3f28160d2de884ebc8", "Zirok", "", "Fast Food (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6b8fb021bb2e1f1e9bd7ee57f2a8e709", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum) (PD) [a]", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6bb09bc915a7411fe160d0b2e4d66047", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6bb22efa892b89b69b9bf5ea547e62b8", "Dynacom", "", "Megamania (1982) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6bde3f6ac31aceef447ce57d4d2c2ec0", "Piero Cavina", "", "Mondo Pong V1 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "01", "", "", "", "" }, - { "6c128bc950fcbdbcaf0d99935da70156", "Digitel", "", "Volleyball (1983) (Digitel)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6c1553ca90b413bf762dfc65f2b881c7", "Quelle", "343.073 3", "Winterjagd (1983) (Quelle) (PAL)", "AKA Ski Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6c1f3f2e359dbf55df462ccbcdd2f6bf", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6c25f58fd184632ca76020f589bb3767", "Dynacom", "", "Beat 'Em & Eat 'Em (1983) (Dynacom)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "6c449db9bbbd90972ad1932d6af87330", "", "", "20 Sprites at Once Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6c658b52d03e01828b9d2d4718a998ac", "", "", "Hangman Invader Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6c76fe09aa8b39ee52035e0da6d0808b", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, - { "6c85098518d3f94f7622c42fd1d819ac", "Suntek", "SS-028", "Firebug (1983) (Suntek) (PAL)", "AKA Spinning Fireball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6c91ac51421cb9fc72c9833c4f440d65", "ITT Family Games", "554-33 375", "Cosmic Town (1983) (ITT Family Games) (PAL)", "AKA Base Attack (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6c9a32ad83bcfde3774536e52be1cce7", "", "", "Space Treat (NTSC) (13-08-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6cab04277e7cd552a3e40b3c0e6e1e3d", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (Prototype)", "AKA Targ", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6cbe945e16d9f827d0d295546ac11b22", "", "", "Gunfight 2600 - AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6ccd8ca17a0e4429b446cdcb66327bf1", "", "", "RPG Engine (12-05-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6cd1dc960e3e8d5c5e0fbe67ab49087a", "", "", "Vertical Playfield Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6cd506509e8fd5627f55603780e862a8", "Greg Troutman", "", "Dark Mage (SuperCharger) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6ce2110ac5dd89ab398d9452891752ab", "Funvision - Fund. International Co.", "", "Persian Gulf War (Funvision)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6cea35ded079863a846159c3a1101cc7", "", "", "Atlantis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6ceb7d6a54e9a5e62d26874d1cc88dbc", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6cf054cd23a02e09298d2c6f787eb21d", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6d218dafbf5a691045cdc1f67ceb6a8f", "Robin Harbron", "", "6 Digit Score Display (1998) (Robin Harbron) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6d475019ea30d0b29f695e9dcfd8f730", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 2) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6d74ebaba914a5cfc868de9dd1a5c434", "", "", "Fortress (Smooth Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6d842c96d5a01967be9680080dd5be54", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6d8a04ee15951480cb7c466e5951eee0", "Zirok", "", "Kanguru (1983) (Zirok)", "AKA Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6d9afd70e9369c2a6bff96c4964413b7", "", "", "Time Warp (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6dda84fb8e442ecf34241ac0d1d91d69", "Atari - GCC, Douglas B. Macrae", "CX2677", "Dig Dug (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6de924c2297c8733524952448d54a33c", "CCE", "C-1006", "Moon Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6dfad2dd2c7c16ac0fa257b6ce0be2f0", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6e179eee3d4631a7434d40cf7aeea6e8", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6e19428387686a77d8c8d2f731cb09e0", "", "", "Purple Cross Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6e372f076fb9586aff416144f5cfe1cb", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6e59dd52f88c00d5060eac56c1a0b0d3", "Atari, Bob Smith", "CX2648", "Video Pinball (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6e5d5ba193d2540aec2e847aafb2a5fb", "Retroactive", "", "Qb (2.14) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6e7ed74082f39ad4166c823765a59909", "", "", "Poker Squares (V0.14) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6e7efb0ed13ec28a00d19572de9c9f03", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6eb10fd23c7161751d18b9e8484c0004", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco) (Prototype)", "AKA Smurf, Smurf Action", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6ed5012793f5ddf4353a48c11ea9b8d3", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "01 70", "", "", "", "" }, - { "6ed6bda5c42b2eb7a21c54e5b3ace3e3", "Canal 3 - Intellivision", "", "Ice Hockey (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6efe876168e2d45d4719b6a61355e5fe", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6f084daf265599f65422ef4173b69bc7", "", "", "Music Kit (V2.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6f2aaffaaf53d23a28bf6677b86ac0e3", "U.S. Games Corporation - Vidtec - JWDA, Garry Kitchen", "VC1001", "Space Jockey (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6f3e3306da2aa6e74a5e046ff43bf028", "", "", "Defender Arcade (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6f744f14aac04f7e1ea0d3f4bafcb3e4", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a3]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6f74ed915ffe73b524ef0f63819e2a1d", "Eckhard Stolberg", "", "An Exercise In Minimalism (V2) (1999) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6fa0ac6943e33637d8e77df14962fbfc", "Imagic, Rob Fulop", "", "Cubicolor (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6fac680fc9a72e0e54255567c72afe34", "", "", "Superman (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6fbd05b0ad65b2a261fa154b34328a7f", "", "", "Boardgame Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6fc0176ccf53d7bce249aeb56d59d414", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6fc27a9233fc69d28d3f190b4ff80f03", "", "", "UFO #6 (Charles Morgan) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6fc394dbf21cf541a60e3b3631b817f1", "Imagic, Bob Smith", "720020-2A, IA3611P", "Dragonfire (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "6fd7c7057eeab273b29c7aafc7429a96", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6fe67f525c39200a798985e419431805", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "6ff4156d10b357f61f09820d03c0f852", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 60", "", "", "", "" }, - { "6ffc95108e5add6f9b8abcaf330be835", "Charles Morgan", "", "TP Bug (Charles Morgan) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "700a786471c8a91ec09e2f8e47f14a04", "Activision", "", "Hard-Head (1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "703d32062436e4c20c48313dff30e257", "", "", "Moving Maze Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "703f0f7af350b0fa29dfe5fbf45d0d75", "Bit Corporation", "P460", "4 Game in One Dark Green (1983) (BitCorp) (PAL)", "Rodeo Champ, Bobby is Going Home, Open Sesame, Festival", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "705fe719179e65b0af328644f3a04900", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "706e3cc4931f984447213b92d1417aff", "", "", "Joustpong (06-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "707ecd80030e85751ef311ced66220bc", "", "", "Double-Height 6-Digit Score Display (Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7096a198531d3f16a99d518ac0d7519a", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "709910c2e83361bc4bf8cd0c20c34fbf", "Rainbow Vision - Suntek", "SS-006", "Netmaker (1983) (Rainbow Vision) (PAL)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "70a43fbdb1c039283ee5048d99842469", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "70a8480cfaf08776e5420365732159d2", "Rob Kudla", "", "Horizontally Scrolling Playfield Thing (Rob Kudla) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "70ce036e59be92821c4c7fd735ec6f68", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "70d14c66c319683b4c19abbe0e3db57c", "", "", "Oystron (V2.82) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "710497df2caab69cdcc45e919c69e13f", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "713fde2af865b6ec464dfd72e2ebb83e", "", "", "Challenge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "71464c54da46adae9447926fdbfc1abe", "M Network - INTV - APh Technological Consulting, Bruce Pedersen", "MT5663", "Lock 'n' Chase (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "714e13c08508ee9a7785ceac908ae831", "Home Vision - Gem International Corp. - VDI", "VCS83123", "Parachute (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "715dbf2e39ba8a52c5fe5cdd927b37e0", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "715dd9e0240638d441a3add49316c018", "Atari", "", "128-in-1 Junior Console (Chip 2 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7187118674ff3c0bb932e049d9dbb379", "Zirok", "", "Keystone Keypers (1983) (Zirok)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "718ae62c70af4e5fd8e932fee216948a", "Data Age, J. Ray Dettling", "112-006", "Journey Escape (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "718ee85ea7ec27d5bea60d11f6d40030", "Thomas Jentzsch", "", "Ghostbusters II (1992) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7197b6cbde6ecd10376155e6b848e80d", "Piero Cavina", "", "Multi-Sprite Game V2.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "71b193f46c88fb234329855452dfac5b", "Digitel", "", "Atlantis (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "71d005b60cf6e608d04efb99a37362c3", "Atari, Larry Kaplan", "CX2643", "Codebreaker (1978) (Atari) (PAL) (4K) [a]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "71f09f128e76eb14e244be8f44848759", "Funvision - Fund. International Co.", "", "Time Race (Funvision) (PAL)", "AKA Time Warp", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "71f8bacfbdca019113f3f0801849057e", "Atari, Dan Hitchens", "CX26126", "Elevator Action (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72097e9dc366900ba2da73a47e3e80f5", "", "", "Euchre (15-06-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "721a5567f76856f6b50a6707aa8f8316", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72305c997f2cec414fe6f8c946172f83", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "724613effaf7743cbcd695fab469c2a8", "", "", "Super-Ferrari (Unknown)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "728152f5ae6fdd0d3a9b88709bee6c7a", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72876fd7c7435f41d571f1101fc456ea", "Quelle", "688.383 9", "Die Ente und der Wolf (1983) (Quelle) (PAL)", "AKA Pooyan", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72a46e0c21f825518b7261c267ab886e", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72a5b5052272ac785fa076709d16cef4", "", "", "KC Munckin (29-01-2003) (J. Parlee)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72a63bcb5eb31bd0fd5e98ed05125ec1", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72bda70c75dfa2365b3f8894bace9e6a", "Thomas Jentzsch", "", "Atlantis (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72d0acb5de0db662de0360a6fc59334d", "", "", "Cosmic Ark (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72db1194b1cc7d45b242f25eb1c148d3", "", "", "Pac-Man (1981) (Atari) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72fd08deed1d6195942e0c6f392e9848", "HES", "0701-406", "2 Pak Special - Wall Defender, Planet Patrol (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "72ffbef6504b75e69ee1045af9075f66", "Atari, Richard Maurer - Sears", "CX2632 - 49-75153", "Space Invaders (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73158ea51d77bf521e1369311d26c27b", "Zellers", "", "Challenge (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73521c6b9fed6a243d9b7b161a0fb793", "Atari, Tom Reuterdahl", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "736388d73198552d77d423962000006f", "Dactari", "", "Tennis (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73a710e621d44e97039d640071908aef", "", "", "Barber Pole Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73aa02458b413091ac940c0489301710", "Rainbow Vision - Suntek", "SS-016", "Boom Bang (1983) (Rainbow Vision) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73b4e8f8b04515d91937510e680214bc", "", "", "Rubik's Cube Demo 3 (24-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73c545db2afd5783d37c46004e4024c2", "CBS Electronics - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf - Schtroumpfs (1983) (CBS Electronics) (PAL)", "Pitufo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73c839aff6a055643044d2ce16b3aaf7", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73cb1f1666f3fd30b52b4f3d760c928f", "", "", "Mines of Minos (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "73e66e82ac22b305eb4d9578e866236e", "Jone Yuan Telephonic Enterprise Co", "", "Unknown Datatech Game (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "73efa9f3cbe197f26e0fb87132829232", "CCE", "C-858", "Tennis (1983) (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "74023e0f2e739fc5a9ba7caaeeee8b6b", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "740a7fa80f52cc7287ba37677afb6b21", "", "", "Double Dragon (PAL) (Genesis)", "Genesis controller (C is jumpkick)", "Hack of Double Dragon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "740b47df422372fbef700b42cea4e0bf", "", "", "Dizzy Wiz (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "740f39e71104e90416c29a73560b9c6b", "Atari", "TE016643", "Diagnostic Test Cartridge 2.6P (1982) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7412f6788087d7e912c33ba03b36dd1b", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "742de93b8d849220f266b627fbabba82", "", "", "SCSIcide (25-02-2001) (Chris Wilkson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7450ae4e10ba8380c55b259d7c2b13e8", "", "", "Register Twiddler Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7454786af7126ccc7a0c31fcf5af40f1", "", "", "Phantom Tank (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7465b06b6e25a4a6c6d77d02242af6d6", "Atari", "CX26193", "8 in 1 (01-16-92) (Atari) (Prototype)", "Game 2 is Centipede, but doesn't work", "Prototype", "", "", "8IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7481f0771bff13885b2ff2570cf90d7b", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "749fec9918160921576f850b2375b516", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "74d072e8a34560c36cacbc57b2462360", "Sancho - Tang's Electronic Co.", "TEC002", "Seahawk (1982) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "74ebaca101cc428cf219f15dda84b6f8", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "74f623833429d35341b7a84bc09793c0", "Zellers", "", "Radar (Zellers)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75028162bfc4cc8e74b04e320f9e6a3f", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (02-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7511c34518a9a124ea773f5b0b5c9a48", "", "", "Donkey Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75169c08b56e4e6c36681e599c4d8cc5", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network)", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "YES", "", "", "AUTO 55", "", "", "", "" }, - { "752da1c0acd7d132ccfb0b1067f53cf6", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "753375d183c713cfa0aa7298d1f3067b", "Arcadia Corporation, Steve Hales, Stephen Harland Landrum", "AR-4102", "Suicide Mission (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7550b821ee56fb5833dca2be88622d5a", "", "", "Multiple Moving Objects Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75511bb694662301c9e71df645f4b5a7", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "755fed16b48e81de05130708a905d00d", "SnailSoft", "", "Comitoid beta 3 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "756ca07a65a4fbbedeb5f0ddfc04d0be", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7574480ae2ab0d282c887e9015fdb54c", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7576dd46c2f8d8ab159d97e3a3f2052f", "Goliath - Hot Shot", "83-112", "Time Machine (1983) (Goliath) (PAL)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "757f529026696e13838364dea382a4ed", "Activision, David Crane - Ariola", "EAX-014, PAX-014, EAX-014-04B, EAX-014-04I - 711 014-720", "Grand Prix (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75893a9dc5de4b91cc426959b82a1da0", "Champ Games", "CG-02-P", "Conquest Of Mars (2010) (PAL60)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75a303fd46ad12457ed8e853016815a0", "ZiMAG - Emag - Vidco", "715-111 - GN-060", "Immies & Aggies (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75b22fdf632d76e246433db1ebccd3c4", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75b557be7f08db84ec5b242207b9f241", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75e276ba12dc4504659481c31345703a", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75e8d8b9e9c5c67c2226dbfd77dcfa7d", "", "", "2600 Digital Clock (V b1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75ea128ba96ac6db8edf54b071027c4e", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "75ea60884c05ba496473c23a58edf12f", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) (PAL) [a]", "ROM must be started in bank 0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "75ee371ccfc4f43e7d9b8f24e1266b55", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (11-09-1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7608abdfd9b26f4a0ecec18b232bea54", "Atari, Bob Whitehead", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7623a639a6fffdb246775fe2eabc8d01", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7628d3cadeee0fd2e41e68b3b8fbe229", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7648e72a5b5899076688df18a1ddcf72", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) (Prototype)", "Black Box", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "764ce6801f28a9ad36f11de3e57c053b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "76809eb1ee0db8a318308a5cdda0f4e2", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "769ddc995dbb9edb8167efcea9f34a7c", "", "", "H.E.R.O. (Genesis)", "Genesis controller (B is laser, C is dynamite)", "Hack of H.E.R.0.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "76a9bf05a6de8418a3ebc7fc254b71b4", "VideoSoft, Jerry Lawson, Dan McElroy", "VS1008", "Color Bar Generator (1984) (VideoSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "76c685d1a60c0107aa54a772113a2972", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "76c88341017eae660efc6e49c4b6ab40", "", "", "Indiana Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "76ee917d817ef9a654bc4783e0273ac4", "Otto Versand", "311377", "Fox & Goat (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Nuts", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "76f53abbbf39a0063f24036d6ee0968a", "M Network, David Akers, Joe 'Ferreira' King, Patricia Lewis Du Long, Jeff Ratcliff - INTV", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "76f66ce3b83d7a104a899b4b3354a2f2", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "77057d9d14b99e465ea9e29783af0ae3", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision)", "AKA Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7732e4e4cc2644f163d6650ddcc9d9df", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7761418d46af069b8cd80c29fe6cd814", "Dion Olsthoorn", "RetroN 77 edition", "Amoeba Jump (R77) (DionoiD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7778ac65d775a079f537e97cbdad541c", "", "", "Spider Fighter (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "777aece98d7373998ffb8bc0b5eff1a2", "", "", "2600 Collison Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "77887e4192a6b0a781530e6cf9be7199", "Atari", "CX2604", "Space War (1978) (Atari) [b1]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "77be57d872e3f5b7ecf8d19d97f73281", "", "", "Basketball (208 in 1) (Unknown) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "77cd9a9dd810ce8042bdb9d40e256dfe", "Kyle Pittman", "", "Evil Dead (2003) (Kyle Pittman) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "77d0a577636e1c9212aeccde9d0baa4b", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "PADDLES_IAXDR", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "78297db7f416af3052dd793b53ff014e", "", "", "Poker Squares (V0.17) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7836794b79e8060c2b8326a2db74eef0", "", "", "RIOT RAM Test (26-11-2002) (Dennis Debro)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "784176346e9422733d55c427230e5bad", "Activision, Alex DeMeo", "", "Title Match Pro Wrestling (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "784abfdb31d5341e5bd404d8d2a71c3b", "Alessandro Ciceri", "", "MagiCard (TV format conversion) (alex_79) (PAL)", "MagiCard PAL conversion hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7860716fa5dbc0fffab93fb9a4cb4132", "", "", "Hangman Monkey Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7867ee819b53d69cfcfe740f7ddca574", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "787ebc2609a31eb5c57c4a18837d1aee", "Prescott", "", "Vault Assault (19xx) (Prescott)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "78821ef76ebc3934850d1bc1b9e4f4b0", "HES - Activision", "542", "Hot Action Pak - Ghostbusters, Tennis, Plaque Attack (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "78963290052fd17c6c7998305ab3a6a0", "", "", "Push (V0.08) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "78b84cfb1c57b0488d674d2374e656e6", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "78c2de58e42cd1faac2ea7df783eaeb3", "", "", "Fu Kung! (V0.07) (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "79004f84bdeee78d142e445057883169", "CCE", "C-830", "Planet Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "791bc8aceb6b0f4d9990d6062b30adfa", "Activision, David Crane - Ariola", "EAX-018, EAX-018-04B, EAX-018-04I - 711 018-725", "Pitfall! (1982) (Activision) (PAL)", "Abenteuer im Urwald (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "791c88eca9836af8c34bf32b07cb58a7", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2 (PAL60)", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "7926083ad423ed685de3b3a04a914315", "Barry Laws Jr.", "", "Face Invaders 2 (Barry Laws Jr.) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "792b1d93eb1d8045260c840b0688ec8f", "Kroko", "", "3E Bankswitch Test (TIA @ $00)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7972e5101fa548b952d852db24ad6060", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "798b8921276eec9e332dfcb47a2dbb17", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "798cc114f1623c14085868cd3494fe8e", "", "", "Pins Revenge (Atari Freak 1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7991e1797e5e9f311fd957e62d889dff", "Joe Grand", "", "SCSIcide (v1.1) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" }, - { "7996b8d07462a19259baa4c811c2b4b4", "", "", "Math Gran Prix (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "79ab4123a83dc11d468fb2108ea09e2e", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "AZ-037-04", "Beamrider (1984) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "79b649fb812c50b4347d12e7ddbb8400", "", "", "Red Pong Number 2 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "79c27f90591e3fdc7d2ed020ecbedeb3", "CCE", "C-815", "Seaquest (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "79d4af56036ec28f298cad964a2e2494", "", "", "Hangman Pac-Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "79d6f61da3c64688ac8e075667f8a39f", "", "", "Tie-Fighters (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "79e5338dbfa6b64008bb0d72a3179d3c", "M Network - INTV, David Akers, Patricia Lewis Du Long", "MT4313", "Star Strike (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "79fcdee6d71f23f6cf3d01258236c3b9", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a09299f473105ae1ef3ad6f9f2cd807", "Atari, Steve Wright", "CX2616P", "Pele's Soccer (1981) (Atari) (PAL)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a2af383014f5d810ad26d322823549d", "", "", "FlickerSort Demo (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a5463545dfb2dcfdafa6074b2f2c15e", "20th Century Fox Video Games - Sirius Software, Mark Turmell", "11007", "Turmoil (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a63d7ea3f2851bcf04f0bb4ba1a3929", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a64a8b727c8215d945e37d565ca95a5", "Atari, Warren Robinett", "CX2606", "Slot Racers (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a64b5a6e90619c6aacf244cdd7502f8", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 1) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a7f6ab9215a3a6b5940b8737f116359", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7a93d0c029eaa72236523eedc3f19645", "", "", "20 Sprites at Once Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ab0917107b6ec768a5ebaadf28c497a", "", "", "Santa's Helper (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "7ab210f448de518fa61a5924120ba872", "", "", "Fortress (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ab2f190d4e59e8742e76a6e870b567e", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 65", "", "", "", "" }, - { "7ac4f4fb425db38288fa07fb8ff4b21d", "Goliath", "83-213", "Space Eagle (1983) (Goliath) (PAL)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ad257833190bc60277c1ca475057051", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7ad782952e5147b88b65a25cadcdf9e0", "Imagic, Dave Johnson", "720119-1A, 03211", "Kwibble (1983) (Imagic) (Prototype)", "AKA Quick Step! Beta", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7adbcf78399b19596671edbffc3d34aa", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7af40c1485ce9f29b1a7b069a2eb04a7", "Amiga - Video Soft", "3120", "Mogul Maniac (1983) (Amiga)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b24bfe1b61864e758ada1fe9adaa098", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b33407b2b198af74906b936ce1eecbb", "King Atari", "", "Ghostbuster 2 (King Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7b3cf0256e1fa0fdc538caf3d5d86337", "CommaVid, Joseph Biel", "CM-009", "Stronghold (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b43c32e3d4ff5932f39afcb4c551627", "Syncro, Daniel Wolf", "", "Kamikaze Saucers (1983) (Syncro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b4be337ac4d73eda75c848355f6f480", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b5207e68ee85b16998bea861987c690", "Atari, Carol Shaw", "CX26163P", "3-D Tic-Tac-Toe (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b57318c489ff178f7ff500da1ec9e8c", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b6f3348dbf71ada88db0fdaf7feefe0", "", "", "3-D Corridor (Pink Spiral) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b79beb378d1b4471def90ceccf413de", "", "", "Pitfall Cupcake (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b7b4ac05232490c28f9b680c72998f9", "Zellers", "", "Freeway (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b8a481e0c5aa78150b5555dff01f64e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7b938c7ddf18e8362949b62c7eaa660a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ba07d4ea18bf3b3245c374d8720ad30", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7bb286cb659d146af3966d699b51f509", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (04-03-1989) (Atari) (Prototype)", "AKA Saving Mary", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7bc4fd254ec8c0a25a13f02fd3f762ff", "Retroactive", "", "Qb (V1.00) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7c00e7a205d3fda98eb20da7c9c50a55", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo)", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7c4a499d343fca0cef2d59dd16af621a", "", "", "Poker Card Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7c757bb151269b2a626c907a22f5dae7", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7c7a4a2d505c2d0c75337c44711d8d54", "Atari, Warren Robinett", "", "Elf Adventure (04-22-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7c9b3b8b25acf2fe3b8da834f69629c6", "", "", "I Robot (1984) (Atari) (Prototype) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ca7a471d70305c673fedd08174a81e8", "Tim Snider", "", "Venture II (2001) (Tim Snider)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7cc77f6745e1f2b20df4a4327d350545", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ccf350354ee15cd9b85564a2014b08c", "", "", "Big Dig (13-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7cd379da92c93679f3b6d2548617746a", "", "", "Demo Image Series #5 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7cd900e9eccbb240fe9c37fa28f917b5", "Jone Yuan Telephonic Enterprise Co", "", "Bi! Bi! (Jone Yuan) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ced6709f091e79a2ab9575d3516a4ac", "Activision, Steve Cartwright - Ariola", "EAX-027 - 711 027-722", "Plaque Attack (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7cedffa0db65d610568b90aeca705ac6", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7cf3a9267cdb95aba91abc5838d61cc5", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d0b49ea4fe3a5f1e119a6d14843db17", "Gameworld, J. Ray Dettling", "133-008", "Frankenstein's Monster (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d1034bcb38c9b746ea2c0ae37d9dff2", "Atari, Brad Stewart", "", "Morse Code Tutor (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d3cdde63b16fa637c4484e716839c94", "CCE", "", "Road Runner (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d483b702c44ee65cd2df22cbcc8b7ed", "Atari, Warren Robinett", "", "Elf Adventure (05-25-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d5c3b7b908752b98e30690e2a3322c2", "Dactari - Milmar", "", "Freeway (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d726fa494f706784bafeb1b50d87f23", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-27-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d8287e8423a56d4f8cef10435d97179", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d903411807704e725cf3fafbeb97255", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (Reaction) (1982) (Imagic) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d93071b3e3616093a6b5a98b0315751", "", "", "Gunfight 2600 - Music & Bugfixes 2 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d940d749e55b96b7b746519fa06f2de", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7d9c96b215d1941e87b6fb412eb9204f", "", "", "Othello (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7da9de8d62fcdd3a2c545b2e720c2a61", "CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7dbc8fa2e488e3f6b87fbe0f76c5b89f", "Ed Federmeyer", "", "Sound X (1996) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7dc03a1f56d0e6a8aae3e3e50d654a08", "", "", "Hozer Video Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7dcbfd2acc013e817f011309c7504daa", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7dd9c5284422f729066ab22a284c8283", "CCE", "C-833", "Target Practice (1983) (CCE) [a]", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ded20e88b17c8149b4de0d55c795d37", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.26)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "DRIVING", "", "", "", "", "", "", "", "" }, - { "7dfd100bda9abb0f3744361bc7112681", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7e2fe40a788e56765fe56a3576019968", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "AK-050-04", "Double Dragon (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7e464186ba384069582d9f0c141f7491", "PlayAround - J.H.M.", "206", "General Re-Treat (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7e4783a59972ae2cd8384f231757ea0b", "Atari - Imagineering, Dan Kichen", "CX26139P", "Crossbow (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7e51a58de2c0db7d33715f518893b0db", "CBS Electronics, E.F. Dreyer, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7e52a95074a66640fcfde124fffd491a", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673", "Phoenix (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7e7c4c59d55494e66eef5e04ec1c6157", "Baroque Gaming (Brian Eno)", "", "Warring Worms (2002) (Baroque Gaming)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7e8aa18bc9502eb57daaf5e7c1e94da7", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" }, - { "7e9da5cb84d5bc869854938fe3e85ffa", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7e9f088e15b2af9ff3411991393e6b1f", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (12-28-1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7eab0284a0cd1043461d446a08d08cec", "Jone Yuan Telephonic Enterprise Co", "", "Basic Math (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ead257e8b5a44cac538f5f54c7a0023", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7eaf009a892f03d90682dc1e67e85f07", "Fabrizio Zavagli", "", "Bounce! (18-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7eafc9827e8d5b1336905939e097aae7", "Atari, Mark R. Hahn", "", "Elk Attack (1987) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7eba20c2291a982214cc7cbe8d0b47cd", "Imagic, Dave Johnson", "720119-1A, 03211", "Quick Step! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ed61a18cebdeca0a93be1f5461731e5", "Dactari", "", "Skiing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ed7130a6e4020161836414332b11983", "", "", "Fu Kung! (V0.05 Cuttle Card Compatible) (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7edc8fcb319b3fb61cac87614afd4ffa", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ef3ca08abde439c6ccca84693839c57", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "7ef74879d7cb9fa0ef161b91ad55b3bb", "CCE", "", "Vanguard (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f0209cfcc3d181715463f4d6451cecf", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (05-15-1983) (Atari) (Prototype)", "AKA RealSports Driving", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f07cd2e89dda5a3a90d3ab064bfd1f6", "Videospielkassette - Ariola", "PGP234", "Boxen (Ariola) (PAL)", "AKA Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f430c33044e0354815392b53a9a772d", "HES", "773-891", "2 Pak Special - Cavern Blaster, City War (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f525b07bc98080cc8950f7284e52ede", "Atari", "", "128-in-1 Junior Console (Chip 4 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f54fa6aa824001af415503c313262f2", "HES", "", "Boom Bang (HES) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f6533386644c7d6358f871666c86e79", "CommaVid, Irwin Gaines", "CM-008", "Cakewalk (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f790939f7eaa8c47a246c4283981f84", "", "", "This Planet Sucks Demo 3 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7f819454734ddf93f83fefcffcd3e212", "Jone Yuan Telephonic Enterprise Co", "", "Outlaw (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7f9fbe3e00a21ea06e6ae5e0e5db2143", "", "", "Skate Boardin' (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7fcd1766de75c614a3ccc31b25dd5b7a", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "7fcd5fb59e88fc7b8473c641f44226c3", "CCE", "C-807", "Space Tunnel (1983) (CCE)", "AKA O Tunel Espacial", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ff53f6922708119e7bf478d7d618c86", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "7ffc2d80fd49a124808315306d19868e", "Ishido", "", "Domino (Ishido) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "801ba40f3290fc413e8c816c467c765c", "Hozer Video Games", "", "Gunfight 2600 - Westward Ho! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "803393ed29a9e9346569dd1bf209907b", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (02-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "804ed85eadf1ce3e93721547cbea7592", "CCE", "", "Fishing Derby (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8055b9c2622136fd91edfea6df642daf", "Activision", "", "Unknown Activision Game #1 (1983) (Activision) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "805f9a32ef97ac25f999a25014dc5c23", "SnailSoft", "", "Balthazar (SnailSoft)", "AKA Babylon 5", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8068e07b484dfd661158b3771d6621ca", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "807841df228ee8aab0a06ee639ce5a8a", "Coleco - Project Guild - GMA, Michael Green, Anthony R. Henderson, Gary Littleton", "2455", "Turbo (1982) (Coleco) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "807a8ff6216b00d52aba2dfea5d8d860", "John Payson", "", "Strat-O-Gems Deluxe (2005) (J. Payson)", "Uses the AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "" }, - { "808c3b1e60ee0e7c65205fa4bd772221", "CCE", "", "Defender (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "80cd42881e670e4b74a9ccd10d0d7b2e", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "80cec82239913cb8c4016eb13749de44", "David Marli", "", "Invaders from Space by David Marli (Space Invaders Hack)", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "80dcbe1b55f12be731a224a53ee4ad5f", "Bit Corporation", "R320", "Amidar (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "80e1410ec98089e0733cc09e584dba4b", "Dynamics", "DY-293005", "Jumping Jack (1983) (Dynamics) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "80e52315919bd8a8b82a407ccd9bb13f", "", "", "Euchre (Jul 28) (2002) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "80e5400470ac788143e6db9bc8dd88cf", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-XX-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "80f7bf7418a462e8687ecefeaf6eb9c2", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8101efafcf0af32fedda4579c941e6f4", "", "", "Okie Dokie (4K) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "81073d0377a2badef8d5e74fc44fc323", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL60) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "8108162bc88b5a14adc3e031cf4175ad", "Suntek", "SS-030", "Skydiver (1983) (Suntek) (PAL)", "AKA Parachute", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8108ad2679bd055afec0a35a1dca46a4", "", "", "Maze Craze (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" }, - { "810d8952af5a6036fca8d0c4e1b23db6", "Tiger Vision - Eram", "", "Keystone (Tiger Vision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "81254ebce88fa46c4ff5a2f4d2bad538", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "81341f00b61ab37d19d1529f483d496d", "", "", "Fu Kung! (V0.04) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "813985a940aa739cc28df19e0edd4722", "Imagic, Bob Smith", "720000-201, 720102-1B, IA3201", "Star Voyager (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "81414174f1816d5c1e583af427ac89fc", "Thomas Jentzsch", "", "Treasure Below (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "814210c0e121f7dbc25661b93c06311c", "", "", "Joustpong (16-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "81591a221419024060b890665beb0fb8", "Atari, Carla Meninsky, Ed Riddle", "CX2611, CX2611P", "Indy 500 (1977) (Atari) (PAL)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" }, - { "8190b403d67bf9792fe22fa5d22f3556", "", "", "Sky Diver (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "819aeeb9a2e11deb54e6de334f843894", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "81a010abdba1a640f7adf7f84e13d307", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "81b3bf17cf01039d311b4cd738ae608e", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "M8776, M8793", "Gorf (1982) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "81f4f0285f651399a12ff2e2f35bab77", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "822a950f27ff0122870558a89a49cad3", "", "", "Space Jockey (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "82337e5fe0f418ca9484ca851dfc226a", "Thomas Jentzsch", "", "Robot City (V1.0) (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "826481f6fc53ea47c9f272f7050eedf7", "Imagic, Dennis Koble", "720103-1A, IA3203", "Atlantis II (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "827a22b9dffee24e93ed0df09ff8414a", "CBS Electronics, Stuart Ross", "", "Wings (10-10-1983) (CBS Electronics) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8290daea8391f96d7c8e1482e184d19c", "Eckhard Stolberg", "", "Frame Timed Sound Effects (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "82bf0dff20cee6a1ed4bb834b00074e6", "Suntek", "SS-035", "Panda (1983) (Quest) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "82c25d1c35e6ac6f893d1d7c2fc2f9c8", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "82de957d155fc041fc6afb8315a28550", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco) (Prototype)", "2K", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "82e7aab602c378cffdd8186a099e807e", "", "", "Space Robot (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "82efe7984783e23a7c55266a5125c68e", "CCE", "C-837", "Pizza Chef (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "834a2273e97aec3181ee127917b4b269", "Quelle", "043.151 0, 874.382 5", "Die hungrigen Froesche (1983) (Quelle) (PAL)", "AKA Frogs and Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "835759ff95c2cdc2324d7c1e7c5fa237", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11011", "M.A.S.H (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8372eec01a08c60dbed063c5524cdfb1", "", "", "Cross Force (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8388d6fe59c38c0b3a6ab2c58420036a", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (12-06-1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "83b8c01c72306d60dd9b753332ebd276", "", "", "Bank Heist (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "83bdc819980db99bf89a7f2ed6a2de59", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "83d15fb9843d9f84aa3710538403f434", "", "", "Gunfight 2600 - Release Candidate (2001) (MP) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "83e1b9f22f29259679e1018bc04cc018", "Bit Corporation", "R320", "Fast Eddie (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "83f05ececae8be59ba1e51135f4bdcbf", "", "", "Demo Image Series #13 - Mario (4K Interleaved Chronocolour) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "83f50fa0fbae545e4b88bb53b788c341", "Atari, Larry Kaplan - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "83fafd7bd12e3335166c6314b3bde528", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "840a5a2eaea24d95d289f514fd12f9bb", "", "", "GBImprov (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "841057f83ce3731e6bbfda1707cbca58", "Champ Games", "CG-04-N", "Super Cobra Arcade (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "841b7bc1cad05f5408302308777d49dc", "Activision", "", "Unknown Activision Game (10-22-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "84290e333ff7567c2380f179430083b8", "Imagic, Dave Johnson", "13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "843435eb360ed72085f7ab9374f9749a", "Joe Grand", "", "SCSIcide (1.31) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" }, - { "84535afb9a69712ec0af4947329e08b8", "CCE", "C-868", "Bingo (1983) (CCE) (PAL)", "AKA Dice Puzzle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8454ed9787c9d8211748ccddb673e920", "Froggo", "FG1002", "Spiderdroid (1987) (Froggo)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8490e1014c2baa0d3a3a08854e5d68b3", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "84db818cd4111542a15c2a795369a256", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "850ffd5849c911946b24544ea1e60496", "", "", "Invasion (07-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "851cc1f3c64eaedd10361ea26345acea", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85227160f37aaa29f5e3a6c7a3219f54", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8530caaaf40acbdcd118c282b5f8a37a", "", "", "This Planet Sucks Demo 2 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8538c5e3ee83267774480649f83fa8d6", "", "", "Escape Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "853c11c4d07050c22ef3e0721533e0c5", "", "", "Oink! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85470dcb7989e5e856f36b962d815537", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85478bb289dfa5c63726b9153992a920", "", "", "Candi (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "854b68b93e7123a3be42b5a2a41f75d7", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85502d69fe46b7f54ef2598225678b47", "Jone Yuan Telephonic Enterprise Co", "", "Super-Ferrari (Jone Yuan)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85564dd0665aa0a1359037aef1a48d58", "ITT Family Games", "554-33 367", "Laser Base (1983) (ITT Family Games) (PAL) [a]", "AKA The End of the World (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8556b42aa05f94bc29ff39c39b11bff4", "Atari, Craig Nelson - Sears", "CX2617 - 49-75183", "Backgammon (1979) (Atari)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 80", "", "", "", "" }, - { "855a42078b14714bcfd490d2cf57e68d", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8597f66dd37d9c855663804669d69d7a", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85a4133f6dcf4180e36e70ad0fca0921", "CCE", "C-827", "Chopper Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85b1bca93e69f13905107cc802a02470", "Atari, Craig Nelson", "CX2617, CX2617P", "Backgammon (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 80", "", "", "", "" }, - { "85bbefb90e16bf386b304c1e9a1f6084", "Champ Games", "CG-02-P", "Conquest Of Mars (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85e48d68c8d802e3ba9d494a47d6e016", "", "", "Ship Demo (V 15) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "85e564dae5687e431955056fbda10978", "Milton Bradley Company - Renaissance Technology, Ty Roberts", "4362", "Survival Run (1983) (Milton Bradley)", "AKA Cosmic Commander", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "86128001e69ab049937f265911ce7e8a", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Lochjaw (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8619da7f6796cedff59e5aa20712fb4e", "Thomas Jentzsch", "", "Sadistroids (v1.2) (2003) (Thomas Jentzsch)", "Supports Driving Controller in right port", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "YES", "30" }, - { "862cf669cbced78f9ed31a5d375b2ebe", "", "", "Gunfight 2600 - Flicker acceptance (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8644352b806985efde499ae6fc7b0fec", "CCE", "C-801", "Mr. Postman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8654d7f0fb351960016e06646f639b02", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83106", "Ski Hunt (1983) (Home Vision) (PAL)", "AKA Skiiing Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "866e5150c995c4ae5172e5207ba948c7", "Canal 3 - Intellivision", "", "Stampede (Canal 3) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "869abe0426e6e9fcb6d75a3c2d6e05d1", "", "", "Stampede (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "86b4aa76bbeb70e1a4f9211a9880ba8e", "", "", "Incoming (1 Player Version) (05-11-2002) (Ben Larson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8712cceec5644aacc2c21203d9ebe2ec", "Retroactive", "", "Qb (V0.10) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8726c17ee7b559cb7bf2330d20972ad0", "", "", "Cave Demo (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "873fb75a7788ba0f4ae715229a05545e", "", "", "Euchre (Improved Colors) (PAL) (26-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8747ba79cd39fa83a529bb26010db21b", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [different speed and colors]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8749a0d088df25218c149dc325abc7ca", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a5]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "874c76726f68c166fcfac48ce78eef95", "", "", "Red Pong Number 2 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8764462d7d19a33b0717af22b99fc88f", "CCE", "", "Sky Jinks (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "87662815bc4f3c3c86071dc994e3f30e", "Intellivision Productions - M Network, Patricia Lewis Du Long, Stephen Tatsumi", "", "Swordfight (1983) (Intellivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "876a953daae0e946620cf05ed41989f4", "Retroactive", "", "Qb (V2.08) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "877a5397f3f205bf6750398c98f33de1", "Erik Eid", "", "Euchre (Beta) (PAL) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8786c1e56ef221d946c64f6b65b697e9", "20th Century Fox Video Games, David Lubar", "11015", "AKA Space Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8786f229b974c393222874f73a9f3206", "Activision, Larry Miller - Ariola", "EAX-021, EAX-021-04I - 711 021-720", "Spider Fighter (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8786f4609a66fbea2cd9aa48ca7aa11c", "Goliath", "5", "Open Sesame (1983) (Goliath) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "87b460df21b7bbcfc57b1c082c6794b0", "Dennis Debro", "", "Climber 5 (20-03-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "87b6a17132fc32f576bc49ea18729506", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "87bea777a34278d29b3b6029833c5422", "Thomas Jentzsch", "", "Polaris (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "87e79cd41ce136fd4f72cc6e2c161bee", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "87f020daa98d0132e98e43db7d8fea7e", "20th Century Fox Video Games - Sirius, David Lubar", "11001", "Worm War I (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "883258dcd68cefc6cd4d40b1185116dc", "Activision, David Crane - Ariola", "EAZ-030, EAZ-030-04B, EAZ-030-04I - 711 030-725", "Decathlon (1983) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8874b68751fd2ba6d3306a263ae57a7d", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 1) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8885d0ce11c5b40c3a8a8d9ed28cefef", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, - { "888debb162d7d1ae71025b4ab794257f", "", "", "Interleaved ChronoColour - Nude Art (17-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "88a6c9c88cb329ee5fa7d168bd6c7c63", "CCE", "C-1007", "Jungle Hunt (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "88d300a38bdd7cab9edad271c18cd02b", "Funvision - Fund. Int'l Co.", "", "Pac Kong (Funvision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "88d7b6b3967de0db24cdae1c7f7181bd", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "88d8a1accab58cf1abb043613cf185e9", "Ultravison", "", "Sabotage (Ultravison)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "88dce4037471424bb38ab6841aaa8cab", "", "", "Double-Height 6-Digit Score Display (Two Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "88ed87c011f699dd27321dbe404db6c8", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "88f74ec75ef696e7294b7b6ac5ca465f", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8905d54f48b8024fc718ed643e9033f7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (05-24-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "890c13590e0d8d5d6149737d930e4d95", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8917f7c1ac5eb05b82331cf01c495af2", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8933976f2029c0d8492ebd8f4eb21492", "", "", "Synthcart Plus (09-02-2003) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8953bc11352d794431d3303e31d3b892", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (02-17-1983) (Tigervision) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "896ec58f26e930e02f5e4f046602c3a1", "", "", "Synthcart (Beta) (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "898143773824663efe88d0a3a0bb1ba4", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision) [FE]", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "898748d5eaac3164b0391a64ae1e0e32", "", "", "Hangman Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "898b5467551d32af48a604802407b6e8", "Bit Corporation", "PG208", "Snail Against Squirrel (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "89a65b83203980d5d4d60f52a584a5b8", "", "", "Marble Craze (PAL) (02-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "89a68746eff7f266bbf08de2483abe55", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "89afff4a10807093c105740c73e9b544", "", "", "Pooyan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "89eaba47a59cbfd26e74aad32f553cd7", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8a159ee58b2f0a54805162984b0f07e5", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8a183b6357987db5170c5cf9f4a113e5", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (01-11-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8a42e2c7266439d8997a55d0124c912c", "", "", "Hangman Invader Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8a49cf1785e3dea2012d331a3ad476e1", "", "", "Boulderdash (10 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8a6c84f481acf42abcb78ba5064ad755", "128-in-1 Junior Console", "", "Street Racer (128-in-1 Junior Console) (PAL) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 75", "", "", "", "" }, - { "8a8e401369e2b63a13e18a4d685387c6", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8a9d874a38608964f33ec0c35cab618d", "Chris Cracknell", "", "Rescue Bira Bira (Chris Cracknell)", "Hack of Jungle Fever", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8a9d953ac3db52a313a90d6a9b139c76", "", "", "Hangman Invader Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8aad33da907bed78b76b87fceaa838c1", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8ac18076d01a6b63acf6e2cab4968940", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8af58a9b90b25907da0251ec0facf3b8", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8b04e9d132b8e30d447acaa6bd049c32", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8b40a9ca1cfcd14822e2547eaa9df5c1", "Parker Brothers - Western Technologies, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8b504b417c8626167a7e02f44229f0e7", "Retroactive", "", "Qb (V1.00) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8b556c3d9ca8e5e6e665bd759b93ffae", "", "", "Synthcart (2002) (Paul Slocum) (PAL) [!]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8b5b1e3a434ebbdc2c2a49dc68f46360", "CBS Electronics - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8b7ca29a55432f886cee3d452fb00481", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8b8152d6081f31365406cb716bd95567", "Atari", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8b8789c6669a4cee86c579a65332f852", "Digivision", "", "Plaque Attack (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8bbfd951c89cc09c148bfabdefa08bec", "UA Limited", "", "Pleiades (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8bc0d2052b4f259e7a50a7c771b45241", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) [a]", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8bd8f65377023bdb7c5fcf46ddda5d31", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8bebac614571135933116045204f0f00", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ) (PAL)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "TRAKBALL", "", "", "", "", "", "", "YES", "" }, - { "8c103a79b007a2fd5af602334937b4e1", "Thomas Jentzsch", "", "Laser Base (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8c136e97c0a4af66da4a249561ed17db", "", "", "Poker Squares (V0.27) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8c146c61817edd376bc1354c7f1ddc63", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8c1cc284edba691139d6626d062c606f", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL60) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "8c2fa33048f055f38358d51eefe417db", "Home Vision - Gem International Corp. - VDI", "VCS83137", "Teddy Apple (1983) (Home Vision) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8c36ed2352801031516695d1eeefe617", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8c7e5e2329f4f4e06cbcc994a30fd352", "Data Age", "DA1004", "Airlock (1982) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8c8a26ed57870daba8e13162d497bad1", "HES", "", "2 Pak Special - Dolphin, Oink (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8c8b15b3259e60757987ed13cdd74d41", "Supergame", "71", "River Raid (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8c941fa32c7718a10061d8c328909577", "Digivision", "", "River Raid (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8ccaa442d26b09139685f5b22bf189c4", "Retroactive", "", "Qb (V1.01) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8ccf63141a029603572d1056e772990e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8cd26dcf249456fe4aeb8db42d49df74", "Atari - Imagineering, Dan Kichen", "CX26139", "Crossbow (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8ce9126066f2ddd5173e9f1f9ce1494e", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "TRAKBALL", "", "", "", "", "", "", "YES", "" }, - { "8cf0d333bbe85b9549b1e6b1e2390b8d", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8d00a38f4c8f8800f1c237215ac243fc", "", "", "3-D Corridor (Green) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8d1e2a6d2885966e6d86717180938f87", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8d8b7d7b983f75debbdaac651e814768", "", "", "Demo Image Series #15 - Three Marios (PAL) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8d9a06101ebb0f147936356e645309b8", "", "", "Grid Pattern Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8da51e0c4b6b46f7619425119c7d018e", "Atari - Imagineering, David Lubar", "CX26183", "Sentinel (1991) (Atari)", "Uses the Light Gun Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8db152458abaef3cfa7a4e420ddbda59", "", "", "Keystone Kapers (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8df4be9ddc54ac363b13dc57ceaf161a", "Scott Stilphen", "", "Asteroids SS (Scott Stilphen) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8e0ab801b1705a740b476b7f588c6d16", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e42674972d6805068fc653e014370fd", "", "", "Skeleton (PAL) (15-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e48ea6ea53709b98e6f4bd8aa018908", "CBS Electronics, Stuart Ross", "", "Wings (06-03-1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8e4cd60d93fcde8065c1a2b972a26377", "Imagic, Dan Oliver", "720118-2A, 13208, EIX-007-04I", "Laser Gates (1983) (Imagic) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e4fa8c6ad8d8dce0db8c991c166cdaa", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e512ad4506800458f99dec084fc2c64", "Bob Montgomery, Nathan Strum", "", "Reindeer Rescue (2005)", "2005 AtariAge Holiday Cart", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e7241bfc8380aac3c0ef1b6881cdded", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (09-01-81) (Atari) (Prototype)", "Time Freeze", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8e737a88a566cc94bd50174c2d019593", "Quelle", "343.173 1", "Feuerwehr im Einsatz (1983) (Quelle) (PAL)", "AKA Fire Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e822b39a71c84ac875f0107fb61d6f0", "", "", "Hangman Ghost Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e879aa58db41edb67cbf318b77766c4", "Thomas Jentzsch", "", "Cosmic Commuter (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8e887d1ba5f3a71ae8a0ea16a4af9fc9", "", "", "Skeleton (V1.1) (PAL) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8ed5a746c59571feb255eaa7d6d0cf98", "", "", "Carnival (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8ed73106e2f42f91447fb90b6f0ea4a4", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8ee3f64dc0f349adc893fe93df5245d8", "", "", "Euchre (20-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8ef96ace4a1d6dfb65926c1e868b0188", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f33bce5ba1053dcf4cea9c1c69981e4", "", "", "Jawbreaker (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f53a3b925f0fd961d9b8c4d46ee6755", "", "", "Astrowar (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f5ac5139419c5d49bacc296e342a247", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (12-22-1982) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f60551db6d1535ef0030f155018c738", "", "", "Space War (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f613ea7c32a587d6741790e32872ddd", "", "", "Troll Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f88309afad108936ca70f8b2b084718", "Spectravision - Spectravideo - Quelle", "SA-203 - 413.223 9", "Cross Force (1982) (Spectravision) (PAL)", "AKA Kreuzfeuer (Cross Fire)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f90590dba143d783df5a6cff2000e4d", "", "", "Gopher (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8f98519a91dbbf4864f135a10050d9ed", "Silvio Mogno", "", "Rainbow Invaders (non-playable demo) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8fa47e5242776e841df7e708b12eb998", "", "", "Sea Hawk (Genesis)", "Genesis controller (C drops bomb)", "Hack of Sea Hawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8fbabaa87941cdf3a377c15e95bdb0f3", "", "", "Meteor Smasher (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8fe00172e7fff4c1878dabcf11bb8dce", "Quelle", "689.302 8", "Hili Ball (1983) (Quelle) (PAL)", "AKA Racquetball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "8febdd9142960d084ab6eeb1d3e88969", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "8fffc8f15bb2e6d24e211884a5479aa5", "Retroactive", "", "Qb (V1.00) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9007c3cbb55ce05ad7d1c34d4906750a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (03-18-1983) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9048ccb7e0802cd8fa5bfc2609f292d8", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9057694dce8449521e6164d263702185", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "90578a63441de4520be5324e8f015352", "Bit Corporation", "PGP204", "Open Sesame (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9072c142728a3a3d994956d03bfacba2", "Fabrizio Zavagli", "", "Crash Dive (Fabrizio Zavagli) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "90a3c3255f2a54225cdcb50831f8793a", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "90b1799dddb8bf748ee286d22e609480", "", "", "Ship Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "90b647bfb6b18af35fcf613573ad2eec", "AtariAge (Chris Walton)", "", "Juno First (2009)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "YES", "" }, - { "90ccf4f30a5ad8c801090b388ddd5613", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "90d77e966793754ab4312c47b42900b1", "Imagic, Brad Stewart", "720105-2A, IA3400P, EIX-005-04I", "Fire Fighter (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "90f502cbf4438a95f69f848cef36eb64", "Digitel", "", "River Raid II (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "910dd9bf98cc5bc080943e5128b15bf5", "", "", "Gunfight 2600 - Improved AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "911d385ee0805ff5b8f96c5a63da7de5", "Thomas Jentzsch", "", "Jammed (V0.1) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "913d5d959b5021f879033c89797bab5e", "", "", "Robot Player Graphic (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "914a8feaf6d0a1bbed9eb61d33817679", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "91925abce3a29e33b6a8b81482f4f5af", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9193b6fff6897d43274741d4f9855b6d", "", "", "M.A.S.H (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "91a3749ff7b7e72b7fa09e05396a0e7b", "", "", "Gunfight 2600 - Final Run Part 2 (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "91b007f33f9b790be64f57220ec52e80", "Jone Yuan Telephonic Enterprise", "", "Laser Blast (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "91c2098e88a6b13f977af8c003e0bca5", "Atari - GCC", "CX2676", "Centipede (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "91d1c82ceaf8af2add3973a3c34bc0cb", "", "", "Starfield Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "91f0a708eeb93c133e9672ad2c8e0429", "", "", "Oystron (V2.9) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "91fdb6541f70c40b16aabf8308123be8", "", "", "Interlacing Game (19-08-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9222b25a0875022b412e8da37e7f6887", "Panda", "106", "Dice Puzzle (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9245a84e9851565d565cb6c9fac5802b", "Bomb - Onbase", "CA282", "Great Escape (1983) (Bomb)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "927d422d6335018da469a9a07cd80390", "Activision, Carol Shaw - Ariola", "EAX-020, EAX-020-04B, EAX-020-04I - 711 020-720", "River Raid (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9281eccd7f6ef4b3ebdcfd2204c9763a", "Retroactive", "", "Qb (2.15) (Retroactive) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9295570a141cdec18074c55dc7229d08", "Telegames", "7045 A015", "Bump 'n' Jump (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "929e8a84ed50601d9af8c49b0425c7ea", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp) (PAL)", "AKA Dishaster, Dancing Plates, Tanzende Teller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "92a1a605b7ad56d863a56373a866761b", "U.S. Games Corporation - Western Technologies, Dave Hampton", "VC2006", "Raft Rider (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "92d1b6cb8a1b615266c4088a58464779", "Bit Corporation", "R320", "Fishing Derby (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "92d1f6ac179ebe5963868d6bc1bdda8d", "HES", "498", "Smash Hit Pak - Frogger, Boxing, Seaquest, Skiing, Stampede (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "92e72f7cc569584c44c9530d645ae04e", "Canal 3 - Intellivision", "", "Spider Fighter (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "931b91a8ea2d39fe4dca1a23832b591a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9333172e3c4992ecf548d3ac1f2553eb", "Konami", "RC 101-X 02", "Strategy X (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93420cc4cb1af1f2175c63e52ec18332", "Tim Snider", "", "Blair Witch Project (Tim Snider) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9364ad51c321e0f15c96a8c0aff47ceb", "Atari, Rob Fulop", "CX2638", "Missile Command (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "936ef1d6f8a57b9ff575dc195ee36b80", "", "", "Pac Kong (Unknown)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "936f555b4b1a2cd061b659ff63f4f5f2", "HES, David Lubar", "535", "My Golf (1990) (HES) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "937736d899337036de818391a87271e0", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-12-1983) (Atari) (Prototype)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "939ce554f5c0e74cc6e4e62810ec2111", "ZiMAG - Emag - Vidco", "711-111 - GN-020", "Dishaster (1983) (ZiMAG)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "93acd5020ae8eb5673601e2edecbc158", "Chris Cracknell", "", "Video Time Machine (Chris Cracknell)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93b9229fc0ea4fb959d604f83f8f603c", "Thomas Jentzsch", "", "Amidar DS (Fast Enemies) (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93c4b910f7649b3e998bb6d8527c6f4a", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype) [fixed]", "Fix for un-initialized 'X' register", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93c52141d3c4e1b5574d072f1afde6cd", "Imagic, Mark Klein", "720112-1A, 03213", "Subterranea (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93c8d9d24f9c5f1f570694848d087df7", "Digivision", "", "Galaxian (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93c9f9239a4e5c956663dd7affa70da2", "Quelle", "626.610 0", "Billard (1983) (Quelle) (PAL)", "AKA Trick Shot", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "93db185c3b3dc382f3aecd6a2fea7fd9", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93dc15d15e77a7b23162467f95a5f22d", "CCE", "", "Sky Jinks (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93e276172b521c4491097f8b1393eea7", "Atari", "", "Diagnostic Test Cartridge 4.2 (06-01-1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "93eb1795c8b1065b1b3d62bb9ec0ccdc", "JSK", "", "Custer's Viagra (JSK) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "94102febc53b4a78342d11b645342ed4", "", "", "Joustpong (14-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9433770890f087bfcf3e50122694d8c0", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9436b7ad131b5a1f7753ce4309ba3dee", "Kyle Pittman", "", "War of The Worlds (Kyle Pittman) (Hack)", "Hack of Defender", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "943798452ceba9357e2c56303cadb4f7", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.28)", "", "New Release, supports BoosterGrip and Genesis (switched by Color/B+W)", "", "", "", "", "", "", "", "JOYSTICK", "DRIVING", "", "", "", "", "", "", "", "" }, - { "9446940866c9417f210f8552cf6c3078", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL60) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "94507dee401b0a072a481c00d7699ffe", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9469d18238345d87768e8965f9f4a6b2", "CCE", "", "Ms. Pac-Man (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "947317a89af38a49c4864d6bdd6a91fb", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "94b92a882f6dbaa6993a46e2dcc58402", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "94d90f63678e086f6b6d5e1bc6c4c8c2", "Digivision", "", "Seaquest (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "94e3fbc19107a169909e274187247a9d", "", "2402-044-01", "2-in-1 Freeway and Tennis (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "94e4c9b924286038527f49cdc20fda69", "Retroactive", "", "Qb (V2.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "94e7cc6342d11e508e7e8b2ddf53c255", "", "", "Missile Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "94ff6b7489ed401dcaaf952fece10f67", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-31-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "951e8cec7a1a1d6c01fd649e7ff7743a", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9526e3db3bdfbc27989a9cbfd0ee34bf", "", "", "Atari Logo Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "95351b46fa9c45471d852d28b9b4e00b", "Atari, Tom Rudadahl", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "955c408265ad6994f61f9b66657bbae9", "", "", "Quadrun (Video Conversion) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "956496f81775de0b69a116a0d1ad41cc", "CCE", "", "Alien (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "956b99511c0f47b3a11d18e8b7ac8d47", "", "", "Bones (Arcade Golf Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "95956108289a917f80667eccd3ce98a9", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "95a69cf8c08ef1522b050529464f0bca", "", "", "Grid Pattern Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "95a89d1bf767d7cc9d0d5093d579ba61", "PlayAround - J.H.M.", "204", "Lady in Wading (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "95e1d834c57cdd525dd0bd6048a57f7b", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "95e542a7467c94b1e4ab24a3ebe907f1", "Suntek", "SS-021", "Dragon Defender (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "95fd6097dc27c20666f039cfe34f7c69", "", "", "Oh No! (Version 1) (17-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "961112b74a920a5242e233480326c356", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "962ffd3eaf865230a7a312b80e6c5cfd", "Imagic, Wilfredo 'Willy' Aguilar, Michael Becker, Rob Fulop", "13205", "Fathom (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "96662271ae50b6859017bffbdda75525", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo (2011)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "96670d0bf3610da2afcabd8e21d8eabf", "", "", "Boring Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "966b11d3c147d894dd9e4ebb971ea309", "", "", "Marble Craze Song (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "966c955e4aaca7082d9ffb9a68e3f3ed", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9671b658286e276cc4a3d02aa25931d2", "", "", "Hangman Ghost Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "968efc79d500dce52a906870a97358ab", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "969b968383d9f0e9d8ffd1056bcaef49", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "96bcb3d97ce4ff7586326d183ac338a2", "", "", "Revenge of the Apes (Hack) [h2]", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "96e798995af6ed9d8601166d4350f276", "20th Century Fox Video Games - Videa, David Ross", "11029", "Meltdown (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "96eccc2277043508a6c481ea432d7dd9", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ) (PAL)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "ATARIMOUSE", "", "", "", "", "", "", "YES", "" }, - { "96f806fc62005205d851e758d050dfca", "", "", "Push (V0.05) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "97184b263722748757cfdc41107ca5c0", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9718b85ac5a55cbc7348963c63ffa35a", "Robby", "", "Demon Attack (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "972486110933623039a3581db308fda6", "", "", "Xeno Plus (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "97327d6962f8c64e6f926f79cd01c6b9", "", "", "Jawbreaker (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "977294ae6526c31c7f9a166ee00964ad", "Atari - GCC, Douglas B. Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9784290f422e7aeeab4d542318bd9a1f", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" }, - { "97842fe847e8eb71263d6f92f7e122bd", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-1A, 03206", "Solar Storm (1983) (Imagic)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, - { "97933c9f20873446e4c1f8a4da21575f", "", "", "Racquetball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "97a9bb5c3679d67f5c2cd17f30b85d95", "Atari", "", "Colors (1980) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "97cd63c483fe3c68b7ce939ab8f7a318", "Thomas Jentzsch", "", "Robot City (V0.21) (15-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "97d0151beb84acbe82aa6db18cd91b98", "Steve Engelhardt", "", "Lunar Attack (2002) (Steve Engelhardt) (Hack)", "Hack of Z-Tack", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "97d079315c09796ff6d95a06e4b70171", "Activision, Garry Kitchen", "AZ-032", "Pressure Cooker (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "97e47512f89e79818d988d078dc90410", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "97f4da9f1031486f4e588f1e53572e53", "SpiceWare - Darrell Spice Jr.", "", "Draconian", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9813b9e4b8a6fd919c86a40c6bda8c93", "Atari", "CX26177", "Ikari Warriors (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9831efc7f4cb8ffb4df0082bab2f07a3", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9848b5ef7a0c02fe808b920a2ac566d2", "Skyworks Technology Inc.", "", "Baseball (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9853089672116117258097dbbdb939b7", "Hozer Video Games", "", "Gunfight 2600 - Cowboy Hair (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98555b95cb38e0e0b22b482b2b60a5b6", "", "", "Spinning Fireball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "98ba601a60172cb46c5bf9a962fd5b1f", "", "", "Gorilla Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98ccd15345b1aee6caf51e05955f0261", "Retroactive", "", "Qb (V2.03) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "98e5e4d5c4dd9a986d30fd62bd2f75ae", "", "", "Air-Sea Battle (Unknown) (Hack) (4K)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98e6e34af45a0664597972c3bb31180f", "", "", "Space Instigators (V1.7) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98e7caaab8ec237558378d2776c66616", "Bradford W. Mott", "", "HMOVE Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98ea10c47c13f1b3306c7b13db304865", "", "", "Jam Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98ec0fa4199b9c01f7b8fa3732e43372", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98ef1593624b409b9fb83a1c272a0aa7", "CCE", "C-831", "Cosmic Ark (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98f63949e656ff309cefa672146dc1b8", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "98fa3ad778a668a79449350de4b3b95b", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9905f9f4706223dadee84f6867ede8e3", "HES", "", "Challenge (HES) (PAL)", "Surfer's Paradise if right difficulty = 'A'", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9912d06eea42200a198dd3e2be18c601", "Imagic, Michael Greene", "IA3312", "No Escape! (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "991d57bbcd529ad62925098e0aec1241", "", "", "Gunfight 2600 - The Final Kernel (MP) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9945a22f60bbaf6d04a8d73b3cf3db75", "Activision, Dan Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9947f1ebabb56fd075a96c6d37351efa", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics)", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "A", "", "", "BOOSTERGRIP", "BOOSTERGRIP", "", "", "", "", "", "", "", "" }, - { "9962034ea7b3d4a905d0991804670087", "", "", "Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9989f974c3cf9c641db6c8a70a2a2267", "Eckhard Stolberg", "", "Colours Selector (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "99a24d7bb31d49b720b422550b32c35f", "", "", "Hangman Ghost Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "99ac89241365b692255ba95d745edd91", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (18-03-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "99f7c6c26046bbe95f1c604b25da8360", "SnailSoft", "", "Comitoid beta 2 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9a01115206f32eb0b539c7e5a47ccafa", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9a165c39af3f050fdee6583fdfcdc9be", "Zirok", "", "Mario Bros. (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9a21fba9ee9794e0fadd7c7eb6be4e12", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9a25b3cfe2bbb847b66a97282200cca2", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, - { "9a4274409216ff09ecde799f2a56ac73", "CCE", "C-801", "Mr. Postman (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9ab72d3fd2cc1a0c9adb504502579037", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9ad362179c2eea4ea115c7640b4b003e", "", "", "Barnstorming (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" }, - { "9ad36e699ef6f45d9eb6c4cf90475c9f", "Imagic, Dennis Koble", "720103-1A, 720103-1B, IA3203, IX-010-04", "Atlantis (1982) (Imagic)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9aeb5206c5bf974892a9cc59f1478db3", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9af615951e9719df2244bc77fc50cb95", "Dactari - Milmar", "", "Defender (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9afdfe1cff7f37f1c971fe3f0c900606", "Funvision - Fund. International Co.", "", "Plug Attack (Funvision)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9b150a42fc788960fbb4cbe250259ee2", "Kroko", "", "3E Bankswitch Test (TIA @ $40)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9b21d8fc78cc4308990d99a4d906ec52", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9b246683f44c963a50e41d6b485bee77", "", "", "Boring (PAL) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9bb136b62521c67ac893213e01dd338f", "Xonox - Beck-Tech", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9bd4e0d5f28ba6da417c26649171f8e4", "", "", "Hangman Pac-Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9be58a14e055b0e7581fc4d6c2f6b31d", "", "", "Adventure (Color Scrolling) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9c27ef3bd01c611cdb80182a59463a82", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9c40bf810f761ffc9c1b69c4647a8b84", "", "", "2 in 1 - Frostbite, River Raid (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9c6d65bd3b477aace0376f705b354d68", "", "", "RPG Kernal (18-04-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9c6faa4ff7f2ae549bbcb14f582b70e4", "U.S. Games Corporation, Garry Kitchen, Paul Willson - Vidtec", "VC1002", "Sneak 'n Peek (1982) (U.S. Games)", "AKA Hide 'n Seek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9c6fd6ed3599978ab7b6f900484b9be6", "Andrew Wallace", "", "Laseresal 2002 (PAL60) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9c729017dd2f9ccbadcb511187f80e6b", "", "", "J-Pac (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9c7fa3cfcaaafb4e6daf1e2517d43d88", "", "", "PIEROXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9ca2deb61318eba4fb784d4bf7441d8b", "", "", "Purple Bar Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9cbb07f1993a027bc2f87d5205457ec9", "", "", "Eckhard Stolberg's Scrolling Text Demo 1 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d0befa555f003069a21d2f6847ad962", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d1556ae5890398be7e3d57449774b40", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d2938eb2b17bb73e9a79bbc06053506", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d2f05d0fe8b2dfcf770b02eda066fc1", "", "", "Push (V0.06) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d33d31fb1de58c5460d8a67b57b36da", "", "", "Star Voyager (Genesis)", "Genesis controller (C is secondary lasers)", "Hack of Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d37a1be4a6e898026414b8fee2fc826", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5665", "Super Challenge Baseball (1982) (M Network)", "AKA Big League Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d4bc7c6fe9a7c8c4aa24a237c340adb", "Dennis Debro", "", "Climber 5 (16-04-2003) (Dennis Debro)", "For Philly Classic 4", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d522a3759aa855668e75962c84546f7", "Atari, Tom Rudadahl", "CX2634, CX2634P", "Golf (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9d7f04618bb4043f531d087e3aaa7ac8", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9de0d45731f90a0a922ab09228510393", "20th Century Fox Video Games - Sirius, Mark Turmell", "11003", "Fast Eddie (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9dec0be14d899e1aac4337acef5ab94a", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9e01f7f95cb8596765e03b9a36e8e33c", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9e135f5dce61e3435314f5cddb33752f", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9e192601829f5f5c2d3b51f8ae25dbe5", "PlayAround - J.H.M.", "201", "Cathouse Blues (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9e2c7299c69b602443d327c7dad51cbf", "Charles Morgan", "", "Xaxyrax Road (Charles Morgan) (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9e437229136f1c5e6ef4c5f36178ed18", "Funvision - Fund. International Co.", "", "Grand Prize (Funvision)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9e5007131695621d06902ab3c960622a", "Sega", "", "Tac Scan (1983) (Sega) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "YES", "" }, - { "9e792a59f8795664cbaaff1ba152d731", "", "", "Bullet Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9e904e2eaa471c050c491289b8b80f60", "", "", "How to Draw a Playfield II (1997) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9ea8ed9dec03082973244a080941e58a", "Eric Mooney, Piero Cavina", "", "INV+", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9ec1b259a1bcffa63042a3c2b3b90f0a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9eca521db1959156a115dee85a405194", "", "", "Fu Kung! (V0.08) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9ed0f2aa226c34d4f55f661442e8f22a", "", "", "Nuts (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9eeb40f04a27efb1c68ba1d25e606607", "Kyle Pittman", "", "Rambo II (2003) (Kyle Pittman) (Hack)", "Hack of Double Dragon", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9efa877a98dd5a075e058214da428abb", "Hozer Video Games", "", "SCSIcide (1.32) (Hozer Video Games)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" }, - { "9efb4e1a15a6cdd286e4bcd7cd94b7b8", "20th Century Fox Video Games, John W.S. Marvin", "", "Planet of the Apes (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9f2d58dce1b81c6ba201ed103507c025", "", "", "Fu Kung! (V0.02) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9f48eeb47836cf145a15771775f0767a", "Atari, Warren Robinett", "CX2620", "Basic Programming (1979) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9f5096a6f1a5049df87798eb59707583", "20th Century Fox Video Games, Mark Klein", "11036", "Entity, The (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9f52271759f8a2004d207b2247ae0bb3", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (03-12-84) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9f59eddf9ba91a7d93bce7ee4b7693bc", "Thomas Jentzsch", "", "Montezuma's Revenge (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9f8fad4badcd7be61bbd2bcaeef3c58f", "Parker Brothers, Charlie Heath", "PB5330", "Reactor (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "9f901509f0474bf9760e6ebd80e629cd", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "9f93734c68f6479eb022cab40814142e", "", "", "Push (V0.07) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9f982421b9b4320ede00fe4aa2e812f4", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "9f9ee0f60c119c831e80694b6678ca1a", "Jeffry Johnston", "", "Radial Pong - Version 8 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9fa0c664b157a0c27d10319dbbca812c", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "9fc2d1627dcdd8925f4c042e38eb0bc9", "Atari - GCC, John Allred, Mike Feinstein", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "E68E28752D3C54EDD3CCDA42C27E320C", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a0028f057d496f22b549fd8deecc6f78", "Joe Grand", "", "SCSIcide Pre-release 6 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a00ec89d22fcc0c1a85bb542ddcb1178", "CCE", "C-1012", "Phoenix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a00ee0aed5c8979add4c170f5322c706", "Barry Laws Jr.", "", "Egghead (Barry Laws Jr.) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a0185c06297b2818f786d11a3f9e42c3", "", "", "International Soccer (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a025a8f83a42a4d6d46c4887e799bfac", "Hozer Video Games", "", "Gunfight 2600 - Descissions had to be made (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a0297c4788f9e91d43e522f4c561b4ad", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "a0563dd6d8215c38c488fbbd61435626", "", "", "Ship Demo (V 1501) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a0675883f9b09a3595ddd66a6f5d3498", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a075ad332942740c386f4c3814925ece", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a0d502dc8b90b1d7daa5f6effb10d349", "", "", "Demo Image Series #5 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a0e2d310e3e98646268200c8f0f08f46", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a100eff2d7ae61ca2b8e65baf7e2aae8", "David Marli", "", "Muncher (David Marli) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a11099b6ec24e4b00b8795744fb12005", "Activision - Bobco, Robert C. Polaro", "EAK-049-04B", "Rampage! (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a1403fef01641dcd3980cac9f24d63f9", "Dactari - Milmar", "", "Atlantis (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a14d8a388083c60283e00592b18d4c6c", "", "", "Tunnel Demo (28-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a15b5831a1fab52e4c416068c85ec011", "Hozer Video Games", "", "Gunfight 2600 - The Good, The Bad, The Ugly (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a174cece06b3abc0aec3516913cdf9cc", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1980) (Sears) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "a1770ef47146ab7b12e2c4beccd68806", "Digitel", "", "Kaystone Kapers (1983) (Digitel)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a184846d8904396830951217b47d13d9", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a189f280521f4e5224d345efb4e75506", "Atari - Thomas Jentzsch", "", "Obelix (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a1bcbe0bfe6570da2661fc4de2f74e8a", "Imagic - Advanced Program Technology, Rob Fulop", "", "Actionauts (Microbots) (1984-2008) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a1ca372388b6465a693e4626cc98b865", "Quelle", "176.543 7", "Der Vielfrass (1983) (Quelle) (PAL)", "AKA Fast Food", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a1ead9c181d67859aa93c44e40f1709c", "American Videogame - Dunhill Electronics, Darrell Wagner, Todd Clark Holm, John Simonds", "", "Tax Avoiders (1986) (American Videogame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a1f9159121142d42e63e6fb807d337aa", "Quelle - Otto Versand", "700.223 1 - 781627", "Der moderne Ritter (1983) (Quelle) (PAL)", "AKA Fast Eddie", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a204cd4fb1944c86e800120706512a64", "Coleco, Rob Harris", "2511", "Smurfs Save the Day (1983) (Coleco)", "Uses the Kid Vid Controller", "", "", "", "", "", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "" }, - { "a20b7abbcdf90fbc29ac0fafa195bd12", "Quelle - Otto Versand", "719.383 2 - 649635, 781393, 781784, 986404", "Motocross (1983) (Quelle) (PAL)", "AKA Motorcross", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a20d931a8fddcd6f6116ed21ff5c4832", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a2170318a8ef4b50a1b1d38567c220d6", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a1]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2276822c772f72073a8a40a72a1ca52", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2424c1a0c783d7585d701b1c71b5fdc", "", "", "Video Pinball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a25bb76e9e773117e567fd4300b1bb23", "", "", "Interleaved ChronoColour Demo (NTSC) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a28d872fc50fa6b64eb35981d0f4bb8d", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a29df35557f31dfea2e2ae4609c6ebb7", "Atari", "", "Circus Atari (1980) (Atari) (Joystick)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a29fc854838e08c247553a7d883dd65b", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2a384d3a16d5be50afd12906f146827", "Bit Corporation", "R320", "Flash Gordon (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2aae759e4e76f85c8afec3b86529317", "", "", "Boom Bang (Unknown)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2d7cc2e5419a9e4ab91fdb26339b726", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2de0fc85548871279ed2a3c1325c13e", "George Veeder", "", "Cat and Mouse (George Veeder) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2eb84cfeed55acd7fece7fefdc83fbb", "", "", "Kool Aid Man (Fixed) (15-11-2002) (CT)", "HMOVE handling fixed in this version", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2f296ea2d6d4b59979bac5dfbf4edf0", "", "", "Warring Worms (28-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a2f9e3b6aaa23b6dc06099cdd5b51b31", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (PAL60) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a302b922a8dbec47743f28b7f91d4cd8", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a30ece6dc4787e474fbc4090512838dc", "Zellers", "", "Circus (Zellers)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a310494ad5ba2b5b221a30d7180a0336", "", "", "Demo Image Series #6 - Mario (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a336beac1f0a835614200ecd9c41fd70", "Atari, Christopher H. Omarzu, Robert Vieira", "CX26121", "Zoo Keeper Sounds (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a34560841e0878c7b14cc65f79f6967d", "Multivision, Michael Case", "", "Harem (1982) (Multivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a3486c0b8110d9d4b1db5d8a280723c6", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (08-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a35d47898b2b16ec641d1dfa8a45c2b7", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a3873d7c544af459f40d58dfcfb78887", "", "", "Tennis (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a3b9d2be822eab07e7f4b10593fb5eaa", "", "", "GREGXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a3c1c70024d7aabb41381adbfb6d3b25", "Telesys, Alex Leavens", "1005", "Stargunner (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a3d7c299fbcd7b637898ee0fdcfc47fc", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "a3f2a0fcf74bbc5fa763b0ee979b05b1", "Quelle", "873.790 0", "Eishockey-Fieber (1983) (Quelle) (PAL)", "AKA Ice Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a3f8aebb38182749cb8da85cfbc63d7c", "", "", "Tennis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a3fee8ce15525ea00d45a06f04c215d1", "Aaron Curtis", "", "AStar (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a406d2f6d84e61d842f4cb13b2b1cfa7", "Tigervision, John Harris - Teldec", "7-002", "Jawbreaker (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a412c8577b2d57b09185ae51739ac54f", "Arcadia Corporation, Dennis Caswell", "AR-4000", "Phaser Patrol (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a41450333f8dd0e96e5e9f0af3770ae9", "", "", "Basic Math (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a422194290c64ef9d444da9d6a207807", "M Network - APh Technological Consulting, Hal Finney", "MT5667", "Dark Cavern (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a428068d3e51498907d97cec40000515", "Bit Corporation", "R320", "Sky Alien (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a47878a760f5fa3aa99f95c3fdc70a0b", "", "", "Demo Image Series #5 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4790224bd5afabd53cbe93e46a7f241", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a47e26096de6f6487bf5dd2d1cced294", "Atari", "CX2643", "Codebreaker (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a484638990de7b12c62947c79dafa4c6", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL60) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a499d720e7ee35c62424de882a3351b6", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "009-01", "Up 'n Down (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4aa7630e4c0ad7ebb9837d2d81de801", "", "", "Atari 2600 Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4ab331e8768eafdc20ce8b0411ff77a", "", "", "Demo Image Series #1 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4b9423877a0b86ca35b52ca3c994ac5", "CCE", "C-805", "Sea Monster (1983) (CCE)", "O Monstro Marinho", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4b99aa5ed85cfdb7d101923147de035", "Jim Goebel", "", "Pac-Law (Jim Goebel) (Hack)", "Hack of Outlaw", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4c08c4994eb9d24fb78be1793e82e26", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4d026a5c200ef98518ebb77719fe8dc", "Kyle Pittman", "", "SpongeBob SquarePants (2003) (Kyle Pittman) (Hack)", "Hack of Revenge of the Beefsteak Tomatoes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4e885726af9d97b12bb5a36792eab63", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4ecb54f877cd94515527b11e698608c", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (12-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4f1cea2c8479284e2a2292f8d51b5fa", "", "", "Gunfight 2600 - The Final Kernel Part 2 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a4ff39d513b993159911efe01ac12eba", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a511f7ee13e4b35512f9217a677b4028", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a5262fe6d01d6a1253692682a47f79dd", "", "", "JKH Text Scrolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a537879d8e82e1061d3ad800479d3b84", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a539b9fd1ba57e46442b3e9351e6383b", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack) [a]", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a56b642a3d3ab9bbeee63cd44eb73216", "Carrere Video - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV - Teldec - Prism", "USC2001", "Gopher (1983) (Carrere Video) (PAL)", "AKA Vossicht Whlmaus!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a5855d73d304d83ef07dde03e379619f", "Atari, David Crane", "", "Boggle (08-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a58b11148c18d85e4c2aef4ff46ade67", "", "", "Video Chess (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a591b5e8587aae0d984a0f6fe2cc7d1c", "", "", "Globe Trotter Demo (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a5b7f420ca6cc1384da0fed523920d8e", "", "", "Adventure (New Graphics) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a5c96b046d5f8b7c96daaa12f925bef8", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a5e9ed3033fb2836e80aa7a420376788", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a60598ad7ee9c5ccad42d5b0df1570a1", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a6127f470306eed359d85eb4a9cf3c96", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a6239810564638de7e4c54e66b3014e4", "Personal Games Company, Robert Anthony Tokar", "", "Birthday Mania (1984) (Personal Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a62e3e19280ff958407e05ca0a2d5ec7", "", "", "Hangman Ghost Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a6737c81542a99ee71cb5f5ff14703d9", "", "", "Scrolling Playfield 3 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a69f5b1761a8a11c98e706ec7204937f", "", "", "Pharaoh's Curse (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a6ed8d72ed691fd3aad5b6974fa17978", "Bit Corporation", "R320", "Bank Heist (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a74689a08746a667a299b0507e1e6dd9", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a7523db9a33e9417637be0e71fa4377c", "Videospielkassette - Ariola", "PGP238", "Gangster (Ariola) (PAL)", "AKA Outlaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a7673809068062106db8e9d10b56a5b3", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118, CX26118P", "Millipede (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a779b9fa02c62d00d7c31ed51268f18a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a7a58e9291aefa1064e933071f60d4ef", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a7b584937911d60c120677fe0d47f36f", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5661", "Armor Ambush (1982) (M Network)", "AKA Tank Battle", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a7b96a8150600b3e800a4689c3ec60a2", "Atari, Mike Lorenzen - Sears", "CX2630 - 49-75122", "Circus Atari (1980) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, - { "a7bf8353f77caca407ef85c2698fdff2", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a7cf2b9afdbb3a161bf418dbcf0321dc", "Barry Laws Jr.", "", "Attack Of The Mutant Space Urchins (2002) (Barry Laws Jr.) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a7d2e9408bb7cd70139ecced407ff238", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a7ed7dc5cbc901388afa59030fb11d26", "Atari, Warren Robinett", "CX2606, CX2606P", "Slot Racers (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a7ef44ccb5b9000caf02df3e6da71a92", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8101cb667e50a46165c6fb48c608b6b", "", "", "Kung Fu Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a81697b0c8bbc338ae4d0046ede0646b", "CCE", "", "Gravitar (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a81b29177f258494b499fbac69789cef", "Greg Thompson", "", "Console Wars (Greg Thompson) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a83b070b485cf1fb4d5a48da153fdf1a", "Apollo", "AP-2011", "Pompeii (1983) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8435ec570141de5d833c4abec499e55", "", "", "Happy Birthday Demo (2001) (Dennis Debro) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8633050a686270fcf6c0cc4dcbad630", "Zirok", "", "Phoenix (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a867b76098786c4091dba2fcee5084c3", "", "", "Dragrace (Hack)", "Hack of Dragster", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a875f0a919129b4f1b5103ddd200d2fe", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (PAL)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8916734ff8c64ec3342f4c73fd5b57d", "Atari", "", "Stand Alone Test Cart (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a89a3e0547d6887279c34aba4b17a560", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype)", "", "Prototype", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8a703e073183a89c94d4d99b9661b7f", "Franklin Cruz", "", "Spice Invaders (Franklin Cruz) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8b3ea6836b99bea77c8f603cf1ea187", "CCE", "C-861", "Boxing (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8c447efbec3a2b5d08b05a09999bd92", "", "", "MegaCart Menu", "", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "a8c48b4e0bf35fe97cc84fdd2c507f78", "Puzzy - Bit Corporation", "PG201", "Seamonster (1982) (Puzzy)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8d0a4a77cd71ac601bd71df5a060e4c", "", "", "Space Shuttle (1983) (Activision) [t2] (Fuel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8d4a9500b18b0a067a1f272f869e094", "", "", "Red And White Checkerboard Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a8e49d7e24ce293629ca29614862821b", "", "", "Enduro (Genesis)", "Genesis controller (B is acceleration, C is brakes)", "Hack of Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a91d0858a52de3a2e6468437212d93e8", "", "", "Q-bert (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a936d80083e99d48752ad15c2b5f7c96", "", "", "Room of Doom (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a93e8ea1f565c3c1e86b708cf0dc2fa9", "Jess Ragan", "", "Kabul! (Jess Ragan) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "a94528ae05dd051894e945d4d2349b3b", "Genus", "", "River Raid (Genus)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a94b8ca630f467b574b614808d813919", "HES", "773-883", "2 Pak Special - Space Voyage, Fire Alert (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a9531c763077464307086ec9a1fd057d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a957dbe7d85ea89133346ad56fbda03f", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "a97733b0852ee3096300102cb0689175", "CCE", "C-834", "Fast Eddie (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a9784c24cddb33bd0d14442b97784f3d", "Thomas Jentzsch", "", "Omega Race DC (2003) (TJ) (Omega Race Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a98b649912b6ca19eaf5c2d2faf38562", "", "", "This Planet Sucks (Greg Troutman) (PAL) [!]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a995b6cbdb1f0433abc74050808590e6", "Imagic, Rob Fulop, Bob Smith", "720106-1A, IA3600", "Riddle of the Sphinx (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a9cb638cd2cb2e8e0643d7a67db4281c", "M Network - INTV - APh Technological Consulting, Larry Zwick", "MT5861", "Air Raiders (1983) (M Network)", "AKA Air Battle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a9d9e19d0c89fb31780b5d63e1f8c6a4", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "a9e3c23599c0d77151602f8e31daf879", "", "", "Kung Fu Master (Genesis)", "Genesis controller (C is extra kick modes)", "Hack of Kung Fu Master", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" }, - { "aa1c41f86ec44c0a44eb64c332ce08af", "Spectravideo, David Lubar", "SA-218", "Bumper Bash (1983) (Spectravideo)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "" }, - { "aa2c4b32656bde9a75042a4d158583e1", "", "", "Oystron X (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aa5cfe3b20395aba1d479135943ad85c", "", "", "Defender (Hack) (Unknown)", "", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aa7bb54d2c189a31bb1fa20099e42859", "CBS Electronics, Ed English", "4L4478", "Mr. Do! (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "aa8c75d6f99548309949916ad6cf33bc", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aa8e4b2cb8a78ffe6b20580033f4dec9", "", "", "Bitmap Demo (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aaac0d277eda054861e613c59c2e4ff2", "JWDA, Todd Marshall", "", "Music Demo (JWDA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aab840db22075aa0f6a6b83a597f8890", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83124", "Racing Car (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "aad61898633f470ce528e3d7ef3d0adb", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aad91be0bf78d33d29758876d999848a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1981) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aaea37b65db9e492798f0105a6915e96", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" }, - { "aafc79ffc32c4c9b2d73c8ada7602cfe", "", "", "Planet Patrol (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab10f2974dee73dab4579f0cab35fca6", "ITT Family Games", "", "Wilma Wanderer (1983) (ITT Family Games) (PAL)", "AKA Lilly Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab2cfcaad3daaf673b2b14fdbb8dac33", "M Network - INTV, David Akers, Joe King, Patricia Lewis Du Long, Jeff Ratcliff", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab2ea35dcc1098c87455bb8210b018cf", "", "", "Fu Kung! (V0.04 Single Line Resolution) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab301d3d7f2f4fe3fdd8a3540b7a74f5", "Jone Yuan Telephonic Enterprise Co", "", "IQ 180 (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab434f4c942d6472e75d5490cc4dd128", "HES", "773-875", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab48c4af46c8b34c3613d210e1206132", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo V2 (2014)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab4ac994865fb16ebb85738316309457", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari)", "Console ports are swapped", "Common", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "ab56f1b2542a05bebc4fbccfc4803a38", "Activision - Imagineering, Dan Kitchen, David Lubar", "AK-048-04", "River Raid II (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab5bf1ef5e463ad1cbb11b6a33797228", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab60ea7b707c58d356cad858eb18db43", "", "", "Tazer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ab8d318da4addd39c65b7f9c408df2a6", "", "", "Star Trek (Genesis)", "Genesis controller (B is phaser, C is warp)", "Hack of Star Trek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "abb740bea0a6842831b4f53112fb8145", "", "", "Qb (V1.01) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "abb741c83f665d73c86d90a7d9292a9b", "Telegames", "", "Space Attack (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "abc64037ca5d5b04ae8a7eedbca3ed74", "", "", "Green and Yellow Number 1 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "abe40542e4ff2d1c51aa2bb033f09984", "Absolute Entertainment, David Crane", "EAZ-042-04B, EAZ-042-04I", "Skate Boardin' (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ac05c0e53a5e7009ddd75ed4b99949fc", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ac0ddbcff34d064009591607746e33b8", "Thomas Jentzsch", "", "Atlantis FH (2003) (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ac26d7d37248d1d8eac5eccacdbef8db", "", "", "Snail Against Squirrel (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ac3dd22dd945724be705ddd2785487c2", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ac53b83e1b57a601eeae9d3ce1b4a458", "Retroactive", "", "Qb (2.15) (Retroactive) (NTSC)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ac5f78bae0638cf3f2a0c8d07eb4df69", "", "", "Minesweeper (V.99) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ac7c2260378975614192ca2bc3d20e0b", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ac9adbd6de786a242e19d4bec527982b", "Activision, Alan Miller - Ariola", "EAG-012-04I, EAX-012, EAX-012-04B - 711 012-720", "Ice Hockey (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aca09ffea77174b148b96b205109db4d", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "acaa27d214039d89d7031609aafa55c3", "", "", "Sprite Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "acb6787b938079f4e74313a905ec3ceb", "", "", "Chronocolor Donkey Kong (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "acb7750b4d0c4bd34969802a7deb2990", "Parker Brothers, Ed Temple", "PB5310", "Amidar (1982) (Parker Bros)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "acb962473185d7a652f90ed6591ae13b", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (16K)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ace319dc4f76548659876741a6690d57", "Atari, Steve Wright", "CX2616", "Pele's Soccer (1981) (Atari)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ad2e6bfb3b9b9b36ba8bf493ce764c49", "", "", "2600 Collison Demo 1 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ad42e3ca3144e2159e26be123471bffc", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ad72d616030a17634ff29ce8680d3c4c", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ad7e97c19bd25d5aa3999430845c755b", "", "", "Sprite Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ad8072675109d13fdd31a2e0403d5cff", "Funvision - Fund. International Co.", "", "Tank City (Funvision)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "adb770ff70e9adf08bbb907a7eccd240", "", "", "Inv Demo 3 (2001) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "adb79f9ac1a633cdd44954e2eac14774", "Digivision", "", "Frostbite (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "adf1afac3bdd7b36d2eda5949f1a0fa3", "Quelle - Otto Versand", "495.463 2 - 746381", "Angriff der Luftflotten (1983) (Quelle) (PAL)", "AKA Paris Attack, M.A.D.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "adfbd2e8a38f96e03751717f7422851d", "Champ Games", "CG-01-N", "Lady Bug (NTSC)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ae047e9468bda961d8e9e9d8ff52980f", "", "", "Tunnel Demo (Red Spiral) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ae0d4f3396cb49de0fabdff03cb2756f", "Retroactive", "", "Qb (V2.02) (PAL) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ae10527840a1ac24de43730645ed508d", "Charles Morgan", "", "Planet Invaders (Charles Morgan) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ae18c11e4d7ed2437f0bf5d167c0e96c", "", "", "Multi-Color Demo 3 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ae2f1f69bb38355395c1c75c81acc644", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-23-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ae465044dfba287d344ba468820995d7", "", "", "Inca Gold (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ae4be3a36b285c1a1dff202157e2155d", "Spectravideo", "SA-210", "Master Builder (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ae682886058cd6981c4b8e93e7b019cf", "Retroactive", "", "Qb (V0.12) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ae6cb335470788b94beb5787976e8818", "", "", "Mortal Kurling (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ae83541cf4a4c0bce0adccd2c1bf6288", "", "", "Maze 003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ae97cf8ed21f4154b4360a3cf6c95c5e", "", "", "Teleterm 2600 (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aeb104f1e7b166bc0cbaca0a968fde51", "", "", "Ms. Pac-Man (1999) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aec9b885d0e8b24e871925630884095c", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aed0b7bd64cc384f85fdea33e28daf3b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "aed82052f7589df05a3f417bb4e45f0c", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "af6ab88d3d7c7417db2b3b3c70b0da0a", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "af6f3e9718bccfcd8afb421f96561a34", "Atari, Tod Frye", "CX2695", "Xevious (01-18-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "afb3bc45c6a82739cc82582127cd96e6", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dungeon (11-22-1985) (Atari) (Prototype)", "Dark Chambers Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "afc194534c1b346609ef05eff6d3cef6", "Jone Yuan Telephonic Enterprise Co", "", "Boxing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "afd2cf258d51ae4965ee21abba3627ab", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (12-08-1982) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "" }, - { "afe4eefc7d885c277fc0649507fbcd84", "Atari", "CX26163P", "Ant Party (32 in 1) (1988) (Atari) (PAL)", "AKA Cosmic Swarm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "afe776db50e3378cd6f29c7cdd79104a", "Thomas Jentzsch", "", "Bobby is Going Home (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "afe88aae81d99e0947c0cfb687b16251", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "aff8cba0f2d2eb239953dd7116894a08", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b00088418fc891f3faa3d4ddde6ace94", "", "", "Unknown Title (bin00007 (200102)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b00a8bc9d7fe7080980a514005cbad13", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b00e8217633e870bf39d948662a52aac", "Konami", "RC 102-X 02", "Marine Wars (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b011d8fdc450597c0762c2c0010a9b17", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b049fc8ac50be7c2f28418817979c637", "Activision - Imagineering, Dan Kitchen, David Lubar", "EAK-048-04, EAK-048-04B", "River Raid II (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b06050f686c6b857d0df1b79fea47bb4", "Activision", "AIZ-001", "Moonsweeper (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b061e98a4c854a672aadefa233236e51", "Atari, Warren Robinett", "CX2620, CX2620P", "Basic Programming (1979) (Atari) (PAL)", "Uses Keypad Controllers", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b095009004df341386d22b2a3fae3c81", "", "", "Sub-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b09b79c9628878be051e89f7f1e77378", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "b0a9c6f6c8014c4023e0341ba11ca35e", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009) (PAL)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b0ba51723b9330797985808db598fc31", "Atari, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b0c47e426c7f799aee2c40422df8f56a", "", "", "Space Treat (PAL) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b0c9cf89a6d4e612524f4fd48b5bb562", "Atari - GCC", "CX2663", "Combat Two (1982) (Atari) (Prototype)", "AKA Super Combat", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b0e1ee07fbc73493eac5651a52f90f00", "Colin Hughes", "", "Tetris 2600 (Colin Hughes)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b1276417fb0f79bc52e741bb8f4d8360", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (NTSC) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b129d7541cff79ebe33852a83057c524", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (NTSC) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b12a7f63787a6bb08e683837a8ed3f18", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic) [fixed]", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b1339c56a9ea63122232fe4328373ac5", "Goliath - Hot Shot", "83-215", "Dream Flight (1983) (Goliath) (PAL)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b1486e12de717013376447ac6f7f3a80", "Spectravideo, Mark Turmell, Quelle", "SA-217, SA-217C - 413.723 8", "Gas Hog - Piraten Schiff (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b15026b43c6758609667468434766dd8", "Retroactive", "", "Qb (0.06) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b16cd9784589219391c839cb68c47b9c", "Video Soft, Jerry Lawson, Dan McElroy", "", "Golf Diagnostic (1983) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b17b9cc4103844dcda54f77f44acc93a", "Quelle", "377.943 6", "Stopp die Gangster (1983) (Quelle) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b182d9708e00709830caab9cf8205ca0", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b1a6c96e9093352106bc335e96caa154", "Joe Grand", "", "SCSIcide Pre-release 1 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b1b20536aef4eed9c79dc5804f077862", "", "", "Euchre (NTSC) (09-11-2001) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b1c14b5ac896400cc91c8e5dd67acb59", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b1d1e083dc9e7d9a5dc1627869d2ade7", "CCE", "C-1004", "Mario's Bros. (1983) (CCE)", "AKA Mario Bros.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b1e2d5dc1353af6d56cd2fe7cfe75254", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b1fd0b71de9f6eeb5143a97963674cb6", "", "", "Multi-Color Demo 7 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b227175699e372b8fe10ce243ad6dda5", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b23ebf427713dd0198b7ef47dbd07ef4", "Jone Yuan Telephonic Enterprise Co", "", "Sky Diver (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b24f6a5820a4b7763a3d547e3e07441d", "CCE", "C-823", "Demon Attack (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b25841173f058380b1771aacd5e7cdf3", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b26506fbf411009e5e3f7365f442960e", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b2737034f974535f5c0c6431ab8caf73", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b2761efb8a11fc59b00a3b9d78022ad6", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "b290c2b139344fcff5b312c71b9ac3b2", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b29359f7de62fed6e6ad4c948f699df8", "Goliath", "3", "Phantom Tank (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b2a6f31636b699aeda900f07152bab6e", "", "", "Space Instigators (Public Release 2) (06-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b2ab209976354ad4a0e1676fc1fe5a82", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a3]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b2d1e63f7f22864096b7b6c154151d55", "Fabrizio Zavagli", "", "Bounce! (17-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b2d3bcee001cff2bd2d8a21b2cb55109", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (08-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b2d5d200f0af8485413fad957828582a", "Atari - Bobco, Robert C. Polaro", "CX26155P", "Sprint Master (1988) (Atari) (PAL)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b2f0d7217147160b2f481954cedf814b", "", "", "Marquee Drawer (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b3017e397f74efd53caf8fae0a38e3fe", "Retroactive", "", "Qb (2.12) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b311ab95e85bc0162308390728a7361d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b31dc989f594764eacfa7931cead0050", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b31e9487efc06f18dfc3d7ebadf54416", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b31f178aa0d569cccac7959f84e0a724", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-13-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b3203e383b435f7e43f9492893c7469f", "Gameworld", "133-003", "Sssnake (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b36040a2f9ecafa73d835d804a572dbf", "Digitel", "", "Pac Man (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b37f0fe822b92ca8f5e330bf62d56ea9", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b392964e8b1c9c2bed12246f228011b2", "", "", "Name This Game (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b4030c38a720dd84b84178b6ce1fc749", "M Network - APh Technological Consulting, Kevin Miller", "MT5687", "International Soccer (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b40dea357d41c5408546e4e4d5f27779", "Digivision", "", "Spider Fighter (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b41fdd4a522e1d5a2721840028684ac2", "", "", "Green and Yellow Number 1 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b42df8d92e3118dc594cecd575f515d7", "Mystique - American Multiple Industries", "1003", "Burning Desire (1982) (Mystique) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b438a6aa9d4b9b8f0b2ddb51323b21e4", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames) (PAL)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b451307b8b5e29f1c5f2cf064f6c7227", "", "", "Demo Image Series #6 - Mario (Fixed) (26-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b49331b237c8f11d5f36fe2054a7b92b", "", "", "Condor Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b4a4c87840613f102acb5b3a647d0a67", "", "", "Mobile 48 Sprite Kernel (04-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b4daedb43511521db9036d503b3c1b69", "", "", "Sokoban (01-01-2003) (Adam Wozniak) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b4e2fd27d3180f0f4eb1065afc0d7fc9", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, William O. Sheppard", "5002002", "London Blitz (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b4f05e544834d0238a0c263491775edf", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b4f31ea8a6cc9f1fd4d5585a87c3b487", "Mystique - American Multiple Industries, Joel H. Martin", "", "Beat 'Em & Eat 'Em (1982) (Mystique) (PAL)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "b4f87ce75f7329c18301a2505fe59cd3", "Videospielkassett - Ariola", "PGP232", "Autorennen (Ariola) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b50ae55aac93fbed258bc5a873edd2cb", "Recompile", "", "E.T. The Extra-Terrestrial (Recompile) (Hack)", "www.neocomputer.org/projects/et", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b5110f55ed99d5279f18266d001a8cd5", "Eckhard Stolberg", "", "Auto-mobile Demo (2001) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b56264f738b2eb2c8f7cf5a2a75e5fdc", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b5657d4c1c732fbb6af150668464247f", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b59417d083b0be2d49a7d93769880a4b", "Pet Boat", "", "Donkey Kong (1983) (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b59fd465abf76f64c85652ff29d5952d", "VentureVision, Dan Oliver", "", "Innerspace (1983) (VentureVision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b5a1a189601a785bdb2f02a424080412", "Imagic, Dennis Koble", "720021-1A, IA3410", "Shootin' Gallery (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b5cb9cf6e668ea3f4cc2be00ea70ec3c", "CommaVid, Irwin Gaines - Ariola", "CM-005 - 712 005-720", "Mines of Minos (1982) (CommaVid) (PAL)", "AKA Im Labyrinth des Roboters", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b5cdbab514ea726a14383cff6db40e26", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL) [a]", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b5efe0271d2214e4d5dc798881486884", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (06-14-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b6166f15720fdf192932f1f76df5b65d", "Amiga - Video Soft", "3130", "Off Your Rocker (1983) (Amiga) (Prototype)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b64426e787f04ff23ee629182c168603", "Dynacom", "", "Plaque Attack (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b65d4a38d6047735824ee99684f3515e", "Dynacom", "", "MegaBoy (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b676a9b7094e0345a76ef027091d916b", "Thomas Jentzsch", "", "Mission Survive (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b6812eaf87127f043e78f91f2028f9f4", "Simage", "", "Eli's Ladder (1984) (Simage)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b6821ac51c4c1dcb283f01be2f047dc1", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (25-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b6960be26bee87d53ba4e2e71cfe772f", "", "", "3-D Corridor (Spiral Words) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b6d52a0cf53ad4216feb04147301f87d", "Imagic, Michael Greene", "720055-1A, IA3312", "No Escape! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b6e40bce550672e5495a8cdde7075b8b", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b702641d698c60bcdc922dbd8c9dd49c", "Atari, Ian Shepard", "CX26163P", "Space War (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b719ada17771a8d206c7976553825139", "Ron Corcoran", "", "DUP Space Invaders (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b731d35e4ac6b3b47eba5dd0991f452f", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (Final) (08-01-2003) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b7345220a0c587f3b0c47af33ebe533c", "Quelle", "176.433 1", "Landungskommando (1983) (Quelle) (PAL)", "AKA Strategy X", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b76fbadc8ffb1f83e2ca08b6fb4d6c9f", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b77468d586957d1b7fb4cccda2684f47", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b7903268e235310dc346a164af4c7022", "Thomas Jentzsch", "", "Cat Trax (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b79fe32320388a197ac3a0b932cc2189", "Imagic, Bob Smith", "13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b7a7e34e304e4b7bc565ec01ba33ea27", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b7b1d3ce07e75976c43a2dca3866237e", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b7d0aae399781b3c18679debda6d32b1", "Thomas Jentzsch", "", "Three.s (v1.02)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b7d7c76e37f372f4e4979b380ed95a58", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b7e459d5416eeb196aaa8e092db14463", "", "", "Push (V0.02) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b7f184013991823fc02a6557341d2a7a", "", "", "Blue Rod Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b80d50ecee73919a507498d0a4d922ae", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b816296311019ab69a21cb9e9e235d12", "Atari, Bob Whitehead - Sears", "CX2652 - 6-99816, 49-75151", "Casino (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "b822fba8b7c8a97ea4e92aeb2c455ef9", "Dactari", "", "Freeway (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b83579c4450fcbdf2b108903731fa734", "", "", "Mission 3,000 A.D. (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b83df1f32b4539c324bdf94851b4db55", "Angelino", "", "One On One by Angelino (Basketball Hack)", "Hack of Basketball (1978) (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b86552198f52cfce721bafb496363099", "Apollo, Tim Martin", "AP-2007", "Kyphus (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b86a12e53ab107b6caedd4e0272aa034", "Funvision - Fund. International Co.", "", "Treasure Hunting (Funvision)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b879e13fd99382e09bcaf1d87ad84add", "Zellers", "", "Time Warp (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b8865f05676e64f3bec72b9defdacfa7", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b897f9e3f939b9f21566d56db812a84e", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b8e715223ba65cf716b3620a90ca3ec1", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b8ed78afdb1e6cfe44ef6e3428789d5f", "Data Age, J. Ray Dettling", "112-007", "Bermuda Triangle (1983) (Data Age)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b9232c1de494875efe1858fc8390616d", "Panda", "110", "Harbor Escape (1983) (Panda)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b9336ed6d94a5cc81a16483b0a946a73", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "b955eb0e2baf7a437c186bddd4c49958", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL60) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b958d5fd9574c5cf9ece4b9421c28ecd", "Piero Cavina", "", "Multi-Sprite Game V1.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b95a6274ca0e0c773bfdc06b4c3daa42", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b98cc2c6f7a0f05176f74f0f62c45488", "Spectravideo", "SV-010", "CompuMate (1983) (Spectravideo)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "COMPUMATE", "", "", "", "", "", "", "YES", "" }, - { "b9b4612358a0b2c1b4d66bb146767306", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b9d1e3be30b131324482345959aed5e5", "Activision - Boston Design Center, Rex Bradford", "", "Kabobber (07-25-1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "b9f6fa399b8cd386c235983ec45e4355", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL)", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, - { "b9f9c0fed0db08c34346317f3957a945", "SuperVision", "405, 427, 806, 808, 813, 816", "Chopper Command (SuperVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ba257438f8a78862a9e014d831143690", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2002", "Squeeze Box (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ba317f83cdfcd58cbc65aac1ccb87bc5", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ba3a17efd26db8b4f09c0cf7afdf84d1", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ba3b0eebccc7b791107de5b4abb671b4", "Thomas Jentzsch", "", "Thrust (V0.9) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ba657d940a11e807ff314bba2c8b389b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bac28d06dfc03d3d2f4a7c13383e84ee", "Supergame", "", "Demon Attack (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bae1a23f9b6acdadf465cfb330ba0acb", "Atari - GCC, Doug Macrae", "CX2677", "Dig Dug (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bae66907c3200bc63592efe5a9a69dbb", "Spectravision - Spectravideo - Quelle", "SA-201 - 412.783 3", "Gangster Alley (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "baf4ce885aa281fd31711da9b9795485", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bb18189021d58362d9e4d317cd2e28b7", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL) (4K)", "AKA Dragster Rennen", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bb2b83fff97604f74ada565e0b5bae94", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bb5049e4558daade0f87fed69a244c59", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [no copyright]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "bb579404924c40ca378b4aff6ccf302d", "", "", "Lightbulb Lightens, The (PD) (Non Functional)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bb6a5a2f7b67bee5d1f237f62f1e643f", "", "", "Demo Image Series #5 - Animegirl (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bb745c893999b0efc96ea9029e3c62ca", "Play Video", "", "Planet Patrol (1982) (Play Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bb756aa98b847dddc8fc170bc79f92b2", "", "", "Golf (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bb9112d478a1a922d2c289a752bba695", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bbf8c7c9ed280151934aabe138e41ba7", "Amiga", "1130", "Power Play Arcade Video Game Album V (1984) (Amiga) (Prototype)", "Mogul Maniac, Surf's Up, Off Your Rocker, S.A.C. Alert", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc24440b59092559a1ec26055fd1270e", "", "", "Private Eye (1984) (Activision) [a]", "", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc3057a35319aae3a5cd87a203736abe", "CCE", "C-845", "Time Warp (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc33c685e6ffced83abe7a43f30df7f9", "Dynacom", "", "Seaquest (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc4cf38a4bee45752dc466c98ed7ad09", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari) (PAL)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc526185ad324241782dc68ba5d0540b", "", "", "Dodge Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc5389839857612cfabeb810ba7effdc", "Atari, Tod Frye", "CX2671", "SwordQuest - WaterWorld (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc703ea6afb20bc089f04d8c9d79a2bd", "", "", "Gunfight 2600 - Not mergeable with Colbert wizardry... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bc97d544f1d4834cc72bcc92a37b8c1b", "", "", "Sky Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bcb31f22856b0028c00d12f0e4c0a952", "Canal 3 - Intellivision", "", "Thunderground (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bcb73b534ed7c613ac379ecd726effb5", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bccb4e2cfad5efc93f6d55dc992118ce", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bce4c291d0007f16997faa5c4db0a6b8", "Quelle", "292.651 7", "Weltraumtunnel (1983) (Quelle) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bce93984b920e9b56cf24064f740fe78", "Atari", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bcef7880828a391cf6b50d5a6dcef719", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bd1bd6f6b928df17a702def0302f46f4", "", "", "Binary To Decimal Routine (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bd39598f067a1193ae81bd6182e756d1", "Telegames", "", "Night Stalker (1988) (Telegames) (PAL)", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bd430c2193045c68d1a20a018a976248", "", "", "Pac Ghost Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bd551ff1264f5c367a3ad7cf0d2f266c", "Bit Corporation", "R320", "SpaceMaster X-7 (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bda1463e02ae3a6e1107ffe1b572efd2", "Atari, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bdb4b584ddc90c9d2ec7e21632a236b6", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack)", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bdbaeff1f7132358ea64c7be9e46c1ac", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bdc381baf7c252c63739c5e9ed087a5c", "", "", "Vertical Ship Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bdecc81f740200780db04a107c3a1eba", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bdf1996e2dd64baf8eff5511811ca6ca", "Tron", "", "H.E.R.O. (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be060a704803446c02e6f039ab12eb91", "Parker Brothers, Rex Bradford, Sam Kjellman", "931501", "Star Wars - The Empire Strikes Back (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be1922bd8e09d74da471287e1e968653", "Cropsy", "", "Hangman Pacman Demo (Cropsy) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be2870a0120fd28d25284e9ccdcbdc99", "", "", "Tomb Raider 2600 [REV 01] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be35d8b37bbc03848a5f020662a99909", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be3f0e827e2f748819dac2a22d6ac823", "Puzzy - Bit Corporation", "PG202", "Space Tunnel (1982) (Puzzy)", "AKA Le Tunnel de L'Estace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be41463cd918daef107d249f8cde3409", "", "", "Berzerk (Voice Enhanced) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be561b286b6432cac71bccbae68002f7", "", "", "Counter Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "be929419902e21bd7830a7a7d746195d", "Activision, Garry Kitchen", "AX-025, AX-025-04", "Keystone Kapers (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "becd908f9d7bb361982c3dc02d6475c6", "Kyle Pittman", "", "THX-1138 (Kyle Pittman) (Hack)", "Hack of Berserk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bedfbde71fb606601f936b5b057f26f7", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "befce0de2012b24fd6cb8b53c17c8271", "", "", "Push (V0.03) (No Illegal Opcodes) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bf1970b692275b42c4ec0683588eb062", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bf52327c2197d9d2c4544be053caded1", "HES - Activision", "AG-930-04, AZ-030", "Decathlon (HES) (PAL) (16K)", "AKA Activision Decathlon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bf84f528de44225dd733c0e6a8e400a0", "CCE", "", "Demons to Diamonds (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" }, - { "bf976cf80bcf52c5f164c1d45f2b316b", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bfa58198c6b9cd8062ee76a2b38e9b33", "", "", "20 Sprites at Once Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bfb73aabb2489316cd5882c3cd11d9f9", "AtariAge, Chris Walton & Thomas Jentzsch", "165", "Star Castle Arcade (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "bff8f8f53a8aeb1ee804004ccbb08313", "", "", "Droid Demo 22 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "bffe34516aaa3cbf5d307eab382a7e95", "", "", "Euchre (Release Candidate) (PAL) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c00734a2233ef683d9b6e622ac97a5c8", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (03-30-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c00b65d1bae0aef6a1b5652c9c2156a1", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "c02e1afa0671e438fd526055c556d231", "Atari", "", "A-Team (Atari) (Prototype) (PAL60)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c032c2bd7017fdfbba9a105ec50f800e", "Activision, Charlie Heath", "", "Thwocker (04-09-1984) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c033dc1d7b6fde41b9cadce9638909bb", "", "", "Skeleton (V1.1) (06-09-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c0589bb73858924389077fa3c2e9441a", "SOLID Corp. (D. Scott Williamson)", "CX2655-014", "Star Castle 2600 (SolidCorp) [014]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c05f367fa4767ceb27abadf0066df7f4", "Thomas Jentzsch", "", "TomInv (31-07-2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c08d0cee43077d3055febb00e5745c1d", "HES - Activision", "", "Super Hit Pak - River Raid, Sky Jinks, Grand Prix, Fishing Derby, Checkers (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c0a68837c60e15d1fc5a40c9a62894bc", "Arcadia Corporation, Kevin Norman", "7 AR-4103", "Killer Satellites (1983) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c0c7eddefce9015346db88ade3e1e096", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics) (Prototype) (4K)", "RAM must be zero'ed to start correctly", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c0d2434348de72fa6edcc6d8e40f28d7", "SEGA - Beck-Tech, Steve Beck", "010-01", "Tapper (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1034a5bfb0bb13cc5bdf86cc58989a7", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c118854d670289a8b5d5156aa74b0c49", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c11e8473c652619ac6166900150ce215", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" }, - { "c126656df6badfa519cc63e681fb3596", "Ron Corcoran", "", "Space Invaders (2002) (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c15042e54c7408498f051d782aaa8945", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c150c76cbde2c9b5a97eb5399d46c64f", "", "", "Unknown Title (xxx00000 (200203)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c16c79aad6272baffb8aae9a7fff0864", "U.S. Games Corporation - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2001", "Gopher (1982) (U.S. Games)", "AKA Gopher Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c16fbfdbfdf5590cc8179e4b0f5f5aeb", "", "", "Wall Break (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c17bdc7d14a36e10837d039f43ee5fa3", "Spectravision - Spectravideo", "SA-203", "Cross Force (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1a83f44137ea914b495fc6ac036c493", "Atari, Carla Meninsky", "CX2660", "Star Raiders (1982) (Atari) (PAL)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1b038ce5cb6d85e956c5509b0e0d0d8", "", "", "Rotating Colors Demo 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1b1049b88bcd98437d8872d1d62ba31", "", "", "Demo Image Series #4 - Donald (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1b7aeabc3ec41556d924c8372a9ba5b", "Atari, Robert C. Polaro", "", "Dukes of Hazard (1980) (Atari) (Prototype)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1cb228470a87beb5f36e90ac745da26", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1e6e4e7ef5f146388a090f1c469a2fa", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1f209d80f0624dada5866ce05dd3399", "Telegames", "", "Deadly Discs (1988) (Telegames) (PAL)", "AKA TRON - Deadly Discs", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c1fdd44efda916414be3527a47752c75", "Parker Brothers, John Emerson", "PB5920", "G.I. Joe - Cobra Strike (1983) (Parker Bros)", "Uses the Paddle (left) and Joystick (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c20f15282a1aa8724d70c117e5c9709e", "Video Gems", "VG-02", "Surfer's Paradise (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c21450c21efb7715746e9fa87ad6f145", "Hozer Video Games", "", "Gunfight 2600 - It could've been soooo cool, but... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c216b91f5db21a093ded6a5aaec85709", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c221607529cabc93450ef25dbac6e8d2", "Eckhard Stolberg", "", "Color Test (26-09-2002) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c225379e7c4fb6f886ef9c8c522275b4", "Video Mania", "", "Frostbite (1983) (Video Mania)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c225abfb584960efe1f359fc94b73379", "", "", "Joustpong (21-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2410d03820e0ff0a449fa6170f51211", "", "", "Pac-Man (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c246e05b52f68ab2e9aee40f278cd158", "Thomas Jentzsch", "", "Star Wars - Ewok Adventure (Thomas Jentzsch) (Prototype)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2778507b83d9540e9be5713758ff945", "", "", "Island Flyer Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c28b29764c2338b0cf95537cc9aad8c9", "", "", "Multi-Color Demo 4 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c29d17eef6b0784db4586c12cb5fd454", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c29f8db680990cb45ef7fef6ab57a2c2", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2a37f1c7603c5fd97df47d6c562abfa", "Roger Williams", "", "Bar-Score Demo (2001) (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2b5c50ccb59816867036d7cf730bf75", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c2bcd8f2378c3779067f3a551f662bb7", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2c7a11717e255593e54d0acaf653ee5", "", "", "Chopper Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2c8eb642765137bb82b83a65232961f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2dea467f4a02fa1f06d66f52bc12e6e", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c2fbef02b6eea37d8df3e91107f89950", "Champ Games", "CG-02-N", "Conquest Of Mars (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c31a17942d162b80962cb1f7571cd1d5", "Home Vision - Gem International Corp. - VDI", "VCS83112", "Sky Alien (1983) (Home Vision) (PAL)", "AKA Sky Aliem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3205e3707f646e1a106e09c5c49c1bf", "", "", "Unknown Title (bin00003 (200206)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3472fa98c3b452fa2fd37d1c219fb6f", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c370c3268ad95b3266d6e36ff23d1f0c", "Atari, Alan Miller", "CX2641, CX2641P", "Surround (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3a9550f6345f4c25b372c42dc865703", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3aeb796fdaf9429e8cd6af6346f337e", "", "", "If It's Not One Thing It's Another (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3bbc673acf2701b5275e85d9372facf", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (07-21-1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3e4aa718f46291311f1cce53e6ccd79", "", "", "Hangman Ghost 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3ef5c4653212088eda54dc91d787870", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c3f53993ade534b0982ca3a286c85bb5", "", "", "Full Screen Bitmap Drawing System (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c4060a31d61ba857e756430a0a15ed2e", "Thomas Jentzsch", "", "Pick 'n Pile (2003) (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c41e7735f6701dd50e84ee71d3ed1d8f", "Dynacom", "", "Spider Fighter (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c43bd363e1f128e73ba5f0380b6fd7e3", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c446288fe62c0c2737639fd788ae4a21", "", "", "Mark's Sound Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c450a285daa7a3b65188c2c3cf04fb3e", "Wizard Video Games", "007", "Halloween (1983) (Wizard Video Games) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c469151655e333793472777052013f4f", "", "", "Base Attack (Unknown) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c471b97446a85304bbac021c57c2cb49", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software) (PAL)", "AKA Bubbles, Soap Suds, The Emphysema Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c47244f5557ae12c61e8e01c140e2173", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c47b7389e76974fd0de3f088fea35576", "Funvision - Fund. International Co.", "", "Mighty Mouse (Funvision)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c482f8eebd45e0b8d479d9b71dd72bb8", "Retroactive", "", "Push (V0.03) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c49fe437800ad7fd9302f3a90a38fb7d", "Atari, Dan Hitchens, Mimi Nyden", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c4b73c35bc2f54b66cd786f55b668a82", "Arcadia Corporation, Stephen Harland Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c4bbbb0c8fe203cbd3be2e318e55bcc0", "", "", "Atlantis (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c4bc8c2e130d76346ebf8eb544991b46", "Imagic", "", "Imagic Selector ROM (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c4d888bcf532e7c9c5fdeafbb145266a", "", "", "Space Robot (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c504a71c411a601d1fc3173369cfdca4", "Retroactive", "", "Qb (V2.02) (Stella) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c5124e7d7a8c768e5a18bde8b54aeb1d", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c517144e3d3ac5c06f2f682ebf212dd7", "Tigervision - Teldec", "7-008 - 3.60006 VG", "Miner 2049er (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c529e63013698064149b9e0468afd941", "", "", "S.I.PLIX 2 (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "c52d9bbdc5530e1ef8e8ba7be692b01e", "Atari, Robert C. Polaro", "CX26130", "Holey Moley (02-29-1984) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5301f549d0722049bb0add6b10d1e09", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" }, - { "c5387fc1aa71f11d2fa82459e189a5f0", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL)", "AKA Weltraum-Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c53c0d10c74325deae9ba84074281983", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c541a5f6fc23b40a211196dd78233780", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1981) (Atari) (Prototype) (4K)", "Uses Joystick (left) and Keypad (right) Controllers", "Prototype", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "c54b4207ce1d4bf72fadbb1a805d4a39", "Billy Eno", "", "Sniper (Feb 30) (2001) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c560a3ecb7b751021953819efcfe5b41", "Omegamatrix", "", "Ghostbusters (Genesis)", "Genesis controller", "", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" }, - { "c569e57dca93d3bee115a49923057fd7", "", "", "Pac-Space (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c58708c09ccb61625cda9d15ddcd8be6", "SPIKE the Percussionist", "", "NOIZ Invaders (SPIKE) (2002) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5930d0e8cdae3e037349bfa08e871be", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c59633dbebd926c150fb6d30b0576405", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5a76bafc4676edb76e0126fb9f0fb2d", "Charles Morgan", "", "Zero Patrol (Charles Morgan) (Hack)", "Hack of Moon Patrol", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5bab953ac13dbb2cba03cd0684fb125", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c5bf03028b2e8f4950ec8835c6811d47", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a2]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5c7cc66febf2d4e743b4459de7ed868", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1983) (Atari) (PAL) [a]", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5d2834bf98e90245e545573eb7e6bbc", "CCE", "", "Snoopy and the Red Baron (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5dd8399257d8862f3952be75c23e0eb", "Atari - GCC", "CX2680", "RealSports Tennis (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5f71dfbdca9cc96b28643ff4d06aa6f", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c5fe45f2734afd47e27ca3b04a90213c", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "c63a98ca404aa5ee9fcff1de488c3f43", "Atari", "CX26145", "Venture (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c6556e082aac04260596b4045bc122de", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c6688781f4ab844852f4e3352772289b", "Atari, Tod Frye", "CX2695", "Xevious (08-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c67ff409f28f44883bd5251cea79727d", "", "", "Gunfight 2600 - Music & Bugfixes 1 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c689148ad9275667924ab334107b517e", "Jone Yuan Telephonic Enterprise Co", "", "Space Raid (Jone Yuan)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c68a6bafb667bad2f6d020f879be1d11", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c6ae21caceaad734987cb24243793bd5", "CCE", "", "Frostbite (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c6c63da3bc2e47291f63280e057061d0", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c6d48c6ae6461e0e82753540a985ac9e", "Ed Federmeyer", "", "Edtris (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c6d7fe7a46dc46f962fe8413c6f53fc9", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype) [a]", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c6db733e0b108c2580a1d65211f06dbf", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (07-09-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c738fc3f5aae1e8f86f7249f6c82ac81", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (16K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, - { "c73ae5ba5a0a3f3ac77f0a9e14770e73", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c745487828a1a6a743488ecebc55ad44", "Rainbow Vision - Suntek", "SS-002", "Galactic (1983) (Rainbow Vision) (PAL)", "AKA The Challenge of.... Nexar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c74bfd02c7f1877bbe712c1da5c4c194", "Thomas Jentzsch", "", "River Raid Tanks (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c7600d72247c5dfa1ec1a88d23e6c85e", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c77c35a6fc3c0f12bf9e8bae48cba54b", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c77d3b47f2293e69419b92522c6f6647", "Panda", "101", "Tank Brigade (1983) (Panda)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c7900a7fe95a47eef3b325072ad2c232", "Larry Petit", "", "Super Congo Bongo (2003) (Larry Petit) (Hack)", "Hack of Bongo", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c7d5819b26b480a49eb26aeb63cc831e", "Bit Corporation", "PGP210", "Ice Hockey (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Hockey, Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c7e43ad79c5e5c029d9f5ffde23e32cf", "", "", "PAL-NTSC Detector (15-11-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c7eab66576696e11e3c11ffff92e13cc", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c7f13ef38f61ee2367ada94fdcc6d206", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c82ec00335cbb4b74494aecf31608fa1", "CCE", "", "E.T. - The Extra-Terrestrial (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c830f6ae7ee58bcc2a6712fb33e92d55", "Atari, Michael Kosaka", "CX2687", "Tempest (01-05-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c866c995c0d2ca7d017fef0fc0c2e268", "Retroactive", "", "Qb (2.00) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c880c659cdc0f84c4a66bc818f89618e", "Thomas Jentzsch", "", "Open Sesame (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c89c3138a99fd1fd54367d65f75b0244", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c8c7da12f087e8d16d3e6a21b371a5d3", "", "", "Demo Image Series #9 - Genius (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c8e90fc944596718c84c82b55139b065", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype) [a]", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c8fa5d69d9e555eb16068ef87b1c9c45", "Atari", "CX26144", "Donkey Kong Junior (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c90788d9aa71a78bcc78c015edb22c54", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL60) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c9196e28367e46f8a55e04c27743148f", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c92cfa54b5d022637fdcbdc1ef640d82", "Retroactive", "", "Qb (V2.05) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c98e8c918a40b4d3a243dd6c49196330", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (PAL60) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "c9b7afad3bfd922e006a6bfc1d4f3fe7", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c9c25fc536de9a7cdc5b9a916c459110", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c9d02d3cfeef8b48fb71cb4520a4aa84", "", "", "Euchre (More for less) (PAL) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c9e721eb29c940c2e743485b044c0a3f", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "c9f6e521a49a2d15dac56b6ddb3fb4c7", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" }, - { "ca09fa7406b7d2aea10d969b6fc90195", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ca4f8c5b4d6fb9d608bb96bc7ebd26c7", "M Network - INTV - APh Technological Consulting, Hal Finney, Glenn Hightower, Peter Kaminski", "MT4317", "Adventures of TRON (1983) (M Network)", "AKA Tron Joystick", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ca50cc4b21b0155255e066fcd6396331", "Suntek", "SS-031", "UFO Patrol (1983) (Suntek) (PAL)", "AKA X'Mission", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ca53fc8fd8b3c4a7df89ac86b222eba0", "CCE", "C-812", "Pac Man (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ca54de69f7cdf4d7996e86f347129892", "PlayAround - J.H.M.", "201", "Philly Flasher (1982) (PlayAround)", "Uses the Paddle Controllers, AKA Beat 'Em & Eat 'Em", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, - { "ca7aaebd861a9ef47967d31c5a6c4555", "Atari, Bob Whitehead", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "ca7abc774a2fa95014688bc0849eee47", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ca7f166a94eed1a349dec6d6a358bcad", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cac9928a84e1001817b223f0cecaa3f2", "Amiga - Video Soft, Jerry Lawson, Dan McElroy", "", "3-D Genesis (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cad982c9b45bc5eff34e4ea982d5f1ca", "", "", "Song (17-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cade123747426df69570a2bc871d3baf", "Gakken", "011", "Marine Wars (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cae8f83c06831ec7bb6a3c07e98e9342", "Colin Hughes", "", "Tetris 2600 (Colin Hughes) [o1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cb18d8d5fbdcb1cd7bd36c5423348859", "", "", "RAM-Pong (NTSC) v1.0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cb24210dc86d92df97b38cf2a51782da", "Video Gems", "VG-01", "Missile Control (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cb4a7b507372c24f8b9390d22d54a918", "ITT Family Games", "554-37 338", "Peter Penguin (1983) (ITT Family Games) (PAL)", "AKA Frisco (Pumuckl-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cb8399dc0d409ff1f531ef86b3b34953", "", "", "Demo Image Series #12 - Luigi And Mario (01-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cb9626517b440f099c0b6b27ca65142c", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "cb96b0cf90ab7777a2f6f05e8ad3f694", "Silvio Mogno", "", "Rainbow Invaders", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cb9b2e9806a7fbab3d819cfe15f0f05a", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "931513", "Star Wars - Death Star Battle (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cba56e939252b05df7b7de87307d12ca", "", "", "Playfield Text Demo (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cbad928e10aeee848786cc55394fb692", "", "", "Fu Kung! (V0.06a Cuttle Cart Compatible) (15-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cbb0ee17c1308148823cc6da85bff25c", "", "", "Rotating Colors Demo 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cbc373fbcb1653b4c56bfabba33ea50d", "CCE", "", "Super Voleyball (CCE)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cbced209dd0575a27212d3eee6aee3bc", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cbd981a23c592fb9ab979223bb368cd5", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1982) (Atari)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cbe5a166550a8129a5e6d374901dffad", "Atari, Carla Meninsky - Sears", "CX2610 - 49-75127", "Warlords (1981) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, - { "cbeafd37f15e0dddb0540dbe15c545a4", "", "", "Black and White Fast Scolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cc03c68b8348b62331964d7a3dbec381", "Jone Yuan Telephonic Enterprise Co", "", "Marauder (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cc12581e079cd18330a89902625b8347", "Dave Neuman", "", "Space Battle (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cc1939e4769d0c157ace326efcfdcf80", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cc2973680c150886cce1ed8693c3aca2", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL) (4K)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cc3d942c6958bd16b1c602623f59e6e1", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cc7138202cd8f6776212ebfc3a820ecc", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (03-30-1983) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "cc724ebe74a109e39c0b2784ddc980ca", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cc74ddb45d7bc4d04c2e6f1907416699", "", "", "Colour Display Programme (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cca33ae30a58f39e3fc5d80f94dc0362", "", "", "Okie Dokie (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ccb56107ff0492232065b85493daa635", "Bit Corporation", "PG206 [demonstration cartridge]", "Bobby Is Going Home (1983) (BitCorp) (PAL) [demo cart]", "AKA Bobby geht Heim", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ccb5fa954fb76f09caae9a8c66462190", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1001", "Malagai (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ccb807eb79b0ed0f5fdc460445ef703a", "", "", "Superman (Stunt_Cycle_Rules!) (Hack)", "Hack of Superman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ccbd36746ed4525821a8083b0d6d2c2c", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [no copyright]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cccfe9e9a11b1dad04beba46eefb7351", "", "", "Poker Squares (V0.25) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ccd6ce508eee4b3fca67212833edcd85", "Otto Versand", "746422", "Hot Wave (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Ram It", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ccd92a269a4c2bd64d58cf2c0114423c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (09-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd032ab6764b55438a7b0bfb5e78595a", "", "", "Hangman Pac-Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd139ae6d09f3665ad09eb79da3f9e49", "Eric Mooney", "", "Invaders by Erik Mooney (4-24-97) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd34b3b3ef9e485201e841ba71beb253", "Bradford W. Mott", "", "Hit HMOVE At Various Cycles After WSYNC Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd38ad19f51b1048d8e5e99c86a2a655", "", "", "Demo Image Series #5 - Flag (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd399bc422992a361ba932cc50f48b65", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (Preview) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd3e26786136a4692fd2cb2dfbc1927e", "", "", "Multiple Moving Objects Demo 2 (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd4423bd9f0763409bae9111f888f7c2", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd4ded1ede63c4dd09f3dd01bda7458c", "Future Video Games", "", "Laser Gate (Future Video Games) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd568d6acb2f14477ebf7e59fb382292", "Videospielkassette - Ariola", "PGP235", "Fussball (Ariola) (PAL)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd5af682685cfecbc25a983e16b9d833", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (05-08-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd88ef1736497288c4533bcca339f881", "SEGA - Teldec", "005-10", "Buck Rogers - Planet of Zoom (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cd8fa2e9f6255ef3d3b9b5a4f24a54f7", "", "", "Daredevil (V2) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cd98be8a48ebf610c9609a688b9c57f2", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia) (Prototype)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cd9fea12051e414a6dfe17052067da8e", "Paul Slocum", "", "Marble Craze Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cda38714267978b9a8b0b24bee3529ae", "", "", "Space Instigators (V1.6) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cdadb57b34438805ee322ff05bd3d43e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cdb81bf33d830ee4ee0606ee99e84dba", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, - { "cdc1a5c61d7488eadc9aba36166b253d", "Retroactive", "", "Qb (V0.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cddabfd68363a76cd30bee4e8094c646", "Computer Magic - CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce17325834bf8b0a0d0d8de08478d436", "", "", "Boring Freeway (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce1cbe159b9ae5992dacf09371de5e13", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (01-19-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce243747bf34a2de366f846b3f4ca772", "Home Vision - Gem International Corp. - VDI", "", "Jacky Jump (1983) (Home Vision) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce4bbe11d682c15a490ae15a4a8716cf", "", "", "Okie Dokie (Older) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce5524bb18e3bd8e092273ef22d36cb9", "Carrere Video - JWDA, Todd Marshall, Wes Trager, Henry Will IV - Teldec - Prism", "USC1004", "Commando Raid (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce5cc62608be2cd3ed8abd844efb8919", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce64812eb83c95723b04fb56d816910b", "Retroactive", "", "Qb (V2.04) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ce6c4270f605ad3ce5e82678b0fc71f8", "", "", "Vertical Rainbow Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce82a675c773ff21e0ffc0a4d1c90a71", "", "", "Defender 2 (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ce8467ae2a3a5bc88ca72a2ce44ce28c", "SOLID Corp. (D. Scott Williamson)", "CX2655-015", "Star Castle 2600 (SolidCorp) (PAL) [015]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ce89529d6e98a13ddf3d84827bbdfe68", "", "", "Kung Fu Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ce904c0ae58d36d085cd506989116b0b", "Telegames", "5687 A279", "International Soccer (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cea9f72036dc6f7af5eff52459066290", "Retroactive", "", "Qb (2.07) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ceba7965a93c689bdecdb46a5b2ac0c1", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cedbd67d1ff321c996051eec843f8716", "Ultravision", "1044", "Karate (1982) (Ultravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cef01595000627ee50863d4290372c27", "", "", "Many Blue Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cef2287d5fd80216b2200fb2ef1adfa8", "Milton Bradley Company", "4363", "Spitfire Attack (1983) (Milton Bradley)", "AKA Flight Commander)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cf0c593c563c84fdaf0f741adb367445", "Retroactive", "", "Qb (V0.05) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cf3a9ada2692bb42f81192897752b912", "", "", "Air Raiders (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cf3c2725f736d4bcb84ad6f42de62a41", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL) [a]", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cf507910d6e74568a68ac949537bccf9", "SEGA, Jeff Lorenz", "003-01", "Thunderground (1983) (SEGA)", "AKA Underground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cf63ffac9da89ef09c6c973083061a47", "CCE", "C-859", "MASH (1983) (CCE)", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cf9069f92a43f719974ee712c50cd932", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cfad2b9ca8b8fec7fb1611d656cc765b", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL) [demo cart]", "demonstration cartridge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cfb3260c603b0341d49ddfc94051ec10", "Dactari - Milmar", "", "Boxing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfb83a3b0513acaf8be4cae1512281dc", "Starpath Corporation", "", "Going-Up (1983) (Starpath) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfc226d04d7490b69e155abd7741e98c", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari) (PAL)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfce5596a7e8ca13529e9804cad693ef", "Canal 3 - Intellivision", "", "Tennis (Canal 3) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfd5518c71552b8bb853b0e461e328d7", "Bit Corporation", "R320", "Spider Fighter (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfd6a8b23d12b0462baf6a05ef347cd8", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfdb4d0427a1ea8085c6bc6eb90259d8", "", "", "Gunfight 2600 - Release Candidate (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfe2185f84ce8501933beb5c5e1fd053", "", "", "Football (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfe62ed7125ff9fae99b4c8a367c0399", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfee10bd7119f10b136921ced2ee8972", "", "", "Space Instigators (V1.8) (19-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cfef1a2d1f6a5ee7a5e1f43f3056f112", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cff1e9170bdbc29859b815203edf18fa", "Retroactive", "", "Push (V0.01) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cff578e5c60de8caecbee7f2c9bbb57b", "George Veeder", "", "Suicide Adventure (George Veeder) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "cff9950d4e650094f65f40d179a9882d", "Paul Slocum", "", "Mr. Roboto (Paul Slocum) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "cfffc4b97d01cc3e7b9f47575f7b11ec", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) (PAL60)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d00f6f8ba89559e4b20972a478fc0370", "Spiceware", "SW-01", "Medieval Mayhem (PAL)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" }, - { "d010e3dfe7366e47561c088079a59439", "Retroactive", "", "Qb (V0.10) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d026716b3c5be2c951cc4c064317c524", "", "", "Fu Kung! (V0.06) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0498baca989e792db4b8270a02b9624", "", "", "Pac Ghost Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d071d2ec86b9d52b585cc0382480b351", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d078674afdf24a4547b4b32890fdc614", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d078d25873c5b99f78fa267245a2af02", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0796a0317abf9018d6745086bef411f", "Edward Smith", "", "Alien Attack (2018)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d08fccfbebaa531c4a4fa7359393a0a9", "Activision, David Crane, Bob Whitehead", "", "Venetian Blinds Demo (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d090836f0a4ea8db9ac7abb7d6adf61e", "Hozer Video Games", "", "Yahtzee (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d09935802d6760ae58253685ff649268", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d09a7504ee8c8717ac3e24d263e7814d", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d09f1830fb316515b90694c45728d702", "Imagic, Brad Stewart", "720105-1A, IA3400", "Fire Fighter (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0a379946ed77b1b126230ca68461333", "Ataripoll", "", "Atari Invaders (Ataripoll) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0af33865512e9b6900714c26db5fa23", "Telegames", "", "Armor Ambush (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0b26e908370683ad99bc6b52137a784", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo - RCA Video Jeux", "AP-2004", "Lost Luggage (1982) (Apollo) (PAL)", "AKA La valise piegee", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0b9df57bfea66378c0418ec68cfe37f", "20th Century Fox Video Games - Sirius, Grady Ward", "11002", "Beany Bopper (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0b9f705aa5f61f47a748a66009ae2d2", "", "", "Synthcart (14-01-2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d0cb28e1b7bd6c7f683a0917b59f707e", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0cdafcb000b9ae04ac465f17788ad11", "Quelle - Otto Versand", "732.273 8 - 600273, 781644", "Lilly Adventure (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0e05ba5f10e3df3023c5ee787f760ef", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0e15a3ce322c5af60f07343594392af", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) (4K)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d0e9beb2347595c6c7d158e9d83d2da8", "Retroactive", "", "Qb (2.00) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d100b11be34a1e5b7832b1b53f711497", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d15655fe355fa57dd541487dc5725145", "Rentacom", "", "Vanguard (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d170317ae4c7d997a989c7d6567c2840", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d175258b2973b917a05b46df4e1cf15d", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d17a671029b1532b197defca5f3649a7", "Hozer Video Games", "", "Gunfight 2600 - Limit broken again! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d17a8c440d6be79fae393a4b46661164", "", "", "Warring Worms (Beta 3) (2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d1a1841b7f2007a24439ac248374630a", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d1a9478b99d6a55e13a9fd4262da7cd4", "U.S. Games Corporation, Garry Kitchen - Vidtec", "VC1001", "Space Jockey (1982) (U.S. Games) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d1b4075925e8d3031a7616d2f02fdd1f", "", "", "Demo Image Series #7 - Two Marios (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d1c3520b57c348bc21d543699bc88e7e", "Gameworld", "133-002", "Warplock (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "YES", "" }, - { "d1ca47b262f952413c1234117c4e4e21", "Bit Corporation", "R320", "Missile Command (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d1d704a7146e95709b57b6d4cac3f788", "Atari, Warren Robinett", "CX26163P", "Slot Racers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d20e61c86ed729780feca162166912ca", "Supergame", "32", "Pitfall (1984) (Supergame)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d214c7a734e133a5c18e93229435b57a", "Digivision", "", "Mickey (Digivision)", "AKA Sorcerer's Apprentice", "", "", "", "UASW", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d223bc6f13358642f02ddacfaf4a90c9", "Rainbow Vision - Suntek", "SS-003", "Pac-Kong (1983) (Rainbow Vision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d245e2f27c84016041e9496b66b722fe", "", "", "Gunfight 2600 - The Final Kernel (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d25018349c544320bf3fd5092ee072bc", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d28afe0517a046265c418181fa9dd9a1", "", "", "Dodge 'Em (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d2901c34bb6496bb96c7bc78a9e6142a", "Greg Zumwalt", "", "Fish Revenge (2003) (Greg Zumwalt) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d2c4f8a4a98a905a9deef3ba7380ed64", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1001", "Sorcerer (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d2c8e6aa8172b16c8aa9aae739ac9c5e", "Activision, David Crane", "08-08-1980", "Laser Blast (08-08-1980) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d2c957dd7746521b51bb09fde25c5774", "Eckhard Stolberg", "", "Cubis (6K) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d2d8c4f1ea7f347c8bcc7d24f45aa338", "", "", "20 Sprites at Once Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d2deddb77c8b823e4be9c57cb3c69adc", "Canal 3 - Intellivision", "C 3007", "Snoopy and the Red Baron (Canal 3)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d2f713c78a9ebba9da6d10aeefc6f20f", "Digivision", "", "Enduro (Digivision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d3171407c3a8bb401a3a62eb578f48fb", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d326db524d93fa2897ab69c42d6fb698", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d339b95f273f8c3550dc4daa67a4aa94", "", "", "Laser Blast (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d341d39774277cee6a1d378a013f92ac", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d3423d7600879174c038f53e5ebbf9d3", "U.S. Games Corporation - Western Technologies", "VC2005", "Piece o' Cake (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, - { "d3456b4cf1bd1a7b8fb907af1a80ee15", "Avalon Hill, Duncan Scott", "5003002", "Wall Ball (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d34b933660e29c0a0a04004f15d7e160", "", "", "Multi-Color Demo 5 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d36308387241e98f813646f346e7f9f7", "King Atari", "", "Ghostbuster 2 (King Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d39e29b03af3c28641084dd1528aae05", "Funvision - Fund. Int'l Co.", "", "Spider Monster (1982) (Funvision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d3bb42228a6cd452c111c1932503cc03", "UA Limited", "", "Funky Fish (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d44d90e7c389165f5034b5844077777f", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d45bf71871b196022829aa3b96bfcfd4", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d45ebf130ed9070ea8ebd56176e48a38", "SEGA, Jeff Lorenz", "001-01", "Tac-Scan (1983) (SEGA)", "Uses the Paddle Controllers (right only)", "", "", "", "", "", "", "", "YES", "", "", "YES", "", "", "AUTO 60", "", "", "YES", "" }, - { "d47387658ed450db77c3f189b969cc00", "PlayAround - J.H.M.", "206", "Westward Ho (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d4806775693fcaaa24cf00fc00edcdf3", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (1987) (Atari) (PAL)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d483f65468d9a265661917bae1a54f3e", "Joe Grand", "", "SCSIcide Pre-release 3 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d4942f4b55313ff269488527d84ce35c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d49aff83f77a1b9041ad7185df3c2277", "", "", "Space Treat (60% complete) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d4aa89e96d2902692f5c45f36903d336", "", "", "Euchre (NTSC) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d4c590ccfb611a73b3331359700c01a3", "", "", "Sprite Movement Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d541b20eae221a8ee321375e5971e766", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d54cd41ecfd59e4b72d2c086152b9a75", "Amiga - Video Soft - Michael K. Glass, Jerry Lawson", "1110", "Power Play Arcade Video Game Album (1983) (Amiga) (Prototype)", "3-D Ghost Attack only (3-D Genesis & 3-D Havoc missing in ROM)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d5618464dbdc2981f6aa8b955828eeb4", "CCE", "C-829", "Megamania (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d563ba38151b8204c9f5c9f58e781455", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d573089534ca596e64efef474be7b6bc", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL) [a]", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, - { "d57913088e0c49ac3a716bf9837b284f", "Activision, Garry Kitchen", "EAZ-032", "Pressure Cooker (1983) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d57eb282d7540051bc9b5427cf966f03", "Atari Troll", "", "Custer's Viagra (Atari Troll) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d597d35c6022c590d6e75e865738558a", "", "", "Sprite Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d5aa7472e7f2cc17e893a1a36f8dadf0", "", "", "Overhead Adventure Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d5c6b81212ad86fd9542a1fedaf57cae", "", "", "Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d5d2d44fb73785996ccc24ae3a0f5cef", "Robby", "", "Grand Prix (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d5e17022d1ecc20fd9b53dc464c302f1", "Activision, Carol Shaw", "EAX-020", "River Raid (1982) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d5e27051512c1e7445a9bf91501bda09", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d5e5b3ec074fff8976017ef121d26129", "Star Game", "003", "River Raid (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d5f965c159e26a1fb49a22a47fbd1dd0", "Supergame", "", "River Raid II (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d605ed12f4eaaaec3dcd5aa909a4bad7", "", "", "Chronocolor Frame Demo (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d61629bbbe035f45552e31cef7d591b2", "", "", "Atari Logo Demo (PD) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d62283aed0f4199adb2333de4c263e9c", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner", "CX2615", "Demons to Diamonds (1982) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" }, - { "d62d7d1a974c31c5803f96a8c1552510", "", "", "StarMaster (Unknown) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d632b74fea533d593af82cf16e7c5e4a", "", "", "Fu Kung! (V0.13) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d65028524761ef52fbbdebab46f79d0f", "CCE", "", "Galaxian (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d65900fefa7dc18ac3ad99c213e2fa4e", "", "", "Guntest (2000) (Eckhard Stolberg)", "Light Gun Test (based on Sentinel code)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d69559f9c9dc6ef528d841bf9d91b275", "Activision, Alan Miller", "AX-016", "StarMaster (1982) (Activision)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d6a44277c3eb4f9d039185e0ecf7bfa6", "", "", "Trick (1997) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d6acff6aed0f04690fe4024d58ff4ce3", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL) [different spaceship]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d6b8beeb05e5b730084d4b8f381bbf8d", "", "", "208 in 1 Game Select ROM (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d6d1ddd21e9d17ea5f325fa09305069c", "Funvision - Fund. International Co.", "", "Time Warp (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d6d5dd8fd322d3cf874e651e7b6c1657", "", "", "How to Draw a Playfield (1997) (Nick Bensema) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d6dc9b4508da407e2437bfa4de53d1b2", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb) (PAL)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d726621c676552afa503b7942af5afa2", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d73ad614f1c2357997c88f37e75b18fe", "Goliath", "7", "Space Tunnel (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d74a81fcd89c5cf0bd4c88eb207ebd62", "", "", "Poker Squares (V0.00a) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d763e3a9cdcdd56c715ec826106fab6a", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d7759fa91902edd93f1568a37dc70cdb", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d782543818b6320e4f60d77da2b596de", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d787ec6785b0ccfbd844c7866db9667d", "Retroactive", "", "Qb (V0.04) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d7891b0faa4c7f764482762d0ed427a5", "", "", "Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d7b2259f6bb57bf37eac82365c1f8ad6", "Parker Brothers, Mike Brodie", "PB5320", "Super Cobra (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d7b58303ec8d8c4dbcbf54d3b9734c7e", "", "", "Paddle Demo (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d7dd56677e4ec1e6627419478a4a9668", "", "", "Shadow Keep (Fixed) (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d7f5bf138cfc7feab7b8ef1534c8b477", "", "", "Eric Bergstrom's KC-135 (Radar Map) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d816fea559b47f9a672604df06f9d2e3", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d81bb6965e6c99b3be99ffd8978740e4", "", "", "Gunfight 2600 - The Final Kernel Part 3 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d82675ce67caf16afe5ed6b6fac8aa37", "Thomas Jentzsch", "", "Robot City (V0.23) (13-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d8295eff5dcc43360afa87221ea6021f", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d82c8a58098a6b46c5b81c16180354d1", "Dennis Debro", "", "Climber 5 (30-10-2002) (Dennis Debro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d85f1e35c5445ac898746719a3d93f09", "Suntek", "SS-034", "Farmyard Fun (1983) (Suntek) (PAL)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d86deb100c6abed1588aa84b2f7b3a98", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d88691c995008b9ab61a44bb686b32e4", "", "", "Warring Worms (07-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d89262907e70c13dff23356c4a9055d0", "Bit Corporation", "R320", "Video Pinball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d89fedded0436fdeda7c3c37e2fb7cf1", "", "", "Surround (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d8acaa980cda94b65066568dd04d9eb0", "CCE", "", "Sea Hunt (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d8b2c81cea5af04f795eb3dc6573d72b", "", "", "Tunnel Demo 2 (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d8df256c0d89e494a9fb3e9abb8e44ac", "Imagic, Michael Greene", "IA3312P", "No Escape! (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d8e4c8e2d210270cd1e0f6d1b4582b91", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d90205e29bb73a4cdf28ea7662ba0c3c", "Thomas Jentzsch", "", "Boulderdash Demo (Brighter Version) (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d912312349d90e9d41a9db0d5cd3db70", "CCE", "C-818", "Star Voyager (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d9548ad44e67edec202d1b8b325e5adf", "Apollo - Games by Apollo, Dan Oliver - RCA Video Jeux", "AP-2002", "Space Cavern (1982) (Apollo) (PAL)", "AKA Les guerriers de l'espace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d968de2b4ff18bfe4a95066cde310578", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d97e3d0b4575ce0b9a6132e19cfeac6e", "Fabrizio Zavagli", "", "Space Treat (061002) (PD)", "Won't work with Stella < V1.2", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d97fd5e6e1daacd909559a71f189f14b", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (04-20-1983) (M Network) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d9ab6b67a17da51e5ad13717e93fa2e2", "Thomas Jentzsch", "", "Turbo (Coleco) Prototype Fake v0.1 (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d9b49f0678776e04916fa5478685a819", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d9bd343533b61389b270c0787210943b", "Atari, Douglas 'Solaris' Neubauer", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Genesis controller (C switches to map mode)", "Hack of Last Starfighter (Solaris prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "d9c9cece2e769c7985494b1403a25721", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "d9da2ae7c7894a29b43b3c6b79f3b7a2", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, - { "d9fbf1113114fb3a3c97550a0689f10f", "ZiMAG - Emag - Vidco", "713-111 - GN-050", "Pizza Chef (1983) (ZiMAG) (Prototype)", "AKA Pizza Time", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "da0fb2a484d0d2d8f79d6e063c94063d", "", "", "Air Raiders (1982) (Unknown) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "da4e3396aa2db3bd667f83a1cb9e4a36", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "da5096000db5fdaa8d02db57d9367998", "Digitel", "", "River Raid (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "da6465a34d2e44d26aa9a2a0cd1bce4d", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "da66d75e4b47fab99733529743f86f4f", "Digitel", "", "Chopper Command (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "da732c57697ad7d7af414998fa527e75", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari) (PAL)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "da79aad11572c80a96e261e4ac6392d0", "Salu - Ubi Soft, Dennis M. Kiss", "460673", "Pick 'n' Pile (1990) (Salu) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" }, - { "da7a17dcdaa62d6971393c0a6faf202a", "", "", "Flag Capture (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dab844deed4c752632b5e786b0f47999", "", "", "Super Challenge Baseball (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dac38b4dd3da73bb7b2e9d70c61d2b7c", "", "", "Hangman Monkey Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dac5c0fe74531f077c105b396874a9f1", "Atari - GCC", "CX2680", "RealSports Tennis (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dac762e4d01d445bdef20b7771f6570e", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K) [a]", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" }, - { "dad2ab5f66f98674f12c92abcfbf3a20", "", "", "Blue and White Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "daeb54957875c50198a7e616f9cc8144", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11005", "Mega Force (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "daef7d8e5a09981c4aa81573d4dbb380", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack)", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "dafc3945677ccc322ce323d1e9930beb", "Atari", "", "A-Team (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "db1753cc702c18d3917ec7f3b0e8659f", "", "", "Frame Counter 2 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "db339aea2b65b84c7cfe0eeab11e110a", "", "", "Chronocolor Frame Demo 2 (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "db4eb44bc5d652d9192451383d3249fc", "CBS Electronics - E.F. Dreyer - VSS, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "db5073bd75eb05f7d62a7268396d1e77", "Atari", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "db76f7a0819659d9e585f2cdde9175c7", "Xonox", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "db80d8ef9087af4764236f7b5649fa12", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "db971b6afc9d243f614ebf380af0ac60", "Gammation, Robert L. Esken Jr.", "", "Gamma-Attack (1983) (Gammation)", "Uses right joystick controller", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "dba270850ae997969a18ee0001675821", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (4K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "dbabb80e92ff18d8eecf615c0539151e", "", "", "Sprite Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dbb10b904242fcfb8428f372e00c01af", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dbba14a0f69f0e13fdccb3fde3baedca", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dbc7485ad5814d466de780a3e7ed3b46", "Kyle Pittman", "", "Pink Floyd (Kyle Pittman) (PD)", "Hack of Adventures of Tron (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dbc8829ef6f12db8f463e30f60af209f", "Data Age", "DA1001", "Encounter at L-5 (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, - { "dbdaf82f4f0c415a94d1030271a9ef44", "CCE", "", "Kaboom! (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "dbdd21e1ee3d72119e8cd14d943c585b", "", "", "Slot Machine (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dc13df8420ec69841a7c51e41b9fbba5", "Atari, Mimi Nyden, Steve Woita", "CX26132", "Garfield (06-21-1984) (Atari) (Prototype)", "AKA Garfield on the Run", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dc33479d66615a3b09670775de4c2a38", "Suntek", "SS-033", "I.Q. Memory Teaser (1983) (Suntek) (PAL)", "AKA IQ 180", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dc81c4805bf23959fcf2c649700b82bf", "Imagic, Michael Greene", "720055-2A, IA3312P", "No Escape! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dc905b22de0f191a029df13eddfcabc4", "Atari, Warren Robinett", "", "Elf Adventure (05-02-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dc97cbcf091a5ef4ca7fe95dc0848036", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dca90ea1084a2fdbe300d7178ca1a138", "Imagic, Dennis Koble", "IA3000P", "Trick Shot (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "dca941dab5c6f859b71883b13ade9744", "", "", "Hangman Pac-Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dcba0e33aa4aed67630a4b292386f405", "Retroactive", "", "Qb (V2.08) (Half Speed Version) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "dcc2956c7a39fdbf1e861fc5c595da0d", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5664", "Frogs and Flies (1982) (M Network)", "AKA Frogs 'n' Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dcec46a98f45b193f07239611eb878c2", "", "", "Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd08e18cfee87a0e7fc19a684b36e124", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd0cbe5351551a538414fb9e37fc56e8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd0de0f61af2a2a4878e377b880a3933", "SOLID Corp. (D. Scott Williamson)", "CX2655-013", "Star Castle 2600 (SolidCorp) [013]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "dd10b5ee37fdbf909423f2998a1f3179", "", "", "Space Instigators (V1.9) (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd13a16d14100819f79b1ce3a5bf499c", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd1422ffd538e2e33b339ebeef4f259d", "Atari, Michael Sierchio", "", "Football Demo (1982) (Atari)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd17711a30ad60109c8beace0d4a76e8", "", "", "Karate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd1842ba0f3f9d94dccb21eaa0f069b7", "Bit Corporation", "R320", "Defender (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd45e370aceff765f1e72c619efd4399", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd4f4e0fbd81762533e39e6f5b55bb3a", "Thomas Jentzsch", "", "Turbo WIP (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd7598b8bcb81590428900f71b720efb", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd7884b4f93cab423ac471aa1935e3df", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "dd8a2124d4eda200df715c698a6ea887", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dd92d6ad50976f881d86b52d38616118", "SpkSoft", "", "River Raid (SpkSoft) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dda23757407c4e217f64962c87ad0c82", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack) [a]", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ddd1efc1862cd3eb3baf4cba81ff5050", "", "", "Max3 (2001) (Maxime Beauvais) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de0173ed6be9de6fd049803811e5f1a8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99008, 6240", "Motocross Racer (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de07e9cb43ad8d06a35f6506e22c62e9", "", "", "Oh No! (Version 4) (22-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de1a636d098349be11bbc2d090f4e9cf", "", "", "Pressure Gauge (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de1e9fb700baf8d2e5ae242bffe2dbda", "Activision - Imagineering, Mike Reidel", "EAK-043-04I", "Commando (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de24f700fd28d5b8381de13abd091db9", "CCE", "", "Plaque Attack (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de29e46dbea003c3c09c892d668b9413", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "4L1717, 4L1718, 4L1719, 4L2277", "Carnival (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de3d0e37729d85afcb25a8d052a6e236", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "de4436eaa41e5d7b7609512632b90078", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de5aab22e5aba5edcb29a3e7491ff319", "Star Game", "001", "Donkey Kong (Star Game)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de61a0b171e909a5a4cfcf81d146dbcb", "Rainbow Vision - Suntek", "SS-005", "Tom Boy (1983) (Rainbow Vision) (PAL)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de62f8a30298e2325249fe112ecb5c10", "CCE", "C-810", "Enduro (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de78b3a064d374390ac0710f95edde92", "Bomb - Onbase", "CA281", "Assault (1983) (Bomb)", "AKA Sky Alien", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de7a64108074098ba333cc0c70eef18a", "", "", "Nuts (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "de7bca4e569ad9d3fd08ff1395e53d2d", "Thomas Jentzsch", "", "Thrust (V1.22) (2000) (TJ)", "Supports BoosterGrip", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "" }, - { "de8443ff47283e7b274a7838cb071fb6", "Atari, Lou Harp", "CX26122", "Sinistar (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dea0ade296f7093e71185e802b500db8", "CCE", "", "Fishing Derby (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "deb39482e77f984d4ce73be9fd8adabd", "Activision, David Lubar", "AK-048-04", "River Raid II (1988) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ded26e1cb17f875a9c17515c900f9933", "", "", "Space Treat (29-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df12953b919844dad2070ed2e70c9fa2", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype) (PAL)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df2745d585238780101df812d00b49f4", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df3e6a9b6927cf59b7afb626f6fd7eea", "", "", "Tuby Bird (208 in 1) (Unknown) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df40af244a8d68b492bfba9e97dea4d6", "Franklin Cruz", "", "Asteroids 2 (Franlin Cruz) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "df5cc5cccdc140eb7107f5b8adfacda1", "Cracker Jack Productions", "", "Lumberman (Cracker Jack) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df62a658496ac98a3aa4a6ee5719c251", "Atari, Tom Reuterdahl - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari)", "AKA Arcade Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df6a28a89600affe36d94394ef597214", "Apollo - Games by Apollo, Dan Oliver", "AP-2002", "Space Cavern (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df6a46714960a3e39b57b3c3983801b5", "Puzzy - Bit Corporation", "PG201", "Sea Monster (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df753cb87d3af4d03f694ab848638108", "CBS Electronics, Bob Curtiss", "4L1845, 4L1852, 4L1853, 4L1854", "Solar Fox (1983) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df91277a3569344b89e6e8bd5bebc8d1", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "df95e4af466c809619299f49ece92365", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (06-03-1983) (Atari) (Prototype) (PAL)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dfad86dd85a11c80259f3ddb6151f48f", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dfafa3fa58f5cc3f0342cca475df6095", "", "", "Space Treat (V1.1 Beta) (24-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dfc03ef371cf5163f54c50d8ee73c8cf", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dfc3dbbb39f05d7dd8ee3ac987478970", "", "", "Imagic Selector ROM (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dfcdd6f593bb7b05dbc2e8e1fc6ee0de", "", "", "Gunfight 2600 - Scenarios complete (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dfe034297200dff672df9533ed1449a9", "", "", "Sprite Movement Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dfe6aa7443bb813cefa35a4cf4887422", "", "", "This Planet Sucks (Greg Troutman) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "dff33523ccd2fdc8912e84cab8e0d982", "", "", "Fu Kung! (V0.03) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e01e00504e6d4b88fa743c0bbe8a96e5", "", "", "Qb (Special Edition, some bugfixes) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e020f612255e266a8a6a9795a4df0c0f", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (PAL)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e02156294393818ff872d4314fc2f38e", "Sancho - Tang's Electronic Co.", "TEC005", "Dice Puzzle (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e0221c95aa657f5764eeeb64c8429258", "", "", "Tomb Raider 2600 [REV 02] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e03b0b091bea5bc9d3f14ee0221e714d", "CBS Electronics, Bob Curtiss", "4L1852, 4L1853, 4L1854, 4L1855", "Solar Fox (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e040df95a055b18ebdb094e904cb71b2", "", "", "Score Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e04f1c1e4401d584d3f4343410a5bcc4", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e0b24c3f40a46cda52e29835ab7ad660", "Quelle - Otto Versand", "626.502 9 - 746381", "Top Gun (1983) (Quelle) (PAL)", "AKA Air Raiders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e0cf2dcc4c1348c468f5bb1e421c9164", "", "", "Invader Sprites in a Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e0de3773f5b867795db557be7b8a703e", "", "", "Boulderdash (13 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e0eff071f578ecf19edc2ab276644e46", "", "", "Gas Gauge Demo (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1029676edb3d35b76ca943da7434da8", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (10-30-1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e10bf1af6bf3b4a253c5bef6577fe923", "Rob Kudla", "", "Space Invaders (1978) (Atari) [h1]", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e10d2c785aadb42c06390fae0d92f282", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1143b72a30d4d3fee385eec38b4aa4d", "", "", "Word Zapper (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e12e32dee68201b6765fcd0ed54d6646", "Atari, Larry Kaplan", "CX2612, CX2612P", "Street Racer (1977) (Atari) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 75", "", "", "", "" }, - { "e13818a5c0cb2f84dd84368070e9f099", "CCE", "C-839", "Misterious Thief, A (1983) (CCE)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e13c7627b2e136b9c449d9e8925b4547", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1486c7822c07117b4f94a32e5ed68c1", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-14-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e14dc36b24fe22c04fa076e298f2e15f", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (16K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "e14feddeb82f5160ed5cf9ca4078e58d", "", "", "SpaceMaster X-7 (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e150f0d14f013a104b032305c0ce23ef", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e15b5525cf8f77297b322838df8d999c", "", "", "Sprite Demo 0 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e171558c51bb3bac97bfa79fa2c1a19c", "", "", "Warring Worms (Tim Strauss Edition) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e17699a54c90f3a56ae4820f779f72c4", "Rainbow Vision - Suntek", "SS-020", "Tuby Bird (1983) (Rainbow Vision) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e18abe87035379c56b435bfe8175077b", "Grimlock", "", "Rumble 2600 (Grimlock) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1a51690792838c5c687da80cd764d78", "20th Century Fox, John Russell", "", "Alligator People (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1b90f1e01b1a316d7bbf141525cc00e", "", "", "Sky Jinks (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1d5c8213e82820128fa9c4775f1e166", "Jess Ragan", "", "Jungle King (2003) (Jess Ragan) (Hack)", "Hack of Jungle Hunt", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1d79e4e7c150f3861256c541ec715a1", "", "", "Space Jockey (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1e09e2f280e8e142121a377d0dc1b46", "Thomas Jentzsch", "", "Thrust (V1.21) (2000) (TJ)", "Bugfixed", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "" }, - { "e1efe2ef7664bb6758b1a22ff8ea16a1", "Dynacom", "", "Enduro (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e1f88da6da8a7d521ca1dcbf2bc6978b", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e21ee3541ebd2c23e817ffb449939c37", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001", "King Kong (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e227be19f572f6900e314213ae9a4deb", "Atari, Dan Hitchens, Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (Prototype)", "AKA Adventure I, SwordQuest I - EarthWorld", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e237ee91514d5ed535c95a14fc608c11", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e2389c0be5b5b84e0d3ca36ec7e67514", "Retroactive", "", "Qb (V2.09) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e24d7d879281ffec0641e9c3f52e505a", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype)", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e25e173740f7ecc0e23025445c4591f3", "Greg Zumwalt", "", "Comitoid (Greg Zumwalt)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e275cbe7d4e11e62c3bfcfb38fca3d49", "M Network - INTV - APh Technological Consulting, Ken Smith", "MT5658", "Super Challenge Football (1982) (M Network)", "AKA Pro Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e27d518993b0a010f16e92b971ecdcdd", "Manuel Polik", "", "Star Fire (2003) (XYPE) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e28113d10c0c14cc3b5f430b0d142fcb", "CCE", "C-816", "Keystone Kappers (1983) (CCE) [a]", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e2846af3e4d172b251ab77cbdd01761e", "Steve Engelhardt", "", "Adventure Plus (2003) (Steve Engelhardt) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e2904748da63dfefc8816652b924b642", "Jone Yuan Telephonic Enterprise Co", "", "Catch Time (Jone Yuan)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e2b682f6e6d76b35c180c7d847e93b4f", "", "", "Dodge Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e2c1b60eaa8eda131632d73e4e0c146b", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e2c89f270f72cd256ed667507fa038a2", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e2ca84a2bb63d1a210ebb659929747a9", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys) (PAL)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e2eccbbe963f80f291cb1f18803bf557", "Atari, Joe Decuir, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e30f3a37032da52d7815b5a409f6d4b4", "SEGA, Fred Mack", "", "Bear Game Demo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e314b42761cd13c03def744b4afc7b1b", "Activision, David Crane, Dan Kitchen", "AZ-108-04", "Ghostbusters (1985) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e34c236630c945089fcdef088c4b6e06", "Activision, Steve Cartwright, David Crane - Ariola", "EAB-035-04 - 711 035-721", "Pitfall II (1984) (Activision) (PAL)", "Lost Caverns", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e3533684a7ef930a7fbd0c4dd8ec4847", "CCE", "C-856", "Pimball (1983) (CCE)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e3600be9eb98146adafdc12d91323d0f", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e363e467f605537f3777ad33e74e113a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e377c3af4f54a51b85efe37d4b7029e6", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e37c8055d70979af354251ebe9f1b7dd", "HES", "", "Mega Funpak - Gorf, P. Patrol, Pacman, Skeet Shoot (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e38dc1f81a02e325562cd285123f579b", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e39843c56b7a4a08b18fa7949ec3ee6b", "", "", "Joshua Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e39a13b13dc82c5fdbfbbfd55ba1230e", "", "", "Analog Clock (Additional Frame Info) (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e3c0451d29dad724231bc5818ec4bae0", "", "", "Single-Scanline Positioning Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e3c35eac234537396a865d23bafb1c84", "TechnoVision - Video Technology", "TVS1001", "Nuts (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e3ed4ba3361756970f076e46e9cad1d2", "", "", "Tennis (Unknown) (PAL) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e40a818dac4dd851f3b4aafbe2f1e0c1", "Atari, Bill Aspromonte, Dr. Lee Salk", "CX26135", "Peek-A-Boo (1984) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e42b937c30c617241ca9e01e4510c3f6", "", "", "Pitfall! (No Walls Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e434c0e161dd3c3fb435eb6bad2e182c", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e48d3a4056ede9393586421996db1ae8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e49ac0ec879a0d7820bc2598fc2cfcd4", "CCE", "", "Kaboom! (CCE) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "e4a0b28befaaa2915df1fa01238b1e29", "", "", "Gunfight 2600 - Red River (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e4afe157c09962cf39cdb25845d83d47", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e4b12deaafd1dbf5ac31afe4b8e9c233", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack) [a]", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e4bff1d5df70163c0428a1ead309c22d", "Atari, Robert C. Polaro, Alan J. Murphy", "CX2609, CX2609P", "Defender (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e4c00beb17fdc5881757855f2838c816", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e4c2077a18e3c27f4819aa7757903aa0", "", "", "Many Blue Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e4c666ca0c36928b95b13d33474dbb44", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e4d41f2d59a56a9d917038682b8e0b8c", "Cody Pittman", "", "Kiss Meets Pacman (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e4e9125a8741977583776729359614e1", "SnailSoft", "", "Comitoid beta 4 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e4fa739c81b003c92bea7da5e84c7feb", "Akor", "", "TV Boy (1992) (Akor) (NTSC) [bad dump]", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "e505bd8e59e31aaed20718d47b15c61b", "Funvision - Fund. Int'l Co.", "", "Space War (1982) (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e51030251e440cffaab1ac63438b44ae", "Parker Brothers - On-Time Software, Joe Gaucher, Louis Marbel", "PB5110", "James Bond 007 (1984) (Parker Bros)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e51c23389e43ab328ccfb05be7d451da", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e5359cbbbff9c6d7fe8aeff5fb471b46", "CCE", "C-849", "Boom Bang (1983) (CCE)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e549f1178e038fa88dc6d657dc441146", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e556e07cc06c803f2955986f53ef63ed", "Coleco - Individeo, Ed Temple", "2665", "Front Line (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e558be88eef569f33716e8e330d2f5bc", "Shock Vision", "", "Keystone Kapers (Shock Vision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e56da674188ba2f02c7a0a343a01236f", "", "", "This Planet Sucks Demo 4 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e59d022d524d05acc19515598c831e4d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118 (PAL)", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e5a6e0bb7d56e2f08b237e15076e5699", "", "", "Color Table Display Helper (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e5bacf526036d3c8c99db5b030cf00e7", "", "", "Starmaster (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Starmaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e5d5085123a98c1e61818caa2971e999", "", "", "Euchre (PAL) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e5d72ff8bab4450be57785cc9e83f3c0", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames) (PAL)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e5ecd78edd24326a968809decbc7b916", "Imagic, Bob Smith", "720020-1A, IA3611", "Cheese (Dragonfire Beta) (05-21-1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e5f17b3e62a21d0df1ca9aee1aa8c7c5", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid)", "AKA Termite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e5f360226dc552aba3e7e9b202330f48", "Supercat", "", "Mega Bitmap Demo (2007) (Supercat)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e5f84930aa468db33c0d0f7b26dd8293", "CCE", "C-826", "Grand Prix (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e5fcc62e1d73706be7b895e887e90f84", "", "", "Air-Sea Battle (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e600f5e98a20fafa47676198efe6834d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e609e8a007127b8fcff79ffc380da6b1", "", "", "Multi-Sprite Game V2.3 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e61210293b14c9c4ecc91705072c6a7e", "Gameworld", "133-005", "Bugs (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, - { "e62e60a3e6cb5563f72982fcd83de25a", "Jone Yuan Telephonic Enterprise Co", "", "End of the World (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e63a87c231ee9a506f9599aa4ef7dfb9", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e63efdfda9a4003dcd77a854a781a06a", "Paul Slocum", "", "Combat Rock (PD) (Hack) [a]", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e643aaec9a9e1c8ab7fe1eae90bc77d7", "Roger Williams", "", "Asymmetric Playfield (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e64a8008812327853877a37befeb6465", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1002", "Gauntlet (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e6508b878145187b87b9cded097293e7", "", "", "Oystron (V2.8) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e66e5af5dea661d58420088368e4ef0d", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e67b0ed32fd9d28d12ab3775d52e8c3a", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, - { "e6d5948f451a24994dfaaca51dfdb4e1", "Jone Yuan Telephonic Enterprise Co", "", "Football (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e6de4ef9ab62e2196962aa6b0dedac59", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-2A, 13206", "Solar Storm (1983) (Imagic) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, - { "e6e5bb0e4f4350da573023256268313d", "Thomas Jentzsch", "", "Missile Control (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e6f49a1053c79211f82be4d90dc9fe3d", "", "", "Gunfight 2600 - Little progress... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e723ad8f406cb258b89681ef4cef0eff", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "e72eb8d4410152bdcb69e7fba327b420", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e72ee2d6e501f07ec5e8a0efbe520bee", "Imagic, Dave Johnson", "720119-2A, 13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e73838c43040bcbc83e4204a3e72eef4", "CCE", "", "Apples and Dolls (CCE)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e74022cfe31ec8908844718dfbdedf7a", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e77ec259e1387bc308b0534647a89198", "Parker Brothers, David Lamkins, Laura Nikolich", "931503", "Spider-Man (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e77f332b71f13884c84771e7a121182d", "Jone Yuan Telephonic Enterprise Co", "", "Hey! Stop! (Jone Yuan)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e784a9d26707cfcd170a4c1c60422a72", "Quelle", "147.443 6", "Gefecht im All (1983) (Quelle) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e7864caaf9ec49ed67b1904ce8602690", "", "", "Donkey Kong 2K3 Pic (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e7a758bb0b43d0f7004e92b9abf4bc83", "", "", "Troll's Adventure (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e7dd8c2e6c100044002c1086d02b366e", "Activision, Steve Cartwright - Ariola", "EAX-013, PAX-013, 711 013-720", "Barnstorming (1982) (Activision) (PAL)", "AKA Die tollkeuhnen Flieger", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e7f005ddb6902c648de098511f6ae2e5", "Spectravideo - Universum", "SV-010", "CompuMate (1983) (Spectravideo) (PAL)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "COMPUMATE", "", "", "", "", "", "", "YES", "80" }, - { "e800e4aec7c6c54c9cf3db0d1d030058", "", "", "Qb (2.06) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e80a4026d29777c3c7993fbfaee8920f", "", "", "Frisco (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e823b13751e4388f1f2a375d3560a8d7", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (Preview) (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e879b7093ac4cfad74c88d636ca97d00", "", "", "Poker Squares (V0.0f) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e88340f5bd2f03e2e9ce5ecfa9c644f5", "", "", "Lock 'n' Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e8a3473bf786cf796d1336d2d03a0008", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-05-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e8aa36e3d49e9bfa654c25dcc19c74e6", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX2601, CX2601P", "Combat (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e8e7b9bdf4bf04930c2bcaa0278ee637", "", "", "Boring Taz (Hack)", "Hack of Taz", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e8f7679359c4f532f5d5e93af7d8a985", "", "", "Hangman Invader Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e9034b41741dcee64ab6605aba9de455", "Digivision", "", "Phanton Tank (Digivision)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e908611d99890733be31733a979c62d8", "Atari, Dan Hitchens, Mimi Nyden", "CX2697", "Mario Bros. (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e91d2ecf8803ae52b55bbf105af04d4b", "Atari, Howard Scott Warshaw", "CX2655, CX2655P", "Yars' Revenge (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e923001015bedd7901569f035d9c592c", "", "", "Adventure II (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e927ecf80f3784d745abd8368d78f2f3", "", "", "Space Instigators (V1.8) (19-10-2002) (CT) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e932f44fad2a66b6d5faec9addec208e", "", "", "Atari Logo Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e94632b0d863dd76459d689a9865bb33", "Jone Yuan Telephonic Enterprise Co", "", "Combat (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e957eb4612d6bd5940d3492dfa749668", "", "", "Tunnel Demo (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e959b5a2c882ccaacb43c32790957c2d", "", "", "Phantom II & Pirate (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e97eafd0635651d3999cece953c06bd5", "", "", "M.A.S.H (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e9be3e8e4a7e73dd63ed4235a3a1a25f", "", "", "MMetall (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e9c5d04643855949a23ff29349af74ea", "", "", "SCSIcide (Score Hack 2) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e9c71f8cdba6037521c9a3c70819d171", "Action Hi Tech - Hi-Score", "", "Bank Heist (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e9cb18770a41a16de63b124c1e8bd493", "Parker Brothers - Roklan, Joe Gaucher", "931519", "Popeye (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "e9db2f91efe6ff7ea3546e2c2578fb09", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" }, - { "e9e646f730b8400cd5da08c849ef3e3b", "Tron", "", "Enduro (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e9e6ad30549a6e2cd89fe93b7691d447", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (05-27-1987) (Atari) (Prototype) (PAL)", "AKA Nile Flyer, Sphinx", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "e9f25c7af4f27c9e1b5b8f6fe6141e8c", "Champ Games", "CG-03-N", "Scramble (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" }, - { "ea38fcfc06ad87a0aed1a3d1588744e4", "Atari, Lou Harp", "CX26122", "Sinistar (01-XX-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ea6d40db5498d6386571a76df448aa4c", "", "", "Vertical Playfield Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ea7e25ade3fe68f5b786ee0aa82b1fe5", "", "", "Galatic (208 in 1) (Unknown) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ea832e2cb6aae6f525f07452c381fa48", "", "", "Polar to Cartesian and VV (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ea86176b27ab0da8cce8f0179884bfaa", "", "", "Demo Image Series #10 - It's Art (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eaacfcdc1d4ee1258429b7ae7f084125", "Telegames", "6057 A227", "Quest for Quintana Roo (1989) (Telegames)", "Genesis controller (B is action button, C chooses tool or weapon)", "Hack of Quest for Quintana Roo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ead60451c28635b55ca8fea198444e16", "Sancho - Tang's Electronic Co.", "TEC004", "Nightmare (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eada0dd61ce13f8317de774dc1e68604", "", "", "2600 Digital Clock (Demo 1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eae0c06ee61c63b81cd016096fc901b0", "Joe Grand", "", "SCSIcide (v1.0) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eae6a5510055341d3abeb45667bb3e9b", "HES", "", "Wall Defender (HES) (PAL)", "AKA Wall Break (Planet Patrol if right difficulty = 'A')", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eaf744185d5e8def899950ba7c6e7bb5", "Atari", "CX26172", "Xenophobe (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eafe8b40313a65792e88ff9f2fe2655c", "Eric Ball", "ELB004", "Skeleton+ (NTSC)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eb3d680699f8762f71f38e28e321234d", "", "", "Fu Kung! (V0.01) (08-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eb4252faff7a4f2ba5284a98b8f78d1a", "", "", "John K Harvey's Equalizer (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "eb46e99ec15858f8cd8c91cef384ce09", "Goliath - Hot Shot", "83-113", "Ground Zero (1983) (Goliath) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eb503cc64c3560cd78b7051188b7ba56", "Star Game", "043", "Moto Laser (Star Game)", "AKA Mega Force", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eb634650c3912132092b7aee540bbce3", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "eb6d6e22a16f30687ade526d7a6f05c5", "Atari", "CX26150P", "Q-bert (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eb71743c6c7ccce5b108fad70a326ad9", "", "", "Euchre (25-11-2001) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eb7934360658a29c50aeaff20bfda23b", "Activision, John Van Ryzin", "EAZ-036-04", "H.E.R.O. (1984) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eb92193f06b645df0b2a15d077ce435f", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "eb9712e423b57f0b07ccd315bb9abf61", "Retroactive", "", "Qb (V2.04) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "eb9f8b84c193d9d93a58fca112aa39ed", "", "", "Register Twiddler Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ebcb084a91d41865b2c1915779001ca7", "JVP", "", "Bob Is Going Home (JVP)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ebcbc8a181a738e13df6216e5c329230", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ebd2488dcace40474c1a78fa53ebfadf", "Skill Screen Games, Herman Quast", "SSG001", "Extra Terrestrials (1984) (SSG)", "The only Canadian-designed and manufactured Atari 2600 game from the 1980's", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ebdc5716b85c4ff44fa357cb697d6cef", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ebf2dff78a08733251bf3838f02f7938", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ebf9038e927e6a0db3e0d170c59911e6", "", "", "Pac-2600 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ec3beb6d8b5689e867bafb5d5f507491", "U.S. Games Corporation - Vidtec - JWDA, Todd Marshall, Henry Will IV", "VC1003", "Word Zapper (1982) (U.S. Games)", "AKA Word Grabber", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ec407a206b718a0a9f69b03e920a0185", "Quelle", "876.482 1", "Landung in der Normandie (1983) (Quelle) (PAL)", "AKA Commando Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ec5c861b487a5075876ab01155e74c6c", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ece463abde92e8b89bcd867ec71751b8", "Puzzy - Bit Corporation", "PG205", "Dancing Plate (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ece908d77ab944f7bac84322b9973549", "", "", "Tom Boy (Unknown) (PAL60)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ecf51385384b468834611d44a8429c03", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ecfa04523dde82fe42cdc7315a8f61b6", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL) (4K)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed014beeeb77dbb2bbcf9b5f6850b2f4", "", "", "Green Bar Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed0451010d022b96a464febcba70b9c4", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ed0ab909cf7b30aff6fc28c3a4660b8e", "Panda", "105", "Stunt Man (1983) (Panda)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed1306436ce237afc5a7ed3f77134202", "HES", "771-341", "2 Pak Special - Dolphin, Pigs n' Wolf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed1492d4cafd7ebf064f0c933249f5b0", "CCE", "", "Video Cube (CCE)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed1a784875538c7871d035b7a98c2433", "Bit Corporation", "R320", "Save Our Ship (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed2218b3075d15eaa34e3356025ccca3", "Atari, Richard Maurer", "CX2635, CX2635P", "Maze Craze (1980) (Atari) (PAL)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed5ccfc93ad4561075436ee42a15438a", "Atari, Tom Reuterdahl", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ed8f319e82d355832195eb7715644795", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (8K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "eddef10fdc0029301064115ae0cd41d4", "CCE", "", "Freeway (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ede4ab11ca346bd023b2c21d941e0c50", "Activision, David Crane", "EAZ-030", "Decathlon (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ede7e8bf865b0afb4744f86d13624f9a", "", "", "Demo Image Series #2 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "edf69b123e06eaf8663cc78d8aeba06e", "SpkSoft 98", "", "River Raid (SpkSoft 98) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee28424af389a7f3672182009472500c", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee456542b93fa8d7e6a8c689b5a0413c", "", "", "Chronocolor Donkey Kong Clean (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee4c186123d31a279ed7a84d3578df23", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner", "CX2608", "Super Breakout (1982 - 1981) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, - { "ee659ae50e9df886ac4f8d7ad10d046a", "Exus Corporation", "", "Video Reflex (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee6665683ebdb539e89ba620981cb0f6", "Coleco", "2658", "Berenstain Bears (1983) (Coleco)", "Uses the KidVid Controller", "Unbelievably Rare", "", "", "", "A", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "" }, - { "ee67dc0b01746372d2b983d88f48e24f", "", "", "Scroller Demo (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee681f566aad6c07c61bbbfc66d74a27", "Activision", "", "Unknown Activision Game (10-29-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee6cbedf6c0aac90faa0a8dbc093ffbe", "CCE", "", "My Golf (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee8027d554d14c8d0b86f94737d2fdcc", "Canal 3 - Intellivision", "", "Yars' Revenge (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "ee84bdc5dae268e227e407c7b5e6b6b7", "", "", "Marilyn Monroe Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ee9caee4eb958284fb10c277b14537f1", "Carrere Video, Garry Kitchen - Teldec", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eea0da9b987d661264cce69a7c13c3bd", "Coleco", "2454", "Zaxxon (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eeb92f3f46df841487d1504f2896d61a", "Cody Pittman", "", "Corys Adventure (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eec61cc4250df70939d48fe02d7122ac", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eed9eaf1a0b6a2b9bc4c8032cb43e3fb", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "eee7695ae3eea7818321df0b790b31f3", "", "", "Sound Paddle V2 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "01", "", "", "", "" }, - { "ef263d40a23483ab339cac44d9515a56", "Thomas Jentzsch", "", "Fatal Run (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ef3a4f64b6494ba770862768caf04b86", "Activision, Bob Whitehead", "AG-034-04", "Private Eye (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ef60b06fddb675b0d783afbfa5fc5232", "", "", "Many Blue Bars and Text Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ef66af190840871409fe1702d2483554", "Andrew Davie, Paul Slocum, Christopher Tumber", "", "DiscoTech (12-02-2003) (Andrew Davie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ef71e9fb0d8d477226d8d42261fbf0a7", "Piero Cavina", "", "Multi-Sprite Demo V2.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ef76ea05655a0b62cb1018c92b9b4b7d", "Gakken", "010", "Strategy X (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "efa1098c7d091b940c2543abe372f036", "Scott Stilphen", "", "E.T. The Extra-Terrestrial (Scott Stilphen) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "efb47d70b2965ce689e2c5757616b286", "", "", "Time Test Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "efd387430a35a659ff569a9a0ec22209", "Atari - GCC", "CX26118", "Millipede (1984) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "efefc02bbc5258815457f7a5b8d8750a", "CBS Electronics, Richard K. Balaska Jr.", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "effa3a7ce078c6d83bf43174a7bfdb1f", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "efffafc17b7cb01b9ca35324aa767364", "", "", "Circus Atari (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f02ba8b5292bf3017d10553c9b7b2861", "Atari", "CX26172", "Xenophobe (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f032b2f2d8323404a6b4541f92dd1825", "", "", "Many Blue Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f047df70d3d08e331122cd2de61d6af8", "Dave Neuman", "", "Space Battle (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f04ee80011d95798006378643650aaa7", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0510abbfbe24ead552e92e3841f63f3", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0536303f49006806bac3aec15738336", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0541d2f7cda5ec7bab6d62b6128b823", "Atari, Paul Donaldson", "", "Bionic Breakthrough (1984) (Atari) (Prototype)", "Uses Mindlink Controller (left only)", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "" }, - { "f060826626aac9e0d8cda0282f4b7fc3", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0631c6675033428238408885d7e4fde", "Paul Slocum", "", "Test Cart (2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f066bea7ab0a37b83c83c924a87c5b67", "", "", "Air Raiders (1982) (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0a6e99f5875891246c3dbecbf2d2cea", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0b7db930ca0e548c41a97160b9f6275", "Atari, Larry Wagner, Bob Whitehead - Sears", "CX2645 - 49-75181", "Video Chess (1979) (Atari)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0cacae1d1b79ee92f0dc035f42e0560", "", "", "Boring Donkey Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0d393dbf4164a688b2346770c9bbd12", "", "", "Racquetball (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f0daaa966199ef2b49403e9a29d12c50", "", "", "Mr. Postman (Unknown)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0de4f49e95d529569e8788d5a7b4d30", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0e0addc07971561ab80d9abe1b8d333", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f0ef9a1e5d4027a157636d7f19952bb5", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a5]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f10e3f45fb01416c87e5835ab270b53a", "Suntek", "SS-024", "Ski Run (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1127ade54037236e75a133b1dfc389d", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f11cfab087fcbd930ab8b0becc5b2e5a", "Canal 3 - Intellivision", "", "River Raid (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f12afbffa080dd3b2801dd14d4837cf6", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f137211537438b1fce3d811baef25457", "", "", "Incoming (02-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1489e27a4539a0c6c8529262f9f7e18", "Champ Games", "CG-01-P", "Lady Bug (PAL60)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f14d5e96ec3380aef57a4b70132c6677", "Goliath - Hot Shot", "83-414", "Pac Kong (1983) (Goliath) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1554569321dc933c87981cf5c239c43", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f16c709df0a6c52f47ff52b9d95b7d8d", "Atari, Alan Miller - Sears", "CX2662 - 6-99811", "Hangman (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f16ef574d2042ed8fe877d6541f4dba4", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1929bb9b5db22d98dd992aa3fe72920", "", "", "Cube Conquest (Improved Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f19aba18f86e415812480ad2be221425", "Chris Larkin", "", "Solaris Trainer (2002) (Chris Larkin) (Hack)", "Hack of Solaris", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1a0a23e6464d954e3a9579c4ccd01c8", "20th Century Fox, Douglas 'Dallas North' Neubauer", "11006", "Alien (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f1ae6305fa33a948e36deb0ef12af852", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f1b2ea568b3e156e3f2849dac83591f6", "", "", "Sprite Demo (1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1b7edff81ceef5af7ae1fa76c8590fc", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1beca5a198cf08190487e5c27b8e540", "", "", "Fu Kung! (V0.16) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1e375d921858467166e53bcec05803f", "Jeffry Johnston", "", "Radial Pong - Version 3 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f1eeeccc4bba6999345a2575ae96508e", "Video Gems", "VG-03", "Steeplechase (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f1fe06ebe2900eac4cdd17799389a102", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f20675c8b98518367b9f5b8ee6f7c8ea", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f20bd756f3990e06c492f53cd0168e68", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f21813aa050437f0dbc8479864acec6d", "", "", "Sneak 'n Peek (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f23d19b73dac50cc6149316912b8ee53", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f240ba9f8092d2e8a4c7d82c554bf509", "Quelle", "463.860 7", "Strahlen der Teufelsvoegel (1983) (Quelle) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f280976d69d6e27a48506bd6bad11dcd", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "f283cc294ece520c2badf9da20cfc025", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "f28c07767b3e90a2689ade5b5e305874", "Canal 3 - Intellivision", "C 3014", "Keystone Kapers (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f2d40c70cf3e1d03bc112796315888d9", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f2d4d6187903cac2d5ea8ed90dad120d", "Digimax", "", "River Raid II (Digimax)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f2e4fb2d3600c0f76d05864e658cc57b", "", "", "Marble Craze (Kernel) (17-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f2f2cb35fdef063c966c1f5481050ea2", "", "", "Ram It (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f2f59629d7341c97644405daeac08845", "Jone Yuan Telephonic Enterprise Co", "", "Bobby Is Going Home (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f303630a2d7316787aecd67fff6b2e33", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f3213a8a702b0646d2eaf9ee0722b51c", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari) (4K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f33f1d0f7819c74148dacb48cbf1c597", "Retroactive", "", "Qb (2.00) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f344ac1279152157d63e64aa39479599", "Tigervision", "7-012", "Espial (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f34dd3b8156aaf113cb621b2e51d90b8", "Joe Grand", "", "SCSIcide Pre-release 5 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f34f08e5eb96e500e851a80be3277a56", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, - { "f367e58667a30e7482175809e3cec4d4", "ZiMAG - Emag - Vidco", "708-111 - GN-040", "Cosmic Corridor (1983) (ZiMAG)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f38358cd8f5ecfedffd5aca1aa939f18", "Universal Gamex Corporation, Alan Roberts", "1005", "X-Man (1983) (Universal) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f39e4bc99845edd8621b0f3c7b8c4fd9", "AtariAge", "", "Toyshop Trouble (AtariAge)", "F8 Emulator Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f3c431930e035a457fe370ed4d230659", "", "", "Crackpots (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f3cd0f886201d1376f3abab2df53b1b9", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f3dfae774f3bd005a026e29894db40d3", "Otto Versand", "649635", "See Saw (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "f3f5f72bfdd67f3d0e45d097e11b8091", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Submarine Commander (1982) (Sears)", "AKA Seawolf 3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f3f92aad3a335f0a1ead24a0214ff446", "", "", "Spectrum Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f40e437a9ebf0bdfe26204152f74f868", "Bit Corporation", "R320", "Jawbreaker (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f4204fc92d17ed4cb567c40361ad58f1", "Inky", "", "Beanie Baby Bash (Inky) (Hack)", "Hack of Beany Bopper", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f4469178cd8998cb437fa110a228eaca", "Digitel", "", "Frostbite (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f45644ff82b533a781a1ee50f2e95f3c", "", "", "Overhead Adventure Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f457674cef449cfd85f21db2b4f631a7", "U.S. Games Corporation - JWDA, Todd Marshall, Wes Trager, Henry Will IV", "VC1004", "Commando Raid (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f473f99e47d4026a7a571184922ebf04", "Philip R. Frey", "", "Donkey Claus (Philip R. Frey) (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f48022230bb774a7f22184b48a3385af", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, - { "f48735115ec302ba8bb2d2f3a442e814", "", "", "Dancing Plate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f49a34f1fdd7dc147cbf96ce2ce71b76", "", "", "Qb (Special Edition) (PAL) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f4a09f906cc37be31224433f576d77d3", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f4ab6bd5f80d8988141edde4c84b23b5", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f4b8a47a95b61895e671c3ec86ffd461", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (01-03-1984) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f4c2e50b01dff99bddbe037b3489511c", "", "", "Hypnotic (V0.04) (2001) (Inkling) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f4c6621f1a0b4d27081123c08d7d1497", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f4cf6881b65c424095dc25dc987f151f", "", "", "128 in 1 Game Select ROM (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f4dabd5bcc603e8464a478208037d423", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (08-21-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f526d0c519f5001adb1fc7948bfbb3ce", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1003", "Star Fox (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f52f40299fd238c6ffd9e6107050dc76", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f539e32bf6ce39c8ca47cb0cdd2c5cb8", "Control Video Corporation", "", "GameLine Master Module ROM (1983) (Control Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f542b5d0193a3959b54f3c4c803ba242", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f5445b52999e229e3789c39e7ee99947", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f5a2f6efa33a3e5541bc680e9dc31d5b", "Suntek", "SS-022", "Motocross (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f5a3e051730d45fea518f2e8b926565b", "Robby", "", "Keystone Kapers (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f5aa6bd10f662199c42e43863a30106c", "", "", "Music Kit (V1.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f5d103a9ae36d1d4ee7eef657b75d2b3", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (Preview) (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f613aad84d2163d6b197b220bfec1b7e", "", "", "X-Doom V.27 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f661f129644f338b13d9f4510d816c03", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f6676e3fe901eb8515fc7ae310302c3c", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f67181b3a01b9c9159840b15449b87b0", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (08-27-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f687ec4b69611a7f78bd69b8a567937a", "Activision, Alan Miller - Ariola", "EAZ-028 - 711 028-725", "Robot Tank (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f69a39b215852a0c2764d2a923c1e463", "", "", "Move a Blue Blob Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f69bb58b815a6bdca548fa4d5e0d5a75", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f69d4fcf76942fcd9bdf3fd8fde790fb", "CCE", "", "Aquaventure (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f6a282374441012b01714e19699fc62a", "ZiMAG - Emag - Vidco", "710-111 - GN-010", "I Want My Mommy (1983) (ZiMAG)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f6a9ea814d15b85bffe980c927df606b", "", "", "Missile Command (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f6b5ebb65cbb2981af4d546c470629d7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype) [a]", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f6c13e816e58c8c62f82b2c8b91a2d67", "", "", "Scrolling Playfield 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f6d512bef1bf253dc935d0e13c3d1462", "", "", "Slot Racers (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f6daebc0424fa0f8d9aaf26c86df50f4", "Brian Watson", "", "Color Tweaker (V1.0) (2001) (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f6efa00ae99aaf33e427b674bcfd834d", "", "", "2600 Digital Clock (Demo 3) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f6f1b27efc247a0e8d473ddb4269ff9e", "Rainbow Vision - Suntek", "SS-015", "Catch Time (1983) (Rainbow Vision) (PAL)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f70e3f3bb2d19ec2aaec8f78dc43744f", "Jone Yuan Telephonic Enterprise Co", "", "Pooyan (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f714a223954c28eccf459295517dcae6", "", "", "Big - Move This Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7154add27b95cd90464dbed8cfd7557", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f724d3dd2471ed4cf5f191dbb724b69f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" }, - { "f736864442164b29235e8872013180cd", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f73d2d0eff548e8fc66996f27acf2b4b", "CCE", "C-813", "Pitfall (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7424985bac41067502b4a05b64cb75a", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "Genesis controller (B is fire up, C is fire down)", "Hack of Plaque Attack", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" }, - { "f74ad642552385c3daa203a2a6fc2291", "Eckhard Stolberg", "", "Cubis (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f750b5d613796963acecab1690f554ae", "Manuel Polik", "", "Gunfight 2600 (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f75872946e82ad74d48eae5bc28f5f0e", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (04-15-1980) (Sears) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f777444fc21a5925e066b68b1d350575", "", "", "Marble Craze (Kernel Works) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f77f5fc3893da5d00198e4cd96544aad", "Canal 3 - Intellivision", "", "Stampede (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7856e324bc56f45b9c8e6ff062ec033", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) [no opening tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f78c125b5da483c41e51522947d6c4ce", "", "", "Sound Paddle V1 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "01", "", "", "", "" }, - { "f7a138eed69665b5cd1bfa796a550b01", "Tigervision - Teldec", "7-012 - 3.60016 VC", "Espial (1984) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7a651972d78f9ba485b14690452d4be", "Paul Slocum", "", "Homestar Runner Demo #2 (2004-03-29)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f7af41a87533524d9a478575b0d873d0", "Quelle", "495.663 7", "Spiderman (1983) (Quelle) (PAL)", "AKA Spider-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7d6592dcb773c81c278140ed4d01669", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7e07080ed8396b68f2e5788a5c245e2", "Video Game Cartridge - Ariola", "TP-617", "Farmyard Fun (Ariola)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7ec2f2bdbe8fbea048c0d5fa6503b0b", "Akor", "", "TV Boy (1992) (Akor) (PAL)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, - { "f7f50d9c9d28bcc9f7d3075668b7ac89", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f7fac15cf54b55c5597718b6742dbec2", "Spiceware", "SW-01", "Medieval Mayhem (NTSC)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" }, - { "f802fa61011dd9eb6f80b271bac479d0", "Suntek", "SS-023", "Mole Hunter (1983) (Suntek) (PAL)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f80cf77164079d774b9b0fae33dffca9", "", "", "Fu Kung! (V0.15) (Negative Version) (05-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8240e62d8c0a64a61e19388414e3104", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f825c538481f9a7a46d1e9bc06200aaf", "Atari, Richard Maurer - Sears", "CX2635 - 49-75157", "Maze Craze (1980) (Atari)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" }, - { "f844f4c6f3baaaf5322657442d6f29eb", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f847fb8dba6c6d66d13724dbe5d95c4d", "Absolute Entertainment, David Crane", "AG-042-02, AG-042-04", "Skate Boardin' (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8582bc6ca7046adb8e18164e8cecdbc", "", "", "Panda Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8648d0c6ad1266434f6c485ff69ec40", "CCE", "", "Oink! (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8811d45a9935cca90c62f924712f8e6", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8b2a6a4d73ebff10d805a9b59041986", "Activision, Larry Kaplan - Ariola", "EAX-006, PAX-006 - 771 006-720", "Bridge (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8bfd99163d2c4ec688357786e6fba28", "", "", "Eckhard Stolberg's Scrolling Text Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8c1c4a41303bd40b0d6c81bfaf8573b", "HES", "773-891", "2 Pak Special - Dungeon Master, Creature Strike (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8fbe2b07345086fc867bceeaf38dc48", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f8ff34b53d86f55bd52d7a520af6d1dc", "", "", "Big Dig (04-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f90b5da189f24d7e1a2117d8c8abc952", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f91fb8da3223b79f1c9a07b77ebfa0b2", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner - Sears", "CX2615 - 49-75140", "Demons to Diamonds (1982) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" }, - { "f93d7fee92717e161e6763a88a293ffa", "20th Century Fox Video Games - Lazer Micro Systems - Dunhill Electronics, B. Winston Hendrickson, Randall Hyde, Mark V. Rhoads, John Simonds", "11013", "Porky's (1983) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9420173efcb4b9f2b01c2a7b595cca7", "CCE", "", "Laser Blast (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f954381f9e0f2009d1ac40dedd777b1a", "Thomas Jentzsch", "", "Robot City (V0.18) (01-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9655ed51462ecfc690c7b97cec649f9", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f965cc981cbb0822f955641f8d84e774", "Answer Software Corporation - TY Associates, Kim Ellis", "ASC2001", "Confrontation (1983) (Answer) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "f9660ebed66fee8bdfdf07b4faa22941", "VGS", "", "Vanguard (VGS)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9677b2ec8728a703eb710274474613d", "Atari, Ian Shepard", "CX2604, CX2604P", "Space War (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f97dee1aa2629911f30f225ca31789d4", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, Jim Jacob", "5005002", "Out of Control (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f98d2276d4a25b286135566255aea9d0", "Digitel", "", "Name This Game (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f98d869f287d2ce4f8fb36e0686929d9", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f991e0670b5f67faa6b6211e9bd81b91", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f992a39b46aa48188fab12ad3809ae4a", "", "", "Sky Jinks (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9967369943209b4788d4e92cefc0795", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9cef637ea8e905a10e324e582dd39c2", "CCE", "", "Private Eye (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9d51a4e5f8b48f68770c89ffd495ed1", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9da42f91a1c5cfa344d2ff440c6f8d4", "ZUT", "", "Pac Invaders (ZUT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9de91d868d6ebfb0076af9063d7195e", "", "", "Maze Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "f9e99596345a84358bc5d1fbe877134b", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, - { "fa0570561aa80896f0ead05c46351389", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fa1b060fd8e0bca0c2a097dcffce93d3", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" }, - { "fa2be8125c3c60ab83e1c0fe56922fcb", "Camelot - DSD, Michael Doherty, Clyde Hager - Johnson & Johnson", "", "Tooth Protectors (1983) (Camelot)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fa3de71841c0841db6a741884a6b6b2f", "", "", "Warring Worms (17-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fa4404fabc094e3a31fcd7b559cdd029", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fa529ec88eca679f6d5fd0ccb2120e46", "", "", "20 Sprites at Once Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fa6fe97a10efb9e74c0b5a816e6e1958", "ZiMAG - Emag - Vidco", "707-111 - GN-030", "Tanks But No Tanks (1983) (ZiMAG)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fa7ce62e7fd77e02b3e2198d70742f80", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-18-1983) (Atari) (Prototype) (PAL)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fa7e11a3dbea4365975cd2f094e61d25", "Tim Snider", "", "Mystery Science Theater 2600 (1999) (Tim Snider) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fa98d48cd609c9babc819e0a1bd8d598", "AtariAge (Chris Walton)", "", "Juno First (2009) (PAL60)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "YES", "" }, - { "fab7b04b9f42df761eb6f2bc445eaa99", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (11-04-1982) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fabca526d57de46768b392f758f1a008", "", "", "Laseresal 2600 (16-12-2001) (Andrew Wallace) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fac28963307b6e85082ccd77c88325e7", "CCE", "", "Berzerk (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fadb89f9b23beb4d43a7895c532757e2", "Galaga Games", "", "River Raid (1984) (Galaga Games) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fae0b86934a7c5a362281dffebdb43a0", "Retroactive", "", "Qb (2.07) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "faebcb2ef1f3831b2fc1dbd39d36517c", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari) (PAL)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "faed2ef6b44894f8c83f2b50891c35c6", "CCE", "", "Super Baseball (CCE)", "AKA RealSports Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "faffd84f3a8eceee2fa5ea5b0a3e6678", "Suntek", "SS-025", "Spectracube Invasion (1983) (Suntek) (PAL)", "AKA Immies & Aggies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb09ee4ccd47ae74a3c314f0d8a40344", "", "", "Titans (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb0c32ef7af5b45486db663510094be8", "", "", "Demo Image Series #15 - Three Marios (NTSC) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb0e84cee4c108d24253bcb7e382cffd", "", "", "Interleaved ChronoColour Demo (SECAM) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb27afe896e7c928089307b32e5642ee", "M Network - INTV - APh Technological Consulting, Jeff Ronne, Brett Stutz", "MT5662", "TRON - Deadly Discs (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb4ca865abc02d66e39651bd9ade140a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb531febf8e155328ec0cd39ef77a122", "", "", "Worm War I (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fb5c8af97bd8ffe88323656f462645a7", "", "", "Interlace Demo (Glenn Saunders)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fb833ed50c865a9a505a125fc9d79a7e", "ITT Family Games", "", "Pumuckl I (1983) (ITT Family Games) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb884ffd89013331a6f01ae3f6abd214", "Activision, David Crane", "", "Venetian Blinds Demo (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb88baa01afd34e0e4b601e1d29bc806", "Manuel Polik", "", "Star Fire (2003) (XYPE)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb88c400d602fe759ae74ef1716ee84e", "20th Century Fox Video Games, Bill Aspromonte", "11031", "Crash Dive (1983) (20th Century Fox)", "AKA Voyage to the Bottom of the Sea", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb91da78455d9b1606913fbf8c859772", "", "", "Split Screen (Ballblazer) Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fb91dfc36cddaa54b09924ae8fd96199", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fb978f1c053e8061cc37a726639f43f7", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fbac6476e7b2b20d246202af81662c88", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fbb0151ea2108e33b2dbaae14a1831dd", "Thomas Jentzsch", "", "Robot Tank TV (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Robot Tank", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fbb4f3debf48dc961b559384467f2057", "Digitel", "", "River Raid III (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fbe554aa8f759226d251ba6b64a9cce4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fbfebee9c14694719e3eda4854dc42ee", "Jake Patterson", "", "Baubles 3 (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fc2104dd2dadf9a6176c1c1c8f87ced9", "Coleco - Woodside Design Associates, Harley H. Puthuff Jr.", "2663", "Time Pilot (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fc2233fc116faef0d3c31541717ca2db", "Atari, Tod Frye", "CX2646", "Pac-Man (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fc24a94d4371c69bc58f5245ada43c44", "Atari - Axlon, Steve DeFrisco", "CX26170", "Secret Quest (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fc6052438f339aea373bbc999433388a", "Atari, David Crane", "CX2653P", "Slot Machine (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fc668a2251dd79cbd903d4fa0e558f96", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fc92d74f073a44bc6e46a3b3fa8256a2", "", "", "Megademo (19xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fc9c1652fe3a2cade6188f4d3692481f", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fca4a5be1251927027f2c24774a02160", "Activision, John Van Ryzin", "AZ-036-04", "H.E.R.O. (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fcbbd0a407d3ff7bf857b8a399280ea1", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fcbdf405f0fc2027b0ea45bb5af94c1a", "Amiga - Video Soft, Michael K. Glass, Jerry Lawson", "", "3-D Ghost Attack (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fcea12625c071ddc49f4e409f4038c60", "Fabrizio Zavagli", "", "Balls! (16-09-2002) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, - { "fcf8e306f6615f74feba5cb25550038c", "", "", "Blue Dot Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd0e5148162e8ec6719445d559f018a9", "Activision, Steve Cartwright - Ariola", "EAX-022, EAX-022-04I - 711 022-720", "Seaquest (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd10915633aea4f9cd8b518a25d62b55", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd16949913aaab5beaefed73bf2ca67c", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-03-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd4f5536fd80f35c64d365df85873418", "Atari - Bobco, Robert C. Polaro", "CX26140", "Desert Falcon (1987) (Atari)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd6e507b5df68beeeddeaf696b6828fa", "", "", "Boxing (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd7464edaa8cc264b97ba0d13e7f0678", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd78f186bdff83fbad7f97cb583812fe", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a2]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd8b4ee0d57605b35e236e814f706ff1", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fd9b321cee5fbb32c39ba3ca5d9ec7cf", "Jeffry Johnston", "", "Radial Pong - Version 5 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fdd4995a50395db14f518f63c2d63438", "", "", "Oh No! (Version 3) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fde42e39710e75e9e4d4d75440f8e4e5", "Thomas Jentzsch", "", "Coke Zero (v1.0) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fdf0de38517e0cf7f0885f98ccc95836", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fdf6680b2b1e8054293a39700a765692", "", "", "Alpha Demo - The Beta Demo 2 (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fe0b7f27e3ad50bbf9ff468ee56d553d", "", "", "Lines Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fe0bc4bb92c1c4de7d5706aaa8d8c10d", "", "", "Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fe3b461d4c8b179fe68bc77760294c25", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "", "", "", "", "" }, - { "fe641247a4ab9bee970e19ab55f23b25", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (02-07-1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fe67087f9c22655ce519616fc6c6ef4d", "Atari - Zip Technology, Randy Bowker, Bruce Williams", "CX26142", "Crack'ed (11-28-1988) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fe6abc0f63e31e2646c9c600926b5b7f", "Atari", "CX26137", "4 in 1 (02-19-1987) (Atari) (Prototype)", "Home Run, Canyon Bomber, Sky Diver, Night Driver", "Prototype", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fe870018332a0221eb59fb18b0c6bccc", "", "", "Incoming (08-11-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fe9ae625d924b54c9f8a14ac9a0f6c6d", "BG Dodson", "", "High Bid! (BG Dodson) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "feba8686fd0376015258d1152923958a", "", "", "Super Circus (Unknown) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fec0c2e2ab0588ed20c750b58cf3baa3", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "EAZ-037-04, EAZ-037-04I", "Beamrider (1984) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "fece458a8023a809a5006867feca40e8", "", "", "SCSIcide (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "feec54aac911887940b47fe8c9f80b11", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, - { "feedcc20bc3ca34851cd5d9e38aa2ca6", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "10", "", "", "", "" }, - { "ff1523783e0e76a3b0d1f7f0d1cb3050", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ff3bd0c684f7144aeaa18758d8281a78", "Atari, Bob Whitehead", "CX2651", "Blackjack (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "ff5a9e340d96df6f5a5b6eb038e923bd", "", "", "Space Shuttle (1983) (Activision) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ff7627207e8aa03730c35c735a82c26c", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" }, - { "ff86fc8ffa717bb095e8471638c1c31c", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" }, - { "ff87d58125ae517eb7b09a0475a1ccdc", "", "", "SCSIcide (Score Hack 1) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ffb1cd548563158ce33f9d10268187e7", "Erik Eid", "", "Euchre (Beta) (NTSC) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ffc0ff4305dd46b4b459885bd1818e2e", "Barry Laws Jr.", "", "Star Wars - The Battle of Alderaan (Star Strike Hack)", "Hack of Star Strike (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ffdc0eb3543404eb4c353fbdddfa33b6", "CCE", "C-827", "Chopper Command (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ffe51989ba6da2c6ae5a12d277862e16", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari) (4K)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - { "ffebb0070689b9d322687edd9c0a2bae", "", "", "Spitfire Attack (1983) (Milton Bradley) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" } +static const BSPF::array2D DefProps = {{ + { "000509d1ed2b8d30a9d94be1b3b5febb", "Greg Zumwalt", "", "Jungle Jane (2003) (Greg Zumwalt) (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0060a89b4c956b9c703a59b181cb3018", "CommaVid, Irwin Gaines - Ariola", "CM-008 - 712 008-720", "Cakewalk (1983) (CommaVid) (PAL)", "AKA Alarm in der Backstube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "007d18dedc1f0565f09c42aa61a6f585", "CCE", "C-843", "Worm War I (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "008543ae43497af015e9428a5e3e874e", "Retroactive", "", "Qb (V2.09) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "00b7b4cbec81570642283e7fc1ef17af", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "00ce0bdd43aed84a983bef38fe7f5ee3", "20th Century Fox, Bill Aspromonte", "11012", "Bank Heist (1983) (20th Century Fox)", "AKA Bonnie and Clyde, Cops 'n' Robbers, Holdup, Rooring 20's", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "00ce76ad69cdc2fa36ada01ae092d5a6", "Bit Corporation", "PGP214", "Cosmic Avenger (4 Game in One) (1983) (BitCorp) (PAL)", "AKA StarMaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "00dc28b881989c39a6cf87a892bd3c6b", "CCE", "", "Krull (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "00e19ebf9d0817ccfb057e262be1e5af", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "00e55b27fe2e96354cd21b8b698d1e31", "", "", "Phoenix (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "00eaee22034aff602f899b684c107d77", "Rainbow Vision - Suntek - Sunteck Corp", "SS-001", "Time Race (1983) (Rainbow Vision) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "00f7985c20b8bdf3c557fac4d3f26775", "Aaron Curtis", "", "AStar (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "012020625a3227815e47b37fd025e480", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01293bd90a4579abb7aed2f7d440681f", "Century", "", "Snoopy (1983) (Century) (PAL)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01297d9b450455dd716db9658efb2fae", "TechnoVision - Video Technology", "TVS1002", "Save Our Ship (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "012b8e6ef3b5fd5aabc94075c527709d", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" }, + { "0164f26f6b38a34208cd4a2d0212afc3", "Coleco, Ed English", "2656", "Mr. Do! (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0173675d40a8d975763ee493377ca87d", "CBS Electronics, Ed English", "4L1751", "Roc 'n Rope (1984) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01abcc1d2d3cba87a3aa0eb97a9d7b9c", "Jone Yuan Telephonic Enterprise Co", "", "Topy (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01b09872dcd9556427761f0ed64aa42a", "Galaga Games", "", "River Raid (1984) (Galaga Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01cb3e8dfab7203a9c62ba3b94b4e59f", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01e5c81258860dd82f77339d58bc5f5c", "CCE", "", "Corrida da Matematica (CCE)", "AKA Math Gran Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01e60a109a6a67c70d3c0528381d0187", "ITT Family Games, Perry Rhodan-Serie", "554-33 383", "Fire Birds (1983) (ITT Family Games) (PAL)", "AKA Sky Alien", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "01f584bf67b0e464014a8c8b5ea470e3", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02066b17f29082412c6754c1a2d6302e", "", "", "Demo Image Series #3 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "024365007a87f213cbe8ef5f2e8e1333", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "025668e36a788e8af8ac4f1be7e72043", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (06-14-82) (Atari) (Prototype)", "Console ports are swapped", "Prototype", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "026180bf641ff17d8577c33facf0edea", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0277c449fae63f6f1c8f94dedfcf0058", "", "", "Laser Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "027a59a575b78860aed780b2ae7d001d", "CCE", "", "Pressure Cooker (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "028024fb8e5e5f18ea586652f9799c96", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "2468", "Carnival (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02811151906e477d47c135db5b1699c6", "", "", "FlickerSort Demo (Updated) (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02a5fc90a0d183f870e8eebac1f16591", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02ab2c47bc21e7feafa015f90d7df776", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02ced7ea2b7cb509748db6bfa227ebec", "Parker Brothers, Ed English, David Lamkins", "931502", "Frogger (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02cee0b140d2f1a1efcfb1d482a5c392", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02dcba28c614fec7ca25955327128abb", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD) [a]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "02e3f4ba156fb578bef7d7a0bf3400c1", "", "", "Booster (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "033e21521e0bf4e54e8816873943406d", "20th Century Fox Video Games - Sirius Software, Dan Thompson", "11020", "Earth Dies Screaming, The (1983) (20th Century Fox)", "The Day the Earth Stood Still", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "034c1434280b0f2c9f229777d790d1e1", "Telegames", "5665 A016", "Baseball (1988) (Telegames) (PAL)", "AKA Super Challenge Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0375f589f7da06d2d2be532e0d4d4b94", "", "", "Push (V0.04) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0383dc02cb82302da3d155fd108bfe3a", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug) (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "038e1e79c3d4410defde4bfe0b99cc32", "Atari, Tod Frye, Gary Shannon", "", "Aquaventure (08-12-1983) (Atari) (Prototype)", "AKA Sea Sentinel", "Unbelievably Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "039cf18b459d33b8a8fca31d06c4c244", "", "", "Demo Image Series #0 (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "03b1051c9374678363c899914412cfc5", "", "", "Incoming (30-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "03c3f7ba4585e349dd12bfa7b34b7729", "SEGA, Jeff Lorenz", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "03fbcee0bc80e31f27254aea3d920510", "Bit Corporation", "R320", "Trick Shot (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "03ff9e8a7af437f16447fe88cea3226c", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "04014d563b094e79ac8974366f616308", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "041b5e56bbc650db574bd8db3fae2696", "Thomas Jentzsch", "", "Thrust (V1.0) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "043f165f384fbea3ea89393597951512", "Spectravision - Spectravideo", "SA-202", "Planet Patrol (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0443cfa9872cdb49069186413275fa21", "M Network - INTV, Patricia Lewis Du Long, Ron Surratt", "MT4518", "BurgerTime (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "045035f995272eb2deb8820111745a07", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia)", "AKA Jungle Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "047ac3b9faea64522b7a23c4465a7aa8", "", "", "Defender (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "04856e3006a4f5f7b4638da71dad3d88", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari) (PAL)", "AKA Dog Fight", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "049626cbfb1a5f7a5dc885a0c4bb758e", "", "", "MegaMania (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "04b488d4eef622d022a0021375e7e339", "Home Vision - Gem International Corp. - VDI", "VCS83107", "Tennis (1983) (Home Vision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "04cf9e6898007024622ed6a0b295961f", "Bit Corporation", "R320", "Tennis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "04dfb4acac1d0909e4c360fd2ac04480", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "04e737c9d53cd84bfd5ee679954e4706", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "04fccc7735155a6c1373d453b110c640", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0519f395d5f7d76be813b834aa51c0be", "Atari, Ian Shepard", "CX2604", "Space War (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0546f4e6b946f38956799dd00caab3b1", "Thomas Jentzsch", "", "My Golf (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "056f5d886a4e7e6fdd83650554997d0d", "Parker Brothers, Ed Temple", "931504", "Amidar (1982) (Parker Bros) (PAL)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "056ff67dd9715fafa91fb8b0ddcc4a46", "", "", "Frisco (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05824fcbe615dbca836d061a140a50e0", "Jeffry Johnston", "", "Radial Pong - Version 9 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05aedf04803c43eb5e09dfd098d3fd01", "", "", "Keystone Kapers (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05aff8f626ef870432ae3b3d9d5aa301", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05b45ba09c05befa75ac70476829eda0", "Parker Brothers, Rex Bradford", "931507", "Star Wars - Jedi Arena (1983) (Parker Bros) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" }, + { "05c60458ec69e7fe8b1be973852d84f1", "", "", "Test (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05c765a63e61882abd1c2d627b652225", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05ccf96247af12eef59698f1a060a54f", "Otto Versand", "600273", "King Arthur (1983) (Otto Versand) (PAL)", "AKA Dragonfire (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "05d61b925d3d2474bab83f0a79bb5df1", "Eckhard Stolberg", "", "Cosmic Ark Stars (1997) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05eb4347f0ec8f4783983ca35ffd8d1b", "", "", "Qb (2.06) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "05ebd183ea854c0a1b56c218246fbbae", "Atari, Dan Hitchens", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "05f11fb2e45c4e47424d3cb25414d278", "", "", "Boring (NTSC) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "060c865c782debb047e6fd101c8923fc", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0614ed51acd027d531e7c85c4f435292", "", "", "Narnia (Glenn Saunders) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0619e1c3286bbfbace040b8c3ec5add2", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" }, + { "0651216c4a4a9c9ac5ada3013a317c72", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "06742cf522f23797157f215a1dc8a1a9", "", "", "Healthbars (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0685bd0bcb975ceef7041749a5454a48", "Piero Cavina", "", "11 Sprite Demo (Piero Cavina) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "069c17beb1e8e0557adb8539fdcf6cba", "", "", "Phantom II & Pirate (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "06b0194ce992584c365278e0d7323279", "Activision", "", "Unknown Activision Game #2 (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "06b6c5031b8353f3a424a5b86b8fe409", "Activision, Mike Lorenzen - Ariola", "EAX-023 - 711 023-720", "Oink! (1983) (Activision) (PAL)", "AKA Das Schweinchen und der Wolf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "06cfd57f0559f38b9293adae9128ff88", "Telegames", "4317 A009", "Adventures on GX-12 (1988) (Telegames) (PAL)", "AKA Adventures of Tron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "06d2f7674cea977607f74c464ce600a2", "CBS Electronics, Alex Nevelson", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "06db908011065e5ebb37f4e253c2a0b0", "", "", "Gopher (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "06e5dc181a8eda1c31cc7c581c68b6ef", "", "", "Tac-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "071f84d10b343c7c05ce3e32af631687", "Rainbow Vision - Suntek", "SS-019", "Curtiss (1983) (Rainbow Vision) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "072a6ea2181ca0df88ac0dedc67b239d", "", "", "Multiple Missiles Demo (19-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "073cb76b006af034fd150be3f5e0e7e6", "", "", "Mobile 48 Sprite Kernel (Bug Fixed) (10-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "073d7aff37b7601431e4f742c36c0dc1", "", "", "Bermuda (Unknown) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "074ec425ec20579e64a7ded592155d48", "Atari - Sculptured Software, Steve Aguirre", "CX26162", "Fatal Run (Ultimate Driving) (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "075069ad80cde15eca69e3c98bd66714", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE)", "AKA Bobby Vai Para Casa", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0751f342ee4cf28f2c9a6e8467c901be", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "07973be3ecfd55235bf59aa56bdef28c", "Suntek", "SS-036", "Criminal Pursuit (1983) (Suntek) (PAL)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "079fe9103515d15bc108577e234a484d", "", "", "Multi-Color Demo 0 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "07a3af1e18b63765b6807876366f5e8a", "Joe Grand", "", "SCSIcide Pre-release 2 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "07c76f2d88552d20ad2c0ed7aef406c6", "Cody Pittman", "", "Blob (Cody Pittman) (Hack)", "Hack of Halloween", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "07f42847a79e4f5ae55cc03304b18c25", "Zellers", "", "Sea Hawk (Zellers)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "07f84db31e97ef8d08dc9fa8a5250755", "Supergame", "", "Enduro (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "07f91e33e76f53bb9d2731fd5d8a35a5", "Atari", "CX2632", "Space Invaders (1978) (Atari) [t1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0805366f1b165a64b6d4df20d2c39d25", "Atari, Dan Hitchens", "CX2650", "Berzerk (1982) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08188785e2b8300983529946dbeff4d2", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" }, + { "081e2c114c9c20b61acf25fc95c71bf4", "Parker Brothers, Ed English, David Lamkins", "PB5300", "Frogger (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "082fdc8bd47fef01482ce5883c4ffdb8", "Charles Morgan", "", "Tanks DX (Charles Morgan) (Hack)", "Hack of Tanks But No Tanks", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0832fb2ee654bf9382bc57d2b16d2ffc", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "083e7cae41a874b2f9b61736c37d2ffe", "Imagic, Rob Fulop, Bob Smith", "720106-2A, IA3600P, EIX-009-04I", "Riddle of the Sphinx (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "085322bae40d904f53bdcc56df0593fc", "Parker Brothers, Dave Engman, Dawn Stockbridge", "PB5340", "Tutankham (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0856f202b18cd46e44fd1dc3b42e9bfb", "", "", "Frame Counter 1 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0866e22f6f56f92ea1a14c8d8d01d29c", "Androbot - Western Technologies, Michael Case, Lenny Carlson", "", "AndroMan on the Moon (1984) (Western Tech) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0891252ee4e307689febccf3cfd8a8ab", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0894aa7be77521f9df562be8d9555fe6", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08989fa4ff537f5dbd611aff4019521a", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08bd4c1dcc843f6a0b563d9fd80b3b11", "Quelle", "343.273 9", "Phantompanzer II (1983) (Quelle) (PAL)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08bf437d012db07b05ff57a0c745c49e", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Meteoroids (1982) (Arcadia) (Prototype)", "Suicide Mission Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "08d1b6d75206edb999252caf542a2c7f", "Larry Petit", "", "Super Home Run (2003) (Larry Petit) (Hack)", "Hack of Home Run", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08d60a58a691c7f690162850302dc0e1", "", "", "Poker Squares (V0.27) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08e5960bb52d9a3e2c9954677b5e4472", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (10-20-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08ea2fdaa22e5802c839ee7dfb0483dc", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "08f4dc6f118f7c98e2406c180c08e78e", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" }, + { "08f853e8e01e711919e734d85349220d", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0906c6e0e4bda9c10cfa4c5fc64d2f4b", "Retroactive", "", "Qb (V0.12) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "090f0a7ef8a3f885048d213faa59b2f8", "Carrere Video - Western Technologies, John Hall - Teldec - Prism", "USC1012", "M.A.D. (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "09274c3fc1c43bf1e362fda436651fd8", "Thomas Jentzsch", "", "Acid Drop (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "09388bf390cd9a86dc0849697b96c7dc", "Absolute Entertainment, Alex DeMeo", "AG-045-04, AK-045-04", "Pete Rose Baseball (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0945081a6bd00345ff3d58eb7a07330a", "", "", "Stampede (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0956285e24a18efa10c68a33846ca84d", "Dismac", "", "Viagem Espacial (Dismac)", "AKA Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0963aa9f7f6cf5a36ff700001583624e", "Franklin Cruz", "", "Space Invaders 2 (Hack) [o1]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "096649575e451508006b17e0353259a5", "Justin J. Scott", "", "Yar Vs. Yar (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "097074f24cde141fe6a0f26a10333265", "", "", "Marble Craze (V0.90) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "097936b07e0e0117b9026ae6835eb168", "Imagic, Dennis Koble", "720100-2B, IA3000P", "Trick Shot (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "09abfe9a312ce7c9f661582fdf12eab6", "Atari, Douglas Neubauer", "CX26154", "Super Football (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "09e1ecf9bd2a3030d5670dba7a65e78d", "Atari, James Andreasen", "CX2654", "Haunted House (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "09e9ba0762fd0c3cf3c2e072cff79cac", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "09f89bbfa2ab00f1964d200e12d7ced0", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0a1b98937911d621b004b1617446d124", "", "", "Hangman Pac-Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0a981c03204ac2b278ba392674682560", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0aa208060d7c140f20571e3341f5a3f8", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Tom Sloper", "VC1009", "Towering Inferno (1982) (U.S. Games)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0abf64ca504a116adca80f77f85e00fb", "", "", "Cube Conquest (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0ac0d491763153fac75f5337ce32a9d6", "", "", "SPAM Image Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0acaf71e60b89f6b6eab63db6ab84510", "", "", "This Planet Sucks (Greg Troutman) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0aceb7c3bd13fe048b77a1928ed4267d", "Imagic, Bob Smith", "720102-2B, IA3201P, EIX-011-04I", "Star Voyager (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0ad9a358e361256b94f3fb4f2fa5a3b1", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari) [a]", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, + { "0adb21206de92e8aec5ef295805ebb90", "", "", "Solaris (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Solaris", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0ae3497e731ca0bf6a77b23441d9d9f9", "", "", "Analog Clock (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0af51ceb4aecc7a8fc89781ac44a1973", "Barry Laws Jr.", "", "Face Invaders Deluxe (Barry Laws Jr.) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0afe6ae18966795b89314c3797dd2b1e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b01909ba84512fdaf224d3c3fd0cf8d", "", "", "Revenge of the Apes (Hack)", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b1056f1091cfdc5eb0e2301f47ac6c3", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b17ed42984000da8b727ca46143f87a", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-17-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b24658714f8dff110a693a2052cc207", "CCE", "C-815", "Seaquest (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b33252b680b65001e91a411e56e72e9", "CCE", "C-832", "Atlantis (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b4e793c9425175498f5a65a3e960086", "CCE", "", "Kung Fu Master (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b55399cf640a2a00ba72dd155a0c140", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-1A, 03205", "Fathom (1983) (Imagic)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0b577e63b0c64f9779f315dca8967587", "Videospielkassette - Ariola", "PGP236", "Raketen-Angriff (Ariola) (PAL)", "AKA Missile Control", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0b8d3002d8f744a753ba434a4d39249a", "Sears Tele-Games, Robert Zdybel", "CX2619 - 49-75159", "Stellar Track (1981) (Sears)", "AKA Stella Trak", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0bf19e40d5cd8aa5afb33b16569313e6", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0bf1e354304f46c0caf8fc0f6f5e9525", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0bfabf1e98bdb180643f35f2165995d0", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c0392db94a20e4d006d885abbe60d8e", "", "", "Dodge Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c336f83b0e6e3bc86c77f368448e77b", "Bit Corporation", "R320", "Circus Atari (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c35806ff0019a270a7acae68de89d28", "Froggo", "FG1003", "Task Force (1987) (Froggo)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c48e820301251fbb6bcdc89bd3555d9", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c54811cf3b1f1573c9164d5f19eca65", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL)", "AKA Dragster Rennen, Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c72cc3a6658c1abd4b735ef55fa72e4", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c7926d660f903a2d6910c254660c32c", "Atari, Larry Kaplan", "CX2602, CX2602P", "Air-Sea Battle (1977) (Atari) (PAL)", "AKA Anti-Aircraft", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0c7bd935d9a7f2522155e48315f44fa0", "Carrere Video - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Tom Sloper - Teldec - Prism", "USC1009", "Infernal Tower (1983) (Carrere Video) (PAL)", "AKA Towering Inferno", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0c80751f6f7a3b370cc9e9f39ad533a7", "Atari, Carla Meninsky", "CX2610", "Warlords (1981) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "0cb7af80fd0ddef84844481d85e5d29b", "", "", "Mr. Pac-Man (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0cc8224ff1edfe458e8629e9e5fe3f5b", "Thomas Jentzsch", "", "Trick 12 (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0cdd9cc692e8b04ba8eb31fc31d72e5e", "Thomas Jentzsch", "", "Wing War (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0cebb0bb45a856b23f56d21ce7d1bc34", "20th Century Fox Video Games, Bill Aspromonte", "11131", "Crash Dive (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0cec9e46a25d338bf595a29aa2606516", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0cfdd2f3b243cac21f38a0f09f54bead", "", "", "Overhead Adventure Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d07d2c1be1a5eaaea235a533bcda781", "", "", "Scrolling Playfield 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d08558f34a47e4eaa39d01c8efb81f0", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d09cff0d28033c02c3290edfc3a5cea", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d1b3abf681a2fc9a6aa31a9b0e8b445", "Atari", "CX26163P", "Laser Blast (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d27c7f5db349b592f70f68daf5e8f3b", "", "", "Space Instigators (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d35618b6d76ddd46d2626e9e3e40db5", "", "", "X-Doom V.26 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d5af65ad3f19558e6f8e29bf2a9d0f8", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0d6b974fe58a1bdd453600401c407856", "Atari", "", "128-in-1 Junior Console (Chip 3 or 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d786a41695e5fc8cffd05a6dbb3f659", "", "", "Scrolling Playfield With Score (10-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d7e630a14856f4d52c9666040961d4d", "", "", "Wavy Line Test (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0d90a0ee73d55539b7def24c88caa651", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0db4f4150fecf77e4ce72ca4d04c052f", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0dd4c69b5f9a7ae96a7a08329496779a", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0de53160a8b54c3aa5aed8d68c970b62", "Quelle", "806.174 9", "Fuchs & Schweinchen Schlau (1983) (Quelle) (PAL)", "AKA Oink!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0dfbdadf8f1bc718e7e1bb3ccd5fef3d", "", "", "Mr. Pac-Man (New start tune) (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0e0808227ef41f6825c06f25082c2e56", "", "", "Candi (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0e08cd2c5bcf11c6a7e5a009a7715b6a", "", "", "Boing! (PD) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0e224ea74310da4e7e2103400eb1b4bf", "Atari, Peter C. Niday, Gary Shannon, Howard Scott Warshaw", "", "Mind Maze (10-10-1984) (Atari) (Prototype)", "Uses the MindLink controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "", "" }, + { "0e23d0ed4c33b2011ab4cc93a7619683", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0e4b2b6e014a93ef8be896823da0d4ec", "", "", "Skiing (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0e713d4e272ea7322c5b27d645f56dd0", "Home Vision - Gem International Corp. - VDI", "VCS83105", "Panda Chase (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0e7e73421606873b544e858c59dc283e", "Digivision", "", "Super Soccer (Digivision)", "AKA RealSports Soccer", "", "", "", "F8", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0e86470791b26292abe1c64545c47985", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "01 70", "", "", "", "" }, + { "0ec93f519bb769e0d9f80e61f6cc8023", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0ecdb07bf9b36ef18f3780ef48e6c709", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0eebfb60d437796d536039701ec43845", "Fabrizio Zavagli", "", "Cakewalk (Fabrizio Zavagli)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0eecb5f58f55de9db4eedb3a0f6b74a8", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0ef64cdbecccb7049752a3de0b7ade14", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0efc91e45f61023cda9d086a7d3c402f", "B.J. Best (aka bjbest60)", "", "Space Cactus Canyon (2017)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0effef4a341f8eebab65621c60c48787", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f14c03050b35d6b1d8850b07578722d", "Jeffry Johnston", "", "Radial Pong - Version 10 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f24ca5668b4ab5dfaf217933c505926", "", "", "Fantastic Voyage (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f2e09c71cc216f79d22a804152ba24b", "Bob Colbert", "", "Scroller Demo (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0f341d1f4e144e3163d9a5fc5a662b79", "", "", "RUN Platform Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "0f39fc03d579d0d93a6b729a3746843e", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f604cd4c9d2795cf5746e8af7948064", "Champ Games", "CG-02-N", "Conquest Of Mars (2010) (NTSC)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f643c34e40e3f1daafd9c524d3ffe64", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f6676b05621f80c670966e2995b227a", "", "", "Globe Trotter Demo 1 (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f738dc44437557624eb277ed7ad91c9", "", "", "Grand Prix (Unknown) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f8043715d66a4bbed394ef801d99862", "Quelle", "684.733 9", "Robin Hood (1983) (Quelle) (PAL)", "AKA Save Our Ship", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0f95264089c99fc2a839a19872552004", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0fba7d8c3520bdb681f75494e498ec36", "", "", "Gunfight 2600 - Final Run (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0fbf618be43d4396856d4244126fe7dc", "Quelle", "805.784 6", "Labyrinth (1983) (Quelle) (PAL)", "AKA Maze Craze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0fc161704c46e16f7483f92b06c1558d", "CCE", "C-853", "Spider Fighter (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0fcff6fe3b0769ad5d0cf82814d2a6d9", "Suntek", "SS-027", "Zoo Fun (1983) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0fd72a13b3b6103fc825a692c71963b4", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "0fee596b974c9d3e70b367a3671599b6", "Bit Corporation", "R320", "Name This Game (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "101ab60f4000a5d13792ef0abad5f74b", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "102672bbd7e25cd79f4384dd7214c32b", "Atari, Alan Miller - Sears", "CX2642 - 6-99814", "Hunt & Score - Memory Match (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "103e9d616328969f5d7b4e0a381b25d5", "", "", "Playfield Illustration and Logo Demo (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "103f1756d9dc0dd2b16b53ad0f0f1859", "Home Vision, Gem International Corp.", "", "Go Go Home Monster (1983) (Home Vision) (PAL)", "AKA Go Go Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "104468e44898b8e9fa4a1500fde8d4cb", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "106326c262dfd3e8eaeabd961d2a0519", "", "", "PAL-NTSC Detector (15-11-2002) (CT)[a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "106855474c69d08c8ffa308d47337269", "Atari - Sculptured Software, Adam Clayton", "CX26151", "Dark Chambers (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "107cc025334211e6d29da0b6be46aec7", "Atari, Bob Smith - Sears", "CX2648 - 49-75161", "Video Pinball (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1086ff69f82b68d6776634f336fb4857", "Activision, David Crane", "AG-009", "Bloody Human Freeway (1981) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10958cd0a1a81d599005f1797ab0e51d", "", "", "Centipede 2k (2000) (PD) (Hack)", "Hack of Centipede", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10a3cd14e5dcfdde6ff216a14ce7b7dd", "Atari", "CX262, CX2627P", "Human Cannonball (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10af8728f975aa35a99d0965de8f714c", "Dinatronic", "", "Seaquest (Dinatronic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10c47acca2ecd212b900ad3cf6942dbb", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a4]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10c8cfd8c37522f11d47540ff024e5f9", "Canal 3 - Intellivision", "C 3016", "Demon Attack (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10eae73a07b3da044b72473d8d366267", "Funvision - Fund. Int'l Co.", "", "Karate (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10f0ecaf962aef1fc28abed870b01b65", "Atari, Paul Donaldson", "", "Bionic Breakthrough (06-22-1984) (Atari) (Prototype)", "Uses the Mindlink Controller", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "10f62443f1ae087dc588a77f9e8f43e9", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "110ac8ecaf1b69f41bc94c59dfcb8b2d", "", "", "Demon Attack (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "111029770226b319524134193886a10e", "Hozer Video Games", "", "Gunfight 2600 - One Limit Reached! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "11330eaa5dd2629052fac37cfe1a0b7d", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "113cd09c9771ac278544b7e90efe7df2", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "114c599454d32f74c728a6e1f71012ba", "Activision, Bob Whitehead - Ariola", "EAX-015, EAX-015-04I - 711 015-725", "Chopper Command (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "11bcf5c752088b5aaf86d6c7a6a11e8d", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "11e7e0d9437ec98fa085284cf16d0eb4", "", "", "Bowling (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "11f9532557e4c9569f4b242164006161", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005) (PAL)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1201c18cf00d2c236f42e4d7d8c86aa1", "", "", "Nick Bensema Demo (Nick Bensema)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "12080205f669b8e7783b976f8cf3d8bb", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "12123b534bdee79ed7563b9ad74f1cbd", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1228c01cd3c4b9c477540c5adb306d2a", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1266b3fd632c981f3ef9bdbf9f86ce9a", "Activision, Bob Whitehead", "EAZ-034-04, EAZ-034-04I", "Private Eye (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1267e3c6ca951ff1df6f222c8f813d97", "", "", "Dragonfire (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "126f7f64b7b00e25dcf5e3710b4cf8b8", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1278f74ca1dfaa9122df3eca3c5bcaad", "Rainbow Vision - Suntek", "SS-013", "Bi! Bi! (Rainbow Vision) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1287535256bf5dff404839ac9e25c3e7", "PacManPlus", "Rev 2", "Alien Pac-Man (PacManPlus) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "12937db3d4a80da5c4452b752891252d", "Digitel", "", "Megamania (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "12bca8305d5ab8ea51fe1cfd95d7ab0e", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "12d7e0d6b187889f8d150bf7034d1db2", "", "", "Poker Squares (V0.0e) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "130c5742cd6cbe4877704d733d5b08ca", "Home Vision - Gem International Corp. - VDI", "VCS83109", "World End (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1323c45d660f5a5b6d5ea45c6c4cbe4a", "Canal 3 - Intellivision", "", "Enduro (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "133456269a03e3fdae6cddd65754c50d", "Tigervision - Software Electronics Corporation - Teldec", "7-006 - 3.60008 VG", "Springer (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "133a4234512e8c4e9e8c5651469d4a09", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "133b56de011d562cbab665968bde352b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1343de49c2a50d99176255f99f0d0234", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" }, + { "13448eb5ba575e8d7b8d5b280ea6788f", "Digivision", "", "Crackpots (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1345e972dbe08ea3e70850902e20e1a5", "Greg Troutman", "", "Dark Mage (rough beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1351c67b42770c1bd758c3e42f553fea", "Digivision", "", "Keystone Kapers (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "135708b9a7dd20576c1b66ab2a41860d", "", "", "Hangman Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13584411da0a8d431991035423fdc0dc", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1367e41858be525710eb04d0dab53505", "Kyle Pittman", "", "Zelda (2003) (Kyle Pittman) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "136f75c4dd02c29283752b7e5799f978", "Atari, Dan Hitchens - Sears", "CX2650 - 49-75168", "Berzerk (1982) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13895ef15610af0d0f89d588f376b3fe", "Tigervision, Rorke Weigandt", "7-005", "Marauder (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13a37cf8170a3a34ce311b89bde82032", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13a991bc9c2ff03753aeb322d3e3e2e5", "Funvision - Fund. International Co.", "", "Galactic (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13aa1f9ac4249947e4af61319d9a08f2", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13abc32f803165c458bb086fa57195fb", "Christian Samuel", "", "E.T. The Extra-Testical (Christian Samuel) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13ccc692f111d52fec75d83df16192e2", "Canal 3 - Intellivision", "", "Fishing Derby (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13d8326bf5648db4dafce45d25e62ddd", "", "", "Atari Logo Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "13dfb095e519a555a5b60b7d9d7169f9", "", "", "Red Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "140909d204abd6841c64cdad4d7765b4", "", "", "Moving Blue Ladder Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "14163eb2a3ddd35576bd8527eae3b45e", "", "", "Multi-Color Demo 6 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1423f560062c4f3c669d55891a2bcbe7", "CCE", "C-859", "MASH (1983) (CCE) [a]", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1428029e762797069ad795ce7c6a1a93", "", "", "Thunderground (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "143918368f4f4dfff90999188c0197c9", "", "", "Unknown Title (bin00016 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1442d1b35a6478fba22ae7dd1fcb5634", "Thomas Jentzsch", "", "Thrust (V0.2) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "148471144ccebd7f6aa9aa9215896533", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "149b543c917c180a1b02d33c12415206", "CCE", "C-857", "Superman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "14a56b493a8d9d10e94a3e100362e3a2", "Hozer Video Games", "", "Gunfight 2600 - Early Play-kernel (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "14b1e30982962c72f426e2e763eb4274", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "14c2548712099c220964d7f044c59fd9", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software)", "AKA Bubbles, Soap Suds, The Emphysema Game", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "14d365bbfaac3d20c6119591f57acca4", "", "", "Video Life (Unknown) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "14dbb3686dd31964332dc2ef0c55cad0", "", "", "Demo Image Series #15 - Three Marios (PAL) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "151c33a71b99e6bcffb34b43c6f0ec23", "Parker Brothers, Laura Nikolich", "", "Care Bears (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "151fa3218d8d7600114eb5bcd79c85cb", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-02-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "152c253478b009c275e18cd731b48561", "", "", "Quest (11-10-2002) (Chris Larkin)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "153f40e335e5cb90f5ce02e54934ab62", "Absolute Entertainment, Alex DeMeo", "EAZ-041-04I", "Title Match Pro Wrestling (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1542662f665d2ffaa77b4b897dd2e2af", "", "", "Starfield (V1.0) (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "155fa7f479dcba3b10b1494e236d6010", "Skyworks", "", "Tomcat (2002) (Skyworks) (PAL)", "AKA The F-14 Flight Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "157356f80c709ab675961d8b8b207e20", "", "", "Multi-Sprite Game V2.5 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "157bddb7192754a45372be196797f284", "Atari, Warren Robinett - Sears", "CX2613, 49-75154", "Adventure (1980) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "159e5cd6ccb968015f49aed5adbc91eb", "Justin J. Scott", "", "Yar's Defeat (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "15a0d59304dece2c7d0580f3ea3527f0", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (04-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "15b498199ed0ed28057bf0dbdce9b8d8", "Thomas Jentzsch", "", "Jammed (V0.2) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "15b9f5e2439bfaa08874b5184261c777", "Bit Corporation", "R320", "Space Invaders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "15bcd74f2f1f2a63e1aa93e90d2c0555", "", "", "Incoming (22-08-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "15bf2ef7583bfcbbba630847a1dc5539", "Erik Eid", "", "Euchre (Jul 15) (2002) (Eric Eid) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "15c11ab6e4502b2010b18366133fc322", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (09-19-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "15dd21c2608e0d7d9f54c0d3f08cca1f", "Data Age, J. Ray Dettling", "112-008", "Frankenstein's Monster (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "15fe28d0c8893be9223e8cb2d032e557", "", "", "Towering Inferno (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1619bc27632f9148d8480cd813aa74c3", "Thomas Jentzsch", "", "Steeple Chase (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "161ded4a85d3c78e44fffd40426f537f", "Thomas Jentzsch", "", "JtzBall (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "16229d61d7b0c89b01853660a8da22bb", "", "", "spin4a50", "", "", "", "", "4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "163e7e757e2dc44469123ff0e5daec5e", "", "", "Many Blue Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "169d4c7bd3a4d09e184a3b993823d048", "", "", "Superman (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "16cb43492987d2f32b423817cdaaf7c4", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "16cc6d1b4ddce51c767a1ba8e5ff196c", "", "", "Big - Move This Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "16d69f71bf5846639be5ff16483f0498", "Bit Corporation", "R320", "Golf (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "16e04823887c547dc24bc70dff693df4", "Atari", "CX26163P", "Tennis (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "16ee443c990215f61f7dd1e55a0d2256", "Spectravideo, David Lubar", "SA-218, SA-218C", "Bumper Bash (1983) (Spectravideo) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "16f494f20af5dc803bc35939ef924020", "Mark De Smet", "", "Video Simon (Mark De Smet)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "170e7589a48739cfb9cc782cbb0fe25a", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network) [fixed]", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "YES", "", "", "AUTO 55", "", "", "", "" }, + { "171cd6b55267573e6a9c2921fb720794", "Kurt Howe", "", "Adventure 34 (Kurt Howe) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "171ebf135b13ba907f462c10d88a2c25", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1733772165d7b886a94e2b4ed0f74ccd", "", "", "Boring Journey Escape (Hack)", "Hack of Journey - Escape", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1738b2e3f25ab3eef3cecb95e1d0d957", "", "", "Hangman Monkey Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "17512d0c38f448712f49f36f9d185c4e", "Retroactive", "", "Qb (Release Candidate #1) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "17515a4d0b7ea5029ffff7dfa8456671", "Piero Cavina", "", "Multi-Sprite Demo V1.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "176d3fba7d687f2b23158098e103c34a", "Zach Matley", "", "Combat AI (16-02-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "177504abd4260c4265e1338955e9fa47", "HCC Software", "", "Pitfall! (Steroids Hack)", "Hack of Pitfall! (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1782929e1c214b70fb6884f77c207a55", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "17ba72433dd41383065d4aa6dedb3d91", "", "", "SCSIcide (09-06-2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "17badbb3f54d1fc01ee68726882f26a6", "M Network - INTV - APh Technological Consulting, Hal Finney, Bruce Pedersen", "MT5659", "Space Attack (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "17bbe288c3855c235950fea91c9504e9", "Dismac", "", "Pega Ladrao (Dismac)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "17c0a63f9a680e7a61beba81692d9297", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper", "VC2004", "Picnic (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "17d000a2882f9fdaa8b4a391ad367f00", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "17ee158d15e4a34f57a837bc1ce2b0ce", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "17ee23e5da931be82f733917adcb6386", "Salu, Dennis M. Kiss", "460758", "Acid Drop (1992) (Salu) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1802cc46b879b229272501998c5de04f", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "183020a80848e06a1238a1ab74079d52", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ) (PAL)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1862fca4f98e66f363308b859b5863af", "Atari", "", "128-in-1 Junior Console (Chip 1 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18a970bea7ac4d29707c8d5cd559d03a", "", "", "Bridge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18b28b386abdadb3a700ac8fb68e639a", "Manuel Polik", "", "Gunfight 2600 (MP) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18b476a34ce5e6db2c032029873ac39b", "Bit Corporation", "R320", "Atlantis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18be8981b8201638f3ed8ae92bb4c215", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18bebbbd41c234f82b1717b1905e6027", "", "", "Space Instigators (Public Release) (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18d26111cef66dff0c8af8cf0e117843", "", "", "Tunnel Demo (Cycling Colours 2) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18dc28bc22402f21e1c9b81344b3b8c5", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "18ed63e3ce5bc3dd2d8bd188b807f1a2", "", "", "Stell-A-Sketch (Bob Colbert) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "18f299edb5ba709a64c80c8c9cec24f2", "Home Vision - Gem International Corp. - VDI", "VCS83111", "Asteroid Fire (1983) (Home Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "19098c46da0640f2b5763167dea6c716", "Andrew Wallace", "", "Laseresal 2002 (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "191449e40b0c56411c70772706f79224", "", "", "Multi-Color Demo 2 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "19162393786098d50587827588198a86", "Jone Yuan Telephonic Enterprise Co", "", "Flag Capture (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "191ac4eec767358ee3ec3756c120423a", "", "", "Checkers (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "192aa2e8c795c9e10a7913e5d41feb81", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125", "Los Angeles 1984 Games (1984) (Atari) (Prototype) (PAL)", "AKA Track and Field (Uses Track & Field Controller)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "193f060553ba0a2a2676f91d9ec0c555", "Atari, Carol Shaw", "CX2636, CX2636P", "Video Checkers (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1942bdb7abc75e412068330a9082b0ff", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" }, + { "1986f864e32e3e8d198b5becf3022257", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "199985cae1c0123ab1aef921daace8be", "", "", "Euchre (Release Candidate 2) (PAL) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "199eb0b8dce1408f3f7d46411b715ca9", "Parker Brothers, David Lamkins, Laura Nikolich", "PB5900", "Spider-Man (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "19a9d3f9fa1b1358fb53009444247aaf", "", "", "Blackjack (Unknown) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "19abaf2144b6a7b281c4112cff154904", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "19b3b807507653516985ba95da92499d", "Joe Gaucher", "", "VCS Draw Demo (Joe Gaucher)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "19d6956ff17a959c48fcd8f4706a848d", "PlayAround - J.H.M.", "202", "Burning Desire (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "19d9b5f8428947eae6f8e97c7f33bf44", "", "", "Fortress (Dual Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "19e739c2764a5ab9ed08f9095aa2af0b", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "19e761e53e5ec8e9f2fceea62715ca06", "Panda", "104", "Scuba Diver (1983) (Panda)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1a23540d91f87584a04f184304a00648", "", "", "Race Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1a613ce60fc834d4970e1e674b9196b3", "Home Vision - Gem International Corp. - VDI", "VCS83135", "Tanks War (1983) (Home Vision) (PAL)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1a624e236526c4c8f31175e9c89b2a22", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL) [a]", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1a8204a2bcd793f539168773d9ad6230", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) [no initials]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1aa7344b563c597eecfbfcf8e7093c27", "David Marli", "", "Slot Invaders (David Marli) (Hack)", "Hack of Slot Machine", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1b0f3d7af668eeea38ddd6182d8f48fb", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1b1daaa9aa5cded3d633bfcbeb06479c", "", "", "Ship Demo (V 1502) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1b22a3d79ddd79335b69c94dd9b3e44e", "Tron", "", "Moon Patrol (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1b4b06c2a14ed3ee73b7d0fd61b6aaf5", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1b5a8da0622bffcee4c5b42aed4e0ef0", "Akor", "", "TV Boy II (1992) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "1b8c3c0bfb815b2a1010bba95998b66e", "Telegames", "", "Frogs and Flies (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1b8d35d93697450ea26ebf7ff17bd4d1", "Quelle - Otto Versand", "176.764 9 - 781644", "Marineflieger (1983) (Quelle) (PAL)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1bb91bae919ddbd655fa25c54ea6f532", "Suntek", "SS-026", "Treasure Island (1983) (Suntek) (PAL)", "AKA Treasure Discovery", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1bc2427ac9b032a52fe527c7b26ce22c", "Intellivision Productions - M Network - APh Technological Consulting, Bruce Pedersen, Larry Zwick", "MT5860", "Sea Battle (1983) (M Network)", "High Seas", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1bef389e3dd2d4ca4f2f60d42c932509", "Dimax - Sinmax", "SM8001", "Space Robot (1983) (Dimax - Sinmax) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1bf503c724001b09be79c515ecfcbd03", "", "", "Bumper Bash (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1bfae770e089fa81412d04eb299f4c3f", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (NTSC) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1c3f3133a3e5b023c77ecba94fd65995", "CCE", "C-830", "Planet Patrol (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1c5796d277d9e4df3f6648f7012884c4", "Rainbow Vision - Suntek", "SS-012", "Hey! Stop! (1983) (Rainbow Vision) (PAL)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1c666ba5aac19b81671357e76062989b", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL60) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1c6eb740d3c485766cade566abab8208", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1c85c0fc480bbd69dc301591b6ecb422", "CCE", "", "Super Box (CCE)", "AKA RealSports Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1c8c42d1aee5010b30e7f1992d69216e", "PlayAround - J.H.M.", "205", "Gigolo (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1cad3b56cc0e6e858554e46d08952861", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1cafa9f3f9a2fce4af6e4b85a2bbd254", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1cca2197d95c5a41f2add49a13738055", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "1cf59fc7b11cdbcefe931e41641772f6", "SEGA", "005-01", "Buck Rogers - Planet of Zoom (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1d1d2603ec139867c1d1f5ddf83093f1", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari) (4K)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1d284d6a3f850bafb25635a12b316f3d", "CCE", "", "H.E.R.O. (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1d2a28eb8c95da0d6d6b18294211839f", "", "", "Fishing Derby (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1d4e0a034ad1275bc4d75165ae236105", "20th Century Fox Video Games, Mark Klein", "11034", "Pick Up (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1d5eac85e67b8cff1377c8dba1136929", "", "", "Chronocolor Donkey Kong Sideways (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1d6ed6fe9dfbde32708e8353548cbb80", "Jone Yuan Telephonic Enterprise Co", "", "Super Challenge Baseball (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1d72cc6ee466a4af1b27587b900ed430", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1da2da7974d2ca73a823523f82f517b3", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1db3bc4601f22cf43be7ce015d74f59a", "", "", "Ship Demo (V 10) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1e060a8025512ad2127e3da11e212ccc", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (3 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1e0ef01e330e5b91387f75f700ccaf8f", "Quelle - Otto Versand", "686.561 2 - 781627", "Mein Weg (1983) (Quelle) (PAL)", "AKA Challenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1e1290ea102e12d7ac52820961457e2b", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-15-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1e272d09c0e55f5ef14fcb76a735f6d7", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1e31b3a48865ba98d4d1aa5205115983", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1e587ca91518a47753a28217cd4fd586", "Telesys, Jim Rupp, Jack Woodman", "1001", "Coco Nuts (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1e750000af77cc76232f4d040f4ab060", "Jone Yuan Telephonic Enterprise Co", "", "Raft Rider (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1e85f8bccb4b866d4daa9fcf89306474", "Atari, Lou Harp", "CX26122", "Sinistar (02-13-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1e89f722494608d6ea15a00d99f81337", "", "", "River Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" }, + { "1ea1abcd2d3d3d628f59a99a9d41b13b", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1ea980574416bfd504f62575ba524005", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1ec57bbd27bdbd08b60c391c4895c1cf", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (09-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1ec5bef77b91e59313cba205f15b06d7", "", "", "Overhead Adventure Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1ede4f365ce1386d58f121b15a775e24", "Parker Brothers, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1ee2cfc7d0333b96bd11f7f3ec8ce8bc", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1ee9c1ba95cef2cf987d63f176c54ac3", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1ef04e7e508296a8d9eb61cc7dae2e5d", "SOLID Corp. (D. Scott Williamson)", "CX2655-069", "Star Castle 2600 (SolidCorp) [069]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1f21666b8f78b65051b7a609f1d48608", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1f2ae0c70a04c980c838c2cdc412cf45", "Atari - GCC", "CX2698", "Rubik's Cube (1984) (Atari)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1f349dd41c3f93c4214e5e308dccb056", "", "", "Virtual Pet Demo 2 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1f40eefc7447336ae6cd8ffa5eb325be", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1f562b89d081e36d58e6fc943512ec05", "", "", "Hangman Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1f5a2927a0b2faf87540b01d9d7d7fd1", "Pet Boat", "", "Tennis (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1f60e48ad98b659a05ce0c1a8e999ad9", "", "", "Mondo Pong V2 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "1f773a94d919b2a3c647172bbb97f6b4", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (07-11-1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1fa58679d4a39052bd9db059e8cda4ad", "Imagic, Dan Oliver", "720118-1A, 03208", "Laser Gates (1983) (Imagic)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1fa7a42c2c7d6b7a0c6a05d38c7508f4", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-04-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "1fa86282403fa35d103ab88a9d603c31", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare) (PAL60)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "1fab68fd67fe5a86b2c0a9227a59bb95", "20th Century Fox Video Games - Videa, Lee Actor", "", "Lasercade (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "200309c8fba0f248c13751ed4fc69bab", "Jeffry Johnston", "", "Radial Pong - Version 1 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2008c76deba5953201ef75a09b2ff7dc", "", "", "Fortress (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "200a9d2a7cb4441ce4f002df6aa47e38", "", "", "Doomzerk (PD) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2016726db38ad6a68b4c48ba6fe51557", "Piero Cavina, Erik Mooney", "", "INV 2 (Piero Cavina, Erik Mooney)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "203049f4d8290bb4521cc4402415e737", "Tigervision, Robert H. O'Neil - Teldec", "7-007 - 3.60005 VG", "Polaris (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "203abb713c00b0884206dcc656caa48f", "Imagic, Bob Smith", "720114-1A, 03207, IZ-001-04", "Moonsweeper (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "203b1efc6101d4b9d83bb6cc1c71f67f", "Quelle", "685.996 1", "Teller-Jonglieren! (1983) (Quelle) (PAL)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "205070b6a0d454961dd9196a8e81d877", "", "", "Hangman Monkey Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2058cf3fefad4d2bc03ed817cedddcd4", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2091af29b4e7b86914d79d9aaa4cbd20", "CBS Electronics - Woodside Design Associates, Harley H. Puthuff Jr.", "4L1802", "Donkey Kong Junior (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "20ae62fb69c6cc6e8098cca8cd080487", "Zirok", "", "Tennis (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "20d4457ba22517253fcb62967af11b37", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "20dca534b997bf607d658e77fbb3c0ee", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1002", "Fire Fly (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "20edcc3aa6c189259fa7e2f044a99c49", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "211774f4c5739042618be8ff67351177", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "211f76dff0b7dad3f6fcac9d938ee61a", "JSK", "", "Custer's Viagra (JSK) (Hack) [a]", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "211fbbdbbca1102dc5b43dc8157c09b3", "Apollo", "AP-2009", "Final Approach (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2124cf92978c46684b6c39ccc2e33713", "", "", "Sea Monster (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "21299c8c3ac1d54f8289d88702a738fd", "K-Tel Vision", "", "Spider Maze (1982) (K-Tel Vision)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "212d0b200ed8b45d8795ad899734d7d7", "Atari, Richard Maurer, Christopher H. Omarzu - Coca Cola", "", "Pepsi Invaders (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "213e5e82ecb42af237cfed8612c128ac", "Sancho - Tang's Electronic Co.", "TEC006", "Forest (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2162266b906c939b35c84ff9a0f50ad1", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "2179dfd7edee76efafe698c1bc763735", "", "", "Yellow Submarine (Cody Pittman) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "217b1452881264ac75126bf77b8d0db8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "218b76f5a4142dc2ea9051a768583d70", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "218c0fe53dfaaa37f3c823f66eafd3fc", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "21a96301bb0df27fde2e7eefa49e0397", "Data Age", "DA1003", "Sssnake (1982) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "21b09c40295c2d7074a83ae040f22edf", "", "", "Marble Craze (V0.90) (Easy Version) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "21d2c435bcccde7792d82844b3cf60f4", "Atari - GCC, Doug Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "21d7334e406c2407e69dbddd7cec3583", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2228c67d25e507603d4873d3934f0757", "", "", "Fu Kung! (V0.10) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "22319be7a640af5314ec3c482cceb676", "", "", "Joustpong (05-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2240655247d6de1c585564004a853ab7", "", "", "Fu Kung! (V0.17) (07-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "225522777dc7155627808bde0c1d0ef0", "", "", "This Planet Sucks Demo 1 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "22675cacd9b71dea21800cbf8597f000", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "227532d82505c3c185a878273c285d5f", "", "", "Hangman Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "22abbdcb094d014388d529352abe9b4b", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype) [a]", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "22b22c4ce240303012e8a9596ae8d189", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "22f6b40fc82110d68e50a1208ae0bb97", "", "", "Purple Bar Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2319922df4d0c820b3e5f15faa870cc3", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2327456f86d7e0deda94758c518d05b3", "Digitel", "", "Mr. Postman (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2351d26d0bfdee3095bec9c05cbcf7b0", "", "", "Warring Worms (19-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2353725ec98e0f0073462109e886efd7", "Champ Games", "CG-03-P", "Scramble (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "235436ab0832370e73677c9c6f0c8b06", "", "", "Beast Invaders (Double Shot) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2365e1534d67f94d8670394ab99150ce", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "", "", "ATARIMOUSE", "", "", "", "", "", "", "", "", "YES", "" }, + { "23d445ea19a18fb78d5035878d9fb649", "CBS Electronics - JWDA, Sylvia Day, Todd Marshall, Henry Will IV", "4L1818, 4L1819, 4L1820, 4L1821", "Mouse Trap (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "23e4ca038aba11982e1694559f3be10f", "", "", "Big Dig (V3) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "23fad5a125bcd4463701c8ad8a0043a9", "CCE", "C-840", "Stone Age (1983) (CCE)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "A", "A", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "240bfbac5163af4df5ae713985386f92", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2432f33fd278dea5fe6ae94073627fcc", "CBS Electronics, Tom DiDomenico", "4L2477, 4L2482, 4L2485, 4L4171", "Blueprint (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2434102f30eeb47792cf0825e368229b", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24385ba7f5109fbe76aadc0a375de573", "CCE", "", "Xevious (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2447e17a4e18e6b609de498fe4ab52ba", "CCE", "", "Super Futebol (CCE)", "AKA RealSports Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "244c6de27faff527886fc7699a41c3be", "", "", "Matt Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2450dfa1df70d12b60683185775efed8", "Jeffry Johnston", "", "Radial Pong - Version 7 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24544ee5d76f579992d9522e9b238955", "Carrere Video - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper - Teldec - Prism", "USC2004", "Picnic (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "245f07c8603077a0caf5f83ee6cf8b43", "Home Vision - Thomas Jentzsch", "", "Parachute (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24759be31e8fe55d2829fd86bdf3181f", "Hozer Video Games", "", "Gunfight 2600 - Worst Nightmare... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "247fa1a29ad90e64069ee13d96fea6d6", "CCE", "C-867", "Radar (1983) (CCE)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "248668b364514de590382a7eda2c9834", "CBS Electronics, Richard K. Balaska Jr., Bob Curtiss, Alex Leavens, Alex Nevelson", "", "Kick-Man (01-08-82) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2496d404bfc561a40a80bea6a69695c3", "CCE", "C-1007", "Jungle Hunt (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24ad538291eb5f5cac4b9998f3b851c3", "", "", "Gunfight 2600 - This time it's your decission! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24aff972d58990f9b88a6d787c796f1e", "CBS Electronics", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf (1982) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24b5f4bbdb853eca38ea0cae2dfe73a1", "", "", "Home Run (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24b9adac1b4f85b0bac9bf9b9e180906", "Angelino", "", "Space 2002 (Angelino) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24d018c4a6de7e5bd19a36f2b879b335", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "24d9a55d8f0633e886a1b33ee1e0e797", "Thomas Jentzsch", "", "Dragon Defender (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "24df052902aa9de21c2b2525eb84a255", "Imagic, Dennis Koble", "720000-100, 720100-1B, IA3000, IA3000C", "Trick Shot (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "24fbf8250a71611e40ef18552e61b009", "", "", "Movable Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2516f4f4b811ede4ecf6fbeb5d54a299", "Quelle", "701.134 9", "Schiessbude (1983) (Quelle) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2517827950fee41a3b9de60275c8aa6a", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25265d0e7f88b3026003809f25ee025e", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25472dfdeef6a42581a231d631d6b04d", "", "", "Gunfight 2600 - Design thoughts (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25710bde8fa181b0c5cf0846b983bec1", "", "", "Demo Image Series #15 - Three Marios (NTSC) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "257bc3b72a6b5db3fd0d47619125b387", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) [a]", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "" }, + { "25a21c47afe925a3ca0806876a2b4f3f", "Quelle", "685.640 5", "Der kleine Baer (1983) (Quelle) (PAL)", "AKA Frostbite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25b52bf8dd215bcbd59c9abdb55c44f8", "Atari - GCC, Betty Ryan Tylko, Doug Macrae", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25b6dc012cdba63704ea9535c6987beb", "Avalon Hill, Jean Baer, Bill Hood", "5004002", "Shuttle Orbiter (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25bb080457351be724aac8a02021aa92", "CBS Electronics", "4L1784, 4L1786, 4L1787, 4L2277", "Zaxxon (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25d4be3309b89583c6b39d9f93bf654f", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25e73efb9a6edf119114718bd2f646ba", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25f2e760cd7f56b88aac88d63757d41b", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25f879ff678130fea615ac418e7943f1", "Activision, Garry Kitchen", "EAX-025", "Keystone Kapers (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "25f9cf703575c5d63048c222f5463758", "", "", "Multi-Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "260c787e8925bf3649c8aeae5b97dcc0", "Thomas Jentzsch", "", "Hell Driver (Thomas Jentzsch)", "NTSC Conversion, joystick ports swapped", "Homebrew", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "262ccb882ff617d9b4b51f24aee02cbe", "Atari, Douglas Neubauer", "CX26154, CX26154P", "Super Football (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "265a85f66544eaf95fda06c3d9e48abf", "", "", "Tunnel Demo (Cycling Colours) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "265c74a956500bd31efd24adc6d5ccf6", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2683d29a282dd059535ac3bb250f540d", "", "", "Space Treat (12-01-2003) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "268f46038e29301568fa9e443e16e960", "Atarius Maximum", "", "Pitfall Unlimited (Atarius Maximus) (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "26bc2bdf447a17376aea7ef187ff6e44", "", "", "Amanda Invaders (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "26f4f8b098609164effef7809e0121e1", "", "", "Oystron (V2.7) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "270229c6d5578446e6a588492e4e5910", "", "", "Space Invaders 2 (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2712e91f6f1dc55e90e2b14b27c042ac", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "271bfd5dc2673d382019f1fb6cab9332", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "273ce50db5a0d6da7ea827a54f44dee9", "", "", "Island Flyer Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "274d17ccd825ef9c728d68394b4569d2", "Playaround - J.H.M.", "202", "Bachelorette Party (1982) (Playaround)", "AKA Bachelor Party, Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, + { "277c7281ac945b8331e2e6fcad560c11", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "277cca62014fceebb46c549bac25a2e3", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "277fa4b9a6bb7a8dcea2c5f38a4c25f0", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari) (Prototype)", "AKA Football II", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "278155fc9956e9b6ef2359eb238f7c7f", "", "", "Donkey Kong Junior (Unknown) (Hack)", "Hack of Donkey Kong Junior", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2783006ee6519f15cbc96adae031c9a9", "Telegames", "", "Night Stalker (1989) (Telegames) (PAL) [a]", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "278531cc31915747018d22145823d2c9", "", "", "Defender MegaDrive (PAL) (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "278f14887d601b5e5b620f1870bc09f6", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "27a5d2d0c74c8e4b2c05b94c9f098eea", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL60) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "27baecd618e7e53dc11f2a9c559f529d", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "27c4c2af4b46394bb98638af8e0f6e9d", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "27c6a2ca16ad7d814626ceea62fa8fb4", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "27f9e2e1b92af9dc17c6155605c38e49", "CCE", "", "Nightmare (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2808dc745ff4321dc5c8122abef6711f", "Retroactive", "", "Qb (2.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "28148a52b1955ce12c7a74d3a3e620a4", "CCE", "", "Freeway (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "281ff9bd0470643853de5cbd6d9e17f5", "Eckhard Stolberg", "", "Cubis (EM) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2823364702595feea24a3fbee138a243", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp) (PAL)", "AKA Bobby geht Heim", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2825f4d068feba6973e61c84649489fe", "", "", "Boom Bang (Unknown) (PAL)", "AKA Crackpots", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "282a77841cb3d33af5b56151acba770e", "Otto Versand", "311388", "Black Hole (1983) (Otto Versand) (PAL)", "AKA Cosmic Ark (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "283cb03ee031c842beabdad1aa4e7dbc", "Bit Corporation", "R320", "Demon Attack (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "283dee88f295834c4c077d788f151125", "Retroactive", "", "Qb (2.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "284ca61b2407bdba3938048b0a559015", "Atari, Tod Frye", "CX2695", "Xevious (05-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2854e5dfb84173fafc5bf485c3e69d5a", "Canal 3 - Intellivision", "C 3004", "Moon Patrol (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2880c6b59bd54b153174676e465167c7", "Tron", "", "Donkey Kong Jr. (Tron)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "28a2bea8f84936cb2e063f857414cda0", "Thiago Paiva", "", "Mega Mania Raid (1999) (Thiago Paiva) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "28a4cd87fb9de4ee91693a38611cb53c", "", "", "Skeleton (V1.1) (NTSC) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "28d5df3ed036ed63d33a31d0d8b85c47", "Bit Corporation", "PG204", "Open, Sesame! (1983) (BitCorp) (PAL)", "AKA Sesam, Offne Dich", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2903896d88a341511586d69fcfc20f7d", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "291bcdb05f2b37cdf9452d2bf08e0321", "Atari", "CX26163P", "32 in 1 Game Cartridge (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "291cc37604bc899e8e065c30153fc4b9", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "291dd47588b9158beebe4accc3a093a6", "Atari", "", "32 in 1 Console ROM (02-10-1989) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "292a0bb975b2587f9ac784c960e1b453", "", "", "Qb (05-02-2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "292f2446a0325b7b423e88a2ebfeb5a0", "", "", "Cube Conquest (Non Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "29396db58406084e416032c372734a3e", "", "", "Gunfight 2600 - Fixed Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2942680c47beb9bf713a910706ffabfe", "", "", "Blue Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "294762000e853b4319f9991c1ced5dfc", "", "", "T.F. Space Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "295f3679bdf91ca5e37da3f787b29997", "", "", "Exorcise (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "29630a20d356fb58685b150bfa8f00c3", "M Network, Kevin Miller", "MT5687", "International Soccer (1982) (Mattel) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "297236cb9156be35679f83c4e38ee169", "Exus Corporation", "", "Video Reflex (1983) (Exus) [no roman numbers]", "AKA Foot Craz (no roman numbers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "297c405afd01f3ac48cdb67b00d273fe", "Atari - GCC, Ava-Robin Cohen", "CX26123, CX26123P", "Jr. Pac-Man (1986) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2982e655dffc89d218a0a3072cfc6811", "", "", "Mini Golf 812631 (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "298387b0637173d2002770a649b4fbca", "", "", "S.I.PLIX 2 (Hack) [a]", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "29843f43b81f3736bf35c00b1bb88fb2", "Gray Games & AtariAge", "", "E.T. Book Cart (NTSC)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" }, + { "29949f893ef6cb9e8ecb368b9e99eee4", "Erik Eid", "", "Euchre (Alpha) (NTSC) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "29dfa26b7988af9984d617708e4fc6e2", "", "", "Boulderdash Demo (05-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2a0ba55e56e7a596146fa729acf0e109", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2a10053fd08664c7cfbbb104386ed77f", "", "", "Alpha Demo - The Beta Demo (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2a1b454a5c3832b0240111e7fd73de8a", "Tigervision, Bill Hogue", "7-011", "Miner 2049er Volume II (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2a2f46b3f4000495239cbdad70f17c59", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2a33e21447bf9e13dcfed85077ff6b40", "", "", "Backwards Cannonball v2 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2a360bc85bf22de438651cf92ffda1de", "Bit Corporation", "PGP213", "Spy Vs. Spy (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2a9f9001540c55a302befd8e9d54b47b", "Atari, Dan Hitchens", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2aa5e56d36c2e58b6f2856109f2099a9", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2aba6a1b01a5859e96d6a66d2286772f", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2abc3d46b3f2140160759e2e10bc86d9", "", "", "Gunfight 2600 - Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2ac3a08cfbf1942ba169c3e9e6c47e09", "Activision, Dan Kitchen", "EAK-046-04B", "Fighter Pilot (1988) (Activision) (PAL)", "AKA Tomcat - The F-14 Fighter Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2ae700c9dba843a68dfdca40d7d86bd6", "TechnoVision - Thomas Jentzsch", "", "Pharaoh's Curse (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2aeedcc6eb1602efb77161b0cef832ab", "SOLID Corp. (D. Scott Williamson)", "CX2655-025", "Star Castle 2600 (SolidCorp) [025]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2b1589c7e1f394ae6a1c046944f06688", "Carrere Video - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC2003", "Eggomania (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, + { "2b27eb194e13f3b38d23c879cc1e3abf", "Quelle", "402.272 9", "Super-Ferrari (1983) (Quelle) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2b42da79a682ed6e2d735facbf70107e", "", "", "DKjr Improved (Hack)", "Hack of Donkey Kong Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2b430c00dc79e495762ac59b2f9b4fcd", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2b71a59a53be5883399917bf582b7772", "Greg Troutman", "", "Dark Mage (final beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2ba02f509a4991aa176ba8d9e540df3d", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2bb0a1f1dee5226de648eb5f1c97f067", "Robby", "", "Enduro (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2bb9f4686f7e08c5fcc69ec1a1c66fe7", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2bc26619e31710a9884c110d8430c1da", "Atari, Bob Whitehead", "CX2652, CX2652P", "Casino (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2bc6c53b19e0097a242f22375a6a60ff", "", "", "Droid Demo 2 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2bee7f226d506c217163bad4ab1768c0", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2bf34b6ad7d2317a2d0808b3fb93571b", "", "", "Easy Playfield Graphics (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c0dc885d5ede94aa664bf3081add34e", "", "", "Earth Dies Screaming, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c29182edf0965a7f56fe0897d2f84ba", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (08-18-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c2aea31b01c6126c1a43e10cacbfd58", "Paul Slocum", "", "Synthcart (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2c3b2843295c9d6b16996971180a3fe9", "HES - Activision", "", "Sports Action Pak - Enduro, Ice Hockey, Fishing Derby, Dragster (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c3b9c171e214e9e46bbaa12bdf8977e", "Bit Corporation", "R320", "Othello (32 in 1) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c45c3eb819a797237820a1816c532eb", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c8835aed7f52a0da9ade5226ee5aa75", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c8c11295d8613f875b7bcf5253ab9bb", "Fabrizio Zavagli", "", "Kool Aid Man (PAL Conversion) (16-11-2002) (Fabrizio Zavagli) (PAL60)", "PAL60 Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2c9fadd510509cc7f28f1ccba931855f", "", "", "Hangman Invader Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2ca6445204ffb7686ddee3e33ba64d5b", "Alex Herbert", "", "AtariVox Test ROM", "Uses the AtariVox controller", "", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "", "" }, + { "2cb42cf62b2f25f59f909b5447821b14", "Atari, Christopher H. Omarzu - Children's Computer Workshop", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "2cc3049b7feb8e92f1870f1972629757", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype) [stack pointer fix]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2cccc079c15e9af94246f867ffc7e9bf", "PlayAround - J.H.M.", "203", "Jungle Fever (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2cefa695df2ed020899a7df7bb1e3a95", "Manuel Polik, Fabrizio Zavagli", "", "A-Team (2002) (Manuel Polik) (Hack)", "Hack of A-Team", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2cf20f82abcae2decff88db99331e071", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2cfb188c1091cc7ec2a7e60064d2a758", "", "", "Space Invaders Hack Demo (2003) (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d15b092e8350912ec4b2e5e750fa1c6", "Wizard Video Games, Bob Davis, Robert H. O'Neil", "", "Texas Chainsaw Massacre, The (1982) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d16a8b59a225ea551667be45f554652", "Quelle", "802.744 3", "Der Geheimkurier (1983) (Quelle) (PAL)", "AKA Mr. Postman", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d1cf85fbc732856bf76470cd4060f4a", "", "", "Daredevil (V1) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d2c5f0761e609e3c5228766f446f7f8", "Atari - Axlon, Steve DeFrisco", "CX26170, CX26170P", "Secret Quest (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d33a44e82f88d05f6c50577218c0cae", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d38a96f92952b301eefdf25a5e6976b", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y_Inverted) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d405da70af82b20a6b3ecc3d1d2c4ec", "Genus", "", "Pitfall (Genus)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d6388a8389f1d59108fd169c3356d79", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d63b452f897818c52b3fceeb080a4d0", "HES - Absolute Entertainment", "", "Pete Rose Baseball (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d6741cda3000230f6bbdd5e31941c01", "CBS Electronics - VSS", "80110", "Targ (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d69a5f23784f1c2230143292a073b53", "", "", "Qb (Fixed background animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2d6da0eb85eabc93270e5bb8a466ca51", "", "", "Sprite Demo 7 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d76c5d1aad506442b9e9fb67765e051", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo) [no opening scene]", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d9e5d8d083b6367eda880e80dfdfaeb", "QDI, Mike Montana, Rich Montana - Selchow & Righter", "87", "Glib (1983) (QDI)", "AKA Video Word Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2d9e65959808a6098c16c82a59c9d9dc", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2dbc92688f9ba92a7e086d62be9df79d", "", "", "How to Draw a Playfield (1997) (Jim Crawford) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2dbdca3058035d2b40c734dcf06a86d9", "Thomas Jentzsch", "", "Asteroids DC+ (Thomas Jentzsch) (Hack)", "Uses the Joystick (left) or Driving (right) Controller", "Hack", "", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "58", "", "", "YES", "" }, + { "2dcf9ce486393cd36ca0928cd53b96cb", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2de41a11c6767e54a5ee9ebaffec72af", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL60)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" }, + { "2dfec1615c49501fefc02165c81955e6", "", "", "Song (05-11-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2e0aed5bb619edcefa3fafb4fbe7c551", "", "", "Qb (2.06) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2e2acef8513edcca991e7e5149412e11", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2e3728f3086dc3e71047ffd6b2d9f015", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2e5b184da8a27c4d362b5a81f0b4a68f", "Atari", "", "Rabbit Transit (08-29-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2e663eaa0d6b723b645e643750b942fd", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2e7e9c6dcfcceaffc6fa73f0d08a402a", "CCE", "C-818", "Star Voyager (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2e82a1628ef6c735c0ab8fa92927e9b0", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2e842c2ee22e9dad9df16eed091315c4", "HES", "701-157", "2 Pak Special - Moto-cross, Boom Bang (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2eaf8fa9e9fdf1fcfc896926a4bdbf85", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 39 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2ec6b045cfd7bc52d9cdfd1b1447d1e5", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2eda6a49a49fcb2b674ea9e160b6a617", "Kyle Pittman", "", "Rambo in Afghanistan (Kyle Pittman) (Hack)", "Hack of Riddle of the Sphinx", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2ef36341d1bf42e02c7ea2f71e024982", "", "", "Space Invaders (Explosion Hack)", "Hack of Space Invaders (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2f0546c4d238551c7d64d884b618100c", "SEGA, Jeff Lorenz", "", "Ixion (1984) (SEGA) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2f0a8bb4e18839f9b1dcaa2f5d02fd1d", "CCE", "", "Super Futebol (CCE) [a]", "AKA RealSports Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2f11ba54609777e2c6a5da9b302c98e8", "Atari - GCC", "CX2676", "Centipede (1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2f16663b01591539624d0ef52934a17d", "M Network", "", "Rocky and Bullwinkle", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2f2f9061398a74c80420b99ddecf6448", "Rentacom - Brazil", "", "Bobby Is Going Home (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2f66ebf037321ed0442ac4b89ce22633", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 2) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2f7772879a1ed04f660aa9d77a86a4bd", "", "", "Yars' Revenge (Genesis)", "Genesis controller (C is zorlon cannon)", "Hack of Yars' Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "2f77f015fc880b05f28e84156f989a0c", "", "", "Plane Demo (Gonzalo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2f7949f71076db42480d3f5036b4a332", "", "", "Name This Game (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "2facd460a6828e0e476d3ac4b8c5f4f7", "Sancho - Tang's Electronic Co.", "", "Words-Attack (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3025bdc30b5aec9fb40668787f67d24c", "", "", "Demo Image Series #14 - Two Marios (4K Interleaved Chronocolour Vertical Movement) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "303242c239474f2d7763b843de58c1c3", "CCE", "", "Laser Blast (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "304512528a5530a9361e8a231ed9a6de", "Thomas Jentzsch", "", "River Raid Plus (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "30512e0e83903fc05541d2f6a6a62654", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari)", "AKA Capture the Flag", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "30516cfbaa1bc3b5335ee53ad811f17a", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3051b6071cb26377cd428af155e1bfc4", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "10", "", "", "", "" }, + { "30685b9b6ebd9ba71536dd7632a1e3b6", "Dactari - Milmar", "", "Tennis (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3091af0ef1a61e801f4867783c21d45c", "CCE", "C-862", "Crackpots (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "30997031b668e37168d4d0e299ccc46f", "", "", "John K Harvey's Equalizer (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "30c92c685224dc7a72b9bbe5eb62d004", "", "", "Hangman Monkey Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "30e012e8d50330c8972f126b8e913bc4", "", "", "Indy 500 (Hack) [a2]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" }, + { "30e0ab8be713208ae9a978b34e9e8e8c", "Atari, Mike Lorenzen", "CX2630, CX2630P", "Circus Atari (1980) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, + { "30f0b49661cfcfd4ec63395fab837dc3", "SEGA, Jeff Lorenz - Teldec", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3105967f7222cc36a5ac6e5f6e89a0b4", "SEGA, Jeff Lorenz", "011-01, 011-02", "Spy Hunter (1984) (SEGA)", "Uses Joystick Coupler (Dual Control Module)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "310ba30e25ea8957e58180b663503c0c", "Ed Federmeyer", "", "Sound X6 (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31235a27b065c2863048fa84db330dc6", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "313243fc41e49ef6bd3aa9ebc0d372dd", "", "", "Fast Food (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31512cdfadfd82bfb6f196e3b0fd83cd", "Tigervision", "7-004", "River Patrol (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3177cc5c04c1a4080a927dfa4099482b", "Atari - Imagineering, Alex DeMeo", "CX26135", "RealSports Boxing (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "317a4cdbab090dcc996833d07cb40165", "Goliath - Hot Shot", "83-312", "Missile War (1983) (Goliath) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "318046ae3711c05fd16e479b298e5fcc", "Retroactive", "", "Qb (V2.08) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "318a9d6dda791268df92d72679914ac3", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "319a142aab6260842ab616382848c204", "", "", "Marble Craze (05-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31bb9b8ceed46cb3e506777a9e65f3ce", "Bit Corporation", "", "4 Game in One Light Green (1983) (BitCorp) (PAL)", "Phantom UFO, Ice Hockey, Cosmic Avenger, Spy Vs. Spy", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31c5fd55a39db5ff30a0da065f86c140", "Dactari - Milmar", "", "Enduro (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31d08cb465965f80d3541a57ec82c625", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31df1c50c4351e144c9a378adb8c10ba", "Quelle", "687.463 0", "Die Ratte und die Karotten (1983) (Quelle) (PAL)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31e518debba46df6226b535fa8bd2543", "Atari, Douglas 'Solaris' Neubauer, Mimi Nyden", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Solaris Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31f4692ee2ca07a7ce1f7a6a1dab4ac9", "Atari, Alan Miller", "CX2642", "Game of Concentration (1980) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "31fcbce1cfa6ec9f5b6de318e1f57647", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32199271dc980eb31a2cc96e10a9e244", "", "", "Radial Pong - Version 12 (Jeffry Johnston) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "321c3451129357af42a375d12afd4450", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32244e55ce6ec6bfbd763f33384bdc2e", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3225676f5c0c577aeccfaa7e6bedd765", "CCE", "C-1002", "Pole Position (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "322b29e84455aa41e7cc9af463bffa89", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (06-25-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "324cb4a749bcac4f3db9da842b85d2f7", "Dennis Debro", "", "Climber 5 (01-05-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "327468d6c19697e65ab702f06502c7ed", "Charles Morgan", "", "Aster-Hawk (2002) (Charles Morgan) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3276c777cbe97cdd2b4a63ffc16b7151", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3278158e5c1f7eb5c5d28ccfd7285250", "Dactari - Milmar", "", "Megamania (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "327fe8cf94f3a45c35a840a453df1235", "", "", "Spice Girls Rule Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "328949872e454181223a80389d03c122", "", "", "Home Run (Unknown) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32ae78abbb5e677e2aabae5cc86cec29", "Atari, Christopher H. Omarzu, Courtney Granner", "CX26112", "Good Luck, Charlie Brown (04-18-1984) (Atari) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32d1260ea682e1bb10850fa94c04ec5f", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32dcd1b535f564ee38143a70a8146efe", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32e65d1e4dfcbcd9b57fee72cafe074c", "", "", "Eckhard Stolberg's Scrolling Text Demo 3 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32ecb5a652eb73d287e883eea751d99c", "Dactar - Milmar", "", "Bowling (Dactar - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "32f4e47a71601ab06cfb59e1c6a0b846", "Ed Federmeyer", "", "Sound X (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3316ee2f887e9cb9b54dd23c5b98c3e2", "", "", "Texas Golf (miniature Gold Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "331938989f0f33ca39c10af4c09ff640", "Zach Matley", "", "Combat - Tank AI (19-04-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "332f01fd18e99c6584f61aa45ee7791e", "", "", "X'Mission (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3347a6dd59049b15a38394aa2dafa585", "Parker Brothers - JWDA, Henry Will IV", "PB5760", "Montezuma's Revenge (1984) (Parker Bros)", "Featuring Panama Joe", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "335793736cbf6fc99c9359ed2a32a49d", "", "", "Analog Clock (V0.0) (20-01-2003) (AD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "335a7c5cfa6fee0f35f5824d1fa09aed", "SEGA - Beck-Tech, Steve Beck, Phat Ho - Teldec", "006-01 - 3.60105 VG", "Congo Bongo (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3367eeba3269aa04720abe6169767502", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "336ea20d38f98926919d4b4651d1a03f", "Omegamatrix", "", "Omega Race (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3391f7c4c656793f92299f4187e139f7", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a4]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "33cac5e767a534c95d292b04f439dc37", "Jone Yuan Telephonic Enterprise Co", "", "Tapeworm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "33d68c3cd74e5bc4cf0df3716c5848bc", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "33ed6dfac4b9ea2f81f778ceddbb4a75", "Activision", "", "River Raid (1982) (SpkSoft) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "340f546d59e72fb358c49ac2ca8482bb", "Sancho - Tang's Electronic Co.", "TEC003", "Skindiver (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "34340c8eecd1e557314789cc6477e650", "Joe Grand", "", "SCSIcide Pre-release 4 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "345488d3b014b684a181108f0ef823cb", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "345758747b893e4c9bdde8877de47788", "CBS Electronics, Joseph Biel", "4L1802, 4L1803, 4L1804, 4L2278", "Venture (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "345769d085113d57937198262af52298", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "346555779a2d51b48833463b5433472f", "Thomas Jentzsch", "", "Thrust (V0.1) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "348615ffa30fab3cec1441b5a76e9460", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL) [fixed]", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "34b269387fa1aa5a396636f5ecdd63dd", "", "", "Marble Craze (mc7_23) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "34c808ad6577dbfa46169b73171585a3", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype)", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "34ca2fcbc8ba4a0b544acd94991cfb50", "Atari, Robert C. Polaro", "", "Dukes of Hazzard (1980) (Atari) (Prototype) (4K)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "34e37eaffc0d34e05e40ed883f848b40", "Retroactive", "", "Qb (2.15) (Retroactive) (Stella)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "34f4b1d809aa705ace6e46b13253fd3b", "Aaron Bergstrom", "", "Nothern Alliance (Aaron Bergstrom) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "34fd4fcb40ff5babce67f8b806d5969c", "", "", "Boxing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "350e0f7b562ec5e457b3f5af013648db", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "35156407e54f67eb1f625450d5c093e1", "", "", "Mouse Trap (Genesis)", "Genesis controller (C changes to dog)", "Hack of Mouse Trap", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "35163b56f4a692a232ae96ad3e23310f", "Retroactive", "", "Qb (2.12) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3545eb3b8b1e7dc19f87d231ab0b1d4c", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3556e125681aea864e17b09f3f3b2a75", "", "", "Incoming (2 Player Demo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3576037c9281656655fa114a835be553", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3577e19714921912685bb0e32ddf943c", "TechnoVision - Video Technology", "TVS1003", "Pharaoh's Curse (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "35ae903dff7389755ad4a07f2fb7400c", "", "", "Colored Wall Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "35b10a248a7e67493ec43aeb9743538c", "Dor-x", "", "Defender (Dor-x) (Hack)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "35b43b54e83403bb3d71f519739a9549", "Parker Brothers, Dave Engman, Isabel Garret", "", "McDonald's (06-06-1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "35be55426c1fec32dfb503b4f0651572", "Men-A-Vision", "", "Air Raid (Men-A-Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "35fa32256982774a4f134c3347882dff", "Retroactive", "", "Qb (V0.05) (Macintosh) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "360ba640f6810ec902b01a09cc8ab556", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (06-15-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "360c0dcb11506e73bd0b77207c81bc62", "Digitel", "", "Enduro (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3619786f6a32efc1e4a262d5aca8a070", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3624e5568368929fabb55d7f9df1022e", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36306070f0c90a72461551a7a4f3a209", "U.S. Games Corporation - JWDA, Roger Booth, Sylvia Day, Ron Dubren, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC1007", "Name This Game (1983) (U.S. Games)", "AKA Octopussy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36547bc6faa5132b87504e18d088e1d7", "", "", "Cosmic Swarm (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "367411b78119299234772c08df10e134", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3685060707df27d4091ba0ea2dc4b059", "", "", "PezZerk - PezMan in Ghost Manor (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "368d88a6c071caba60b4f778615aae94", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36a701c60a9f9768d057bc2a83526a80", "", "", "Cube Conquest (Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "36b20c427975760cb9cf4a47e41369e4", "Coleco - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "2451", "Donkey Kong (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36c29ceee2c151b23a1ad7aa04bd529d", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1986) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36c31bb5daeb103f488c66de67ac5075", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" }, + { "36c993dc328933e4dd6374a8ffe224f4", "Gameworld, J. Ray Dettling", "133-007", "Bermuda Triangle (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36e47ed74968c365121eab60f48c6517", "Quelle", "343.373 7", "Master Builder (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36edef446ab4c2395666efc672b92ed0", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "36f9a953ebdd9a8be97ccf27a2041903", "", "", "Chinese Character Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "37252757a79dc5b174e3c03d6ea0bdcb", "", "", "Sky Diver (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "372bddf113d088bc572f94e98d8249f5", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb) (PAL)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "373b8a081acd98a895db0cb02df35673", "", "", "Demo Image Series #5 - Boofly (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3750f2375252b6a20e4628692e94e8b1", "Dismac", "", "Ases do Ar (Dismac)", "AKA Sky Jinks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "37527966823ee9243d34c7da8302774f", "", "", "Word Zapper (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "376944889dcfa96c73d3079f308e3d32", "Retroactive", "", "Qb (0.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3783f12821b88b08814da8adb1a9f220", "", "", "Mission Survive (PAL) (Genesis)", "Genesis controller (C is vertical fire)", "Hack of Mission Survive)", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "378a62af6e9c12a760795ff4fc939656", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "378c118b3bda502c73e76190ca089eef", "Atari, Alan Miller", "CX2662P", "Hangman (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "37ab3affc7987995784b59fcd3fcbd31", "", "", "Sprite Test (29-11-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "37b98344c8e0746c486caf5aaeec892a", "K-Tel Vision", "6", "Spider Maze (1982) (K-Tel Vision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "37e828675d556775ae8285c0caf7d11c", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby) (Genesis)", "Genesis controller (C throws cookie)", "New Release", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "37f42ab50018497114f6b0f4f01aa9a1", "", "", "Droid Demo 2-M (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "37fd7fa52d358f66984948999f1213c5", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a2]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "384db97670817103dd8c0bbdef132445", "Atari - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "384f5fbf57b5e92ed708935ebf8a8610", "20th Century Fox Video Games, John W.S. Marvin", "11009", "Crypts of Chaos (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3856b9425cc0185ed770376a62af0282", "Kyle Pittman", "", "Yellow Submarine (Kyle Pittman) (Hack)", "Hack of Bermuda Triangle", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "386ff28ac5e254ba1b1bac6916bcc93a", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "3882224adbd0ca7c748b2a1c9b87263e", "Atari, Tod Frye", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3889351c6c2100b9f3aef817a7e17a7a", "CCE", "", "Dolphin (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3897744dd3c756ea4b1542e5e181e02a", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (05-05-1983) (Atari) (Prototype)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "38bd172da8b2a3a176e517c213fcd5a6", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "38c362dcd5cad5a62e73ae52631bd9d8", "Jake Patterson", "", "Baubles (14-11-2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "38cf93eacfb2fa9a2c5e39059ff35a74", "Greg Zumwalt", "", "WacMan (2003) (Greg Zumwalt) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "38de7b68379770b9bd3f7bf000136eb0", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "391764720140c432aec454a468f77a40", "Video Game Program", "", "Miss Pack Man (Video Game Program) (PAL)", "AKA Ms. Pac-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "392d34c0498075dd58df0ce7cd491ea2", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "392f00fd1a074a3c15bc96b0a57d52a1", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, + { "393948436d1f4cc3192410bb918f9724", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "393e41ca8bdd35b52bf6256a968a9b89", "U.S. Games Corporation - Western Technologies, John Hall", "VC1012", "M.A.D. (1983) (U.S. Games)", "AKA Missile Intercept, Mutually Assured Destruction", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3947eb7305b0c904256cdbc5c5956c0f", "Jone Yuan Telephonic Enterprise Co", "", "Lilly Adventure (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "396f7bc90ab4fa4975f8c74abe4e81f0", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "3974e2d1f614fbd3a092533ecae2e84d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "39790a2e9030751d7db414e13f1b6960", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "39a6a5a2e1f6297cceaa48bb03af02e9", "", "", "Pitfall 2 Plus (Hack)", "Hack of Pitfall 2", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "39b94d41bd3b01c12b4054c1a8733783", "SOLID Corp. (D. Scott Williamson)", "CX2655-016", "Star Castle 2600 (SolidCorp) [016]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "39c78d682516d79130b379fa9deb8d1c", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "39d36366ae7e6dfd53393fb9ebab02a0", "CCE", "C-811", "River Raid (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "39da69ff9833f8c143f03b6e0e7a996b", "Charles Morgan", "", "Ventrra Invaders 2002 (Charles Morgan) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "39fe316952134b1277b6a81af8e05776", "Robby", "18", "River Raid (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3a10562937a766cbbb77203d029b00e1", "Carrere Video - JWDA, Garry Kitchen, Paul Willson - Teldec - Prism", "USC1002", "Sneak 'n Peek (1983) (Carrere Video) (PAL)", "AKA Der Unsichtbare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3a2e2d0c6892aa14544083dfb7762782", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3a35d7f1dc2a33565c8dca52baa86bc4", "", "", "Rubik's Cube Demo 2 (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3a51a6860848e36e6d06ffe01b71fb13", "Retroactive", "", "Qb (2.07) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3a521b7e29123b2d38e34e3ff8dc255c", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3a526e6a1f9fe918af0f2ce997dfea73", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3a53963f053b22599db6ac9686f7722f", "", "", "Word Zapper (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3a771876e4b61d42e3a3892ad885d889", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3aad0ef62885736a5b8c6ccac0dbe00c", "Dynacom", "", "Atlantis (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3ab5d138e26d88c8190e7cc629a89493", "", "", "Phased Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3ac6c50a8e62d4ce71595134cbd8035e", "Absolute Entertainment, Dan Kitchen", "AK-046-04", "Tomcat (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3ad3dc799211ccd424d7c6d454401436", "Probe 2000 - NAP", "", "Power Lords (1983) (Probe) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3ad58b53a1e972396890bd86c735e78d", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 36 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b040ed7d1ef8acb4efdeebebdaa2052", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b097a7ed5bd2a84dc3d3ed361e9c31c", "", "", "Interleaved ChronoColour Demo (PAL) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b10106836565e5db28c7823c0898fbb", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b2c32fcd331664d037952bcaa62df94", "Xonox", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b5751a8d20f7de41eb069f76fecd5d7", "", "", "Eckhard Stolberg's Scrolling Text Demo 4 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b64a00ce147c3c29f7f8f8e531d08d8", "", "", "This Planet Sucks (16K) (Greg Troutman)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b69f8929373598e1752f43f8da61aa4", "Apollo - Games by Apollo - RCA Video Jeux", "AP-2006", "Infiltrate (1921) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3b6dba1a24bb2893bd3bd0593f92016b", "CBS Electronics / Thomas Jentzsch", "", "Omega Race JS (TJ)", "Hack of Omega Race (CBS Electronics)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b76242691730b2dd22ec0ceab351bc6", "M Network - INTV, Connie Goldman, Joe King, Patricia Lewis Du Long, Gerald Moore, Mike Sanders, Jossef Wagner", "MT4319", "Masters of the Universe (1983) (M Network)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3b80b8f52a0939e16b5059f93a3fc19a", "V007", "", "Virtual Pet (V007) (after Demo 2) (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b86a27132fb74d9b35d4783605a1bcb", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b8aacf5f5638492b926b5124de19f18", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1981) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b91c347d8e6427edbe942a7a405290d", "Parker Brothers", "PB5350", "Sky Skipper (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b9480bb6fb1e358c9c0a64e86945aee", "", "", "Title Match Pro Wrestling (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3b966bf3c2ca34ac6ca1de4cf6383582", "", "", "Double-Height 6-Digit Score Display (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3bb9793c60c92911895cf44530846136", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c21a89bc38d8cd0b010a2916bcff5c2", "", "", "Colony 7 - CX-22 Hack v0.4 (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" }, + { "3c3a2bb776dec245c7d6678b5a56ac10", "", "", "Unknown Title (bin00003) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c4223316c835ceaad619651e25df0f9", "", "", "Defender (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c4a6f613ca8ba27ce9e43c6c92a3128", "", "", "Qb (V0.04) (Non-Lax Version) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3c57748c8286cf9e821ecd064f21aaa9", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c72ddaf41158fdd66e4f1cb90d4fd29", "Dismac", "", "Comando Suicida (Dismac)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c7a7b3a0a7e6319b2fa0f923ef6c9af", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c7a96978f52b2b15426cdd50f2c4048", "", "", "Overhead Adventure Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c82e808fe0e6a006dc0c4e714d36209", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3c853d864a1d5534ed0d4b325347f131", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3c8e57a246742fa5d59e517134c0b4e6", "Parker Brothers, Rex Bradford, Sam Kjellman", "PB5050", "Star Wars - The Empire Strikes Back (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3ca51b5c08f5a0ecfb17d0c1ec6d0942", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (09-28-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3caa902ac0ce4509308990645876426a", "Atari - GCC, Dave Payne", "CX2669, CX2669P", "Vanguard (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3cbdf71bb9fd261fbc433717f547d738", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE) (PAL)", "AKA Bobby Vai Para Casa", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3cdd91e1c28d28e856c0063d602da166", "", "", "Stell-A-Sketch (03-11-1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3d1e83afdb4265fa2fb84819c9cfd39c", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco)", "AKA Smurf, Smurf Action", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d2367b2b09c28f1659c082bb46a7334", "Imagic, Dennis Koble", "720103-2A, IA3203P, EIX-010-04I", "Atlantis (1982) (Imagic) (PAL)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d2652cbea462a886a41791dd7c8d073", "", "", "Ritorno dei frattelli di Mario (Mario Bros Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d48b8b586a09bdbf49f1a016bf4d29a", "Video Game Cartridge - Ariola", "TP-606", "Hole Hunter (Video Game Cartridge)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d6fc7a19be76d808aa233415cb583fc", "CCE", "C-833", "Target Practice (1983) (CCE)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d7749fb9c2f91a276dfe494495234c5", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d7aad37c55692814211c8b590a0334c", "Atari, Dan Oliver", "", "Telepathy (1983) (Atari) (Prototype)", "Uses both left joystick and right Mindlink controllers (press Fire on respective controller to begin)", "Prototype", "", "", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "78", "", "", "", "" }, + { "3d8a2d6493123a53ade45e3e2c5cafa0", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d934bb980e2e63e1ead3e7756928ccd", "Activision, Steve Cartwright - Ariola", "EAX-017, EAX-017-04I - 711 017-720", "MegaMania (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3d9c2fccf8b11630762ff00811c19277", "", "", "Challenge of.... Nexar, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3da7cc7049d73d34920bb73817bd05a9", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3dfb7c1803f937fadc652a3e95ff7dc6", "Dimax - Sinmax", "SM8001", "Space Robot (Dimax - Sinmax)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3e03086da53ecc29d855d8edf10962cb", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "4L1751, 4L1752, 4L1753, 4L2275", "Gorf (1982) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3e1682ddaec486d8b6b90b527aaa0fc4", "Thomas Jentzsch", "", "Robot City (V0.12) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3e22c7eaf6459b67388602e4bebbb3a8", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL) (4K)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3e33ac10dcf2dff014bc1decf8a9aea4", "Spectravideo - Video Games Industries Corporation, Michael Schwartz - Ralston Purina", "", "Chase the Chuckwagon (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3e49da621193d2611a4ea152d5d5ca3a", "", "", "Atari Logo Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3e4b1137433cc1e617b5508619e13063", "", "", "Asteroids (Genesis)", "Genesis controller (C is hyperspace)", "Hack of Asteroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3e5ca1afaa27c5da3c54c9942fec528b", "", "", "2600 Digital Clock (Demo 2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3e6dab92009d6034618cb6b7844c5216", "", "", "Ed Invaders (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3e7d10d0a911afc4b492d06c99863e65", "VGS", "", "Super Tenis (VGS)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3e88cca5b860d0bd8947479e74c44284", "Atari, Lou Harp", "CX26122", "Sinistar (01-23-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3e899eba0ca8cd2972da1ae5479b4f0d", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3e90cf23106f2e08b2781e41299de556", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3eae062a9b722bda1255d474a87eca5c", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3eb1e34a4f0eec36f12e7336badcecf2", "Jake Patterson", "", "Baubles (V0.001) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3eb21313ea5d5764c5ed9160a5a55a83", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3ec12372ca3e870b11ca70edc7ec26a4", "CommaVid, John Bronstein", "CM-002", "Video Life (1981) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3eccf9f363f5c5de0c8b174a535dc83b", "", "", "Plaque Attack (Unknown) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3ef9573536730dcd6d9c20b6822dbdc4", "Atari, Larry Wagner, Bob Whitehead", "CX2645, CX2645P", "Video Chess (1979) (Atari) (PAL)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f01bd6d059396f495a4cde7de0ab180", "", "", "Qb (Special Edition) (NTSC) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "3f039981255691d3859d04ef813a1264", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) [a]", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f251c50aa7237e61a38ab42315ebed4", "Thomas Jentzsch", "", "Ikari Warriors (1990) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f3ad2765c874ca13c015ca6a44a40a1", "CCE", "C-862", "Crackpots (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f540a30fdee0b20aed7288e4a5ea528", "Atari - GCC", "CX2670", "Atari Video Cube (1983) (Atari)", "AKA Atari Cube, Video Cube", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f58f972276d1e4e0e09582521ed7a5b", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f5a43602f960ede330cd2f43a25139e", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f6938aa6ce66e6f42e582c1eb19b18c", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f6dbf448f25e2bd06dea44248eb122d", "", "5687 A279", "Soccer (1988) (Telegames)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f75a5da3e40d486b21dfc1c8517adc0", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f9431cc8c5e2f220b2ac14bbc8231f4", "", "", "Colors Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f96eb711928a6fac667c04ecd41f59f", "Bit Corporation", "PGP218", "Rodeo Champ (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3f9cb1aba8ec20e2c243ae642f9942bf", "", "", "New Questions (1998) (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3fd1f9d66a418c9f787fc5799174ddb7", "Aaron Curtis", "", "AStar (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3fd53bfeee39064c945a769f17815a7f", "CCE", "", "Sea Hawk (CCE)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3fe43915e5655cf69485364e9f464097", "CCE", "C-863", "Fisher Price (1983) (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "3ff5165378213dab531ffa4f1a41ae45", "Otto Versand", "311377", "Pygmy (1983) (Otto Versand) (PAL)", "AKA Lock 'n' Chase (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4026ad38ba5ce486e88383dc27d7a46f", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "402b1ca3c230a60fb279d4a2a10fa677", "", "", "3-D Tic-Tac-Toe (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "402d876ec4a73f9e3133f8f7f7992a1e", "Alex Herbert", "", "Man Goes Down (2006) (A. Herbert) (Prototype)", "Uses AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "", "" }, + { "405f8591b6941cff56c9b392c2d5e4e5", "Telegames", "", "Star Strike (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4066309eb3fa3e7a725585b9814bc375", "", "", "Multi Ball Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4066d7d88ec4a2c656127a67fa52dcf1", "", "", "Overhead Adventure Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "407a0c6cc0ff777f67b669440d68a242", "Erik Eid", "", "Euchre (Alpha) (PAL) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4093382187f8387e6d011883e8ea519b", "", "", "Go Go Home (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "40aa851e8d0f1c555176a5e209a5fabb", "", "", "Euchre (More for less) (NTSC) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "40b1832177c63ebf81e6c5b61aaffd3a", "Atari, Peter C. Niday", "", "Rubik's Cube 3-D (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "40b59249e05135bca33861e383735e9e", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "40d8ed6a5106245aa79f05642a961485", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "40d9f5709877ecf3dd1184f9791dd35e", "Dactari - Milmar", "", "Skiing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "40e12c008037a323a1290c8fa4d2fe7f", "", "", "Skeleton (NTSC) (06-09-2002) (Eric Ball)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "40eb4e263581b3dfec6dd8920b68e00f", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Seawolf 3 (03-23-1981) (Sears) (Prototype) (PAL)", "Submarine Commander Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "413c925c5fdcea62842a63a4c671a5f2", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4153dd2beed648e9dc082140ebe8e836", "Thomas Jentzsch", "", "Coke Zero (v1.0) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "415c11fcac66bbd2ace2096687774b5a", "", "", "Fu Kung! (V0.00) (07-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4181087389a79c7f59611fb51c263137", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (06-24-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "41810dd94bd0de1110bedc5092bef5b0", "Funvision - Fund. International Co.", "", "Dragon Treasure (Funvision)", "AKA Dragonfire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "41818738ab1745e879024a17784d71f5", "CCE", "C-832", "Atlantis (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4189adfc1b30c121248876e3a1a3ac7e", "Eric Ball", "", "Skeleton (Complete) (06-09-2002) (Eric Ball)", "", "New Release", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4191b671bcd8237fc8e297b4947f2990", "Exus Corporation", "", "Video Jogger (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "41b554c6970b18670acc7b6baef8ed2e", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "41c4e3d45a06df9d21b7aae6ae7e9912", "CCE", "C-826", "Grand Prix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "41f252a66c6301f1e8ab3612c19bc5d4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (1983) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4209e9dcdf05614e290167a1c033cfd2", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid) [higher sounds]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "42249ec8043a9a0203dde0b5bb46d8c4", "CCE", "", "Resgate Espacial (CCE)", "AKA Moonsweeper", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4233eb824c2b4811abef9b6d00355ae9", "Retroactive", "", "Qb (V0.10) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4251b4557ea6953e88afb22a3a868724", "Thomas Jentzsch", "", "Robot City (V1.1) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "425ee444a41d218598893d6b6e03431a", "Thomas Jentzsch", "", "Invaders Demo (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4279485e922b34f127a88904b31ce9fa", "", "", "Enduro (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "428b2d36f5d716765460701f7016ac91", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "42ae81ae8ac51e5c238639f9f77d91ae", "", "", "Multi-Sprite Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "42b2c3b4545f1499a083cfbc4a3b7640", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC2003", "Eggomania (1982) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, + { "42b3ab3cf661929bdc77b621a8c37574", "Robby", "", "Volleyball (Robby)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "42b5e3a35b032f033809afb0ea28802d", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (03-12-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "42cdd6a9e42a3639e190722b8ea3fc51", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "42dcc02777b0bcfacd85aeb61d33558a", "", "", "Human Cannonball (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "42e0ec5ab8f5deba53e4169ff2a5efbe", "", "", "Atari Logo Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4311a4115fb7bc68477c96cf44cebacf", "", "", "Challenge (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4326edb70ff20d0ee5ba58fa5cb09d60", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "435fd469f088468c4d66be6b5204d887", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "438968a26b7cfe14a499f5bbbbf844db", "", "", "Raft Rider (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "43adf60ebdd6b5a0fae21594ecf17154", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "43c6cfffeddab6b3787357fed9d44529", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11111", "M.A.S.H (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "43f33c6dfdeaf5138ce6e6968ad7c5ce", "Jeffry Johnston", "", "Radial Pong - Version 11 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "43f8459d39fb4eddf9186d62722ff795", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "442602713cb45b9321ee93c6ea28a5d0", "", "", "Demon Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4427f06085bb4c22ff047027f7acecc2", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros) (Prototype)", "Uses the Paddle Controllers (swapped)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" }, + { "442b7863683e5f084716fda050474feb", "Eckhard Stolberg", "", "Frame Timed Sound Effects-EM (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4431428a7500c96fc0e2798a5dbd36d6", "", "", "Kangaroo (Genesis)", "Genesis controller (B is punch, C is jump)", "Hack of Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4474b3ad3bf6aabe719a2d7f1d1fb4cc", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4476c39736090dabac09f6caf835fc49", "", "", "Text Screen (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "448c2a175afc8df174d6ff4cce12c794", "Activision, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a2]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "44e9c4a047c348dbeb7ace60f45484b4", "", "", "Moon Patrol Arcade (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "44f71e70b89dcc7cf39dfd622cfb9a27", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "45027dde2be5bdd0cab522b80632717d", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "45040679d72b101189c298a864a5b5ba", "20th Century Fox Video Games - Sirius Software, David Lubar", "11022", "SpaceMaster X-7 (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4543b7691914dfd69c3755a5287a95e1", "CommaVid, Irwin Gaines", "CM-005", "Mines of Minos (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "456453a54ca65191781aef316343ae00", "", "", "Full Screen Bitmap (3-D Green) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4565c1a7abce773e53c75b35414adefd", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "457b03cd48ff6d895795ef043c6b0f1e", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "457e7d4fcd56ebc47f5925dbea3ee427", "Carrere Video - JWDA, Garry Kitchen - Teldec - Prism", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "457f4ad2cda5f4803f122508bfbde3f5", "", "", "Canyon Bomber (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "458883f1d952cd772cf0057abca57497", "", "", "Fishing Derby (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "45a095645696a217e416e4bd2baea723", "Digivision", "", "Snoopy (Digivision)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "45a4f55bb9a5083d470ad479afd8bca2", "CommaVid, Joseph Biel", "", "Frog Demo (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "45beef9da1a7e45f37f3f445f769a0b3", "Atari, Suki Lee", "CX2658", "Math Gran Prix (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "45c4413dd703b9cfea49a13709d560eb", "Jone Yuan Telephonic Enterprise Co", "", "Challenge of.... Nexar, The (Jone Yuan) (Hack)", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "45cb0f41774b78def53331e4c3bf3362", "Carrere Video - JWDA, Roger Booth, Sylvia Day, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC1007", "Octopus (1983) (Carrere Video) (PAL)", "AKA Name This Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4605a00f5b44a9cbd5803a7a55de150e", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-03-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "461029ab23800833e9645be3e472d470", "", "", "Combat TC (v0.1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "46258bd92b1f66f4cb47864d7654f542", "Zellers", "", "Turmoil (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "463dd4770506e6c0ef993a40c52c47be", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "463e66ad98806a49106cffa49c08e2ed", "", "", "Interlace Game Demo (01-09-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "467340a18158649aa5e02a4372dcfccd", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4689081b7363721858756fe781cc7713", "", "", "Oystron (V2.6) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "468f2dec984f3d4114ea84f05edf82b6", "Tigervision - Teldec", "7-011 - 3.60015 VG", "Miner 2049er Volume II (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4690fdb70c86604bb35da26696818667", "", "", "Euchre (Release Candidate) (NTSC) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "469473ff6fed8cc8d65f3c334f963aab", "Atari, Bruce Poehlman, Gary Stark", "", "Dune (07-10-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "46c021a3e9e2fd00919ca3dd1a6b76d8", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "46c43fdcbce8fde3a91ebeafc05b7cbd", "", "", "Invaders Demo (PAL) (2001) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "46dc526773808c8b9bb2111f24e5704c", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "46e9428848c9ea71a4d8f91ff81ac9cc", "Telegames", "", "Astroblast (1988) (Telegames) (PAL)", "Can also use left joystick", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "YES", "", "", "AUTO 55", "", "", "", "" }, + { "4702d8d9b48a332724af198aeac9e469", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "470878b9917ea0348d64b5750af149aa", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "471f7bdc933e8db0e44aa3dde2dd92af", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "47464694e9cce07fdbfd096605bf39d4", "Activision, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "47585c047802dd9af888b998fb921f32", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4767356fa0ed3ebe21437b4473d4ee28", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (04-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "47711c44723da5d67047990157dcb5dd", "CCE", "", "Ice Hockey (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "47911752bf113a2496dbb66c70c9e70c", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari) (PAL)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "4799a40b6e889370b7ee55c17ba65141", "Konami", "RC 100-X 02", "Pooyan (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "47aad247cce2534fd70c412cb483c7e0", "Rainbow Vision - Suntek", "SS-010", "Mafia (1983) (Rainbow Vision) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "47abfb993ff14f502f88cf988092e055", "Zellers", "", "Inca Gold (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "47aef18509051bab493589cb2619170b", "", "", "Stell-A-Sketch (Bob Colbert) (PD)", "Uses Driving, Joystick, or Amiga/Atari ST Mouse Controllers", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "47b82d47e491ac7fdb5053a88fccc832", "Atari Freak 1, Franklin Cruz", "", "Asteroid 2 (Atari Freak 1) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "47cd61f83457a0890de381e478f5cf5f", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-2A, 13205", "Fathom (1983) (Imagic) (PAL)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "481d20ec22e7a63e818d5ef9679d548b", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "481f9a742052801cc5f3defb41cb638e", "Jeffry Johnston", "", "Radial Pong - Version 4 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "48287a9323a0ae6ab15e671ac2a87598", "Zellers", "", "Laser Volley (Zellers)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4834b7b28ea862227ac7e40053fb52a5", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "48411c9ef7e2cef1d6b2bee0e6055c27", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "484b0076816a104875e00467d431c2d2", "Atari", "CX26150", "Q-bert (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4857f8bb88bb63c640d3ea5aac7f5d6d", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (08-12-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4868a81e1b6031ed66ecd60547e6ec85", "Eric Mooney", "", "Invaders by Erik Mooney (V2.1) (1-3-98) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "487193a7b7fe57a1bbc2f431f628bd5f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4884b1297500bd1243659e43c7e7579e", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (10-24-1991) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4892b85c248131d6a42c66a4163a40d0", "Canal 3 - Intellivision", "", "Tac-Scan (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "48bcf2c5a8c80f18b24c55db96845472", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "48e5c4ae4f2d3b62b35a87bca18dc9f5", "Quelle", "476.774 5", "Bobby geht nach Hause (1983) (Quelle) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "48f18d69799a5f5451a5f0d17876acef", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4901c05068512828367fde3fb22199fe", "Imagic, Rob Fulop", "720101-2B, IA3200P, EIX-006-04I", "Demon Attack (1982) (Imagic) (PAL)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4904a2550759b9b4570e886374f9d092", "Parker Brothers, Charlie Heath", "931506", "Reactor (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "490e3cc59d82f85fae817cdf767ea7a0", "", "", "Berzerk (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "490eed07d4691b27f473953fbea6541a", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "49366f41aa7a54baf263426e99ce4312", "", "", "POP-MDM-Test (PAL) (63 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "493daaf9fb1ba450eba6b8ed53ffb37d", "", "", "3-D Corridor Demo (27-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "493de059b32f84ab29cde6213964aeee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "493e90602a4434b117c91c95e73828d1", "Telegames", "", "Lock 'n' Chase (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4947c9de2e28b2f5f3b0c40ce7e56d93", "", "", "3-D Corridor Demo 2 (29-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "494cda91cc640551b4898c82be058dd9", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "49571b26f46620a85f93448359324c28", "", "", "Save Our Ship (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "497c811026367c08fd838c9c59e5041d", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "497f3d2970c43e5224be99f75e97cbbb", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4981cefe5493ea512284e7f9f27d1e54", "Home Vision - Gem International Corp. - VDI", "VCS83136", "Cosmic War (1983) (Home Vision) (PAL)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4999b45be0ab5a85bac1b7c0e551542b", "CCE", "", "Double Dragon (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "499b612f6544ae71d4915aa63e403e10", "Atari, Carol Shaw", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "49f2cef5269fd06218be9f9474c74f8d", "Rentacom", "", "Time Pilot (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4a196713a21ef07a3f74cf51784c6b12", "Jone Yuan Telephonic Enterprise Co", "", "Frogs and Flies (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4a2fe6f0f6317f006fd6d4b34515448b", "", "", "Warring Worms (Midwest Classic Edition) (08-06-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4a45c6d75b1ba131f94a9c13194d8e46", "", "", "How to Draw a Playfield II (Joystick Hack) (1997) (Eric Bacher) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4a5fddf89801336637ac8e57a7c9a881", "Amiga", "1125", "Power Play Arcade Video Game Album IV (1984) (Amiga) (Prototype)", "Atlantis, Cosmic Ark, Dragonfire", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4a6be79310f86f0bebc7dfcba4d74161", "", "", "Demolition Herby (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4a7eee19c2dfb6aeb4d9d0a01d37e127", "Hozer Video Games", "", "Crazy Valet (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4a8c743396b8ad69d97e6fd3dd3e3132", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4a9009620038f7f30aaeb2a00ae58fde", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4ab2ebd95a8f861ea451abebdad914a5", "Nukey Shay, Thomas Jentzsch", "PAL conversion (F6)", "Montezuma's Revenge (PAL) (Genesis)", "Genesis controller (B jumps left, C jumps right)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4ab4af3adcdae8cdacc3d06084fc8d6a", "Nick Bensema", "", "Sucky Zepplin (Nick Bensema) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4abb4c87a4c5f5d0c14ead2bb36251be", "Atari - Imagineering, Alex DeMeo", "CX26135, CX26135P", "RealSports Boxing (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4ac9f40ddfcf194bd8732a75b3f2f214", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (12-29-1982) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4ae8c76cd6f24a2e181ae874d4d2aa3d", "", "", "Flash Gordon (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4af4103759d603c82b1c9c5acd2d8faf", "Imagic, Bob Smith", "720114-2A, 13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4afa7f377eae1cafb4265c68f73f2718", "Ed Fries", "", "Halo 2600 (2010) (Ed Fries)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4afe528a082f0d008e7319ebd481248d", "", "", "Multi-Color Demo 1 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4b143d7dcf6c96796c37090cba045f4f", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4b205ef73a5779acc5759bde3f6d33ed", "", "", "Berzerk (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4b27f5397c442d25f0c418ccdacf1926", "Atari, Warren Robinett", "CX2613, 49-75154", "Adventure (1980) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4b379b885e2694f992c6cc932f18327f", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4b71197153d651480830638cb6a03249", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4b753a97aee91e4b3e4e02f5e9758c72", "Glenn Saunders, Roger Williams", "", "Asymmetric Reflected Playfield (Glenn Saunders)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4b94fd272785d7ec6c95fb7279d0f522", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (12-03-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "4b9581c3100a1ef05eac1535d25385aa", "", "", "IQ 180 (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4baada22435320d185c95b7dd2bcdb24", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4bcc7f6ba501a26ee785b7efbfb0fdc8", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4bdae9246d6ee258c26665512c1c8de3", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4bdf54a454470ba015a217a8f5e61320", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" }, + { "4c030667d07d1438f0e5c458a90978d8", "Retroactive", "", "Qb (V2.03) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4c0fb2544ae0f8b5f7ae8bce7bd7f134", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c205f166157154df2f1ef60d87e552f", "", "", "Single-Scanline Positioning Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c39a2c97917d3d71739b3e21f60bba5", "", "", "Whale (Sub Scan Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c462b2b6fb0a19a1437eb2c3dc20783", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c4ce802cbfd160f7b3ec0f13f2a29df", "", "", "Beta Demo (V1.1) (26-09-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c606235f4ec5d2a4b89139093a69437", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4c6afb8a44adf8e28f49164c84144bfe", "CCE", "C-806", "Mission 3,000 A.D. (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c8832ed387bbafc055320c05205bc08", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c8970f6c294a0a54c9c45e5e8445f93", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4c9307de724c36fd487af6c99ca078f2", "Imagic, Brad Stewart", "720106-1A, IA3409", "Sky Patrol (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4ca0959f846d2beada18ecf29efe137e", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666, CX2666P", "RealSports Volleyball (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4ca73eb959299471788f0b685c3ba0b5", "Activision, Steve Cartwright", "AX-031", "Frostbite (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4ca90ba45eced6f5ad560ea8938641b2", "", "", "Hangman Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4cabc895ea546022c2ecaa5129036634", "Funvision - Fund. International Co.", "", "Ocean City (Funvision)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4cd796b5911ed3f1062e805a3df33d98", "Tigervision - Software Electronics Corporation - Teldec", "7-006", "Springer (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d06f72cc3d8934579c11ff8f375c260", "Bit Corporation", "R320", "Bowling (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d0a28443f7df5f883cf669894164cfa", "", "", "Beast Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d2cef8f19cafeec72d142e34a1bbc03", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d38e1105c3a5f0b3119a805f261fcb5", "Bit Corporation", "PGP212", "Phantom UFO (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Spider Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d502d6fb5b992ee0591569144128f99", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (11-21-1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d5f6db55f7f44fd0253258e810bde21", "Fabrizio Zavagli", "", "Betterblast (Fabrizio Zavagli) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d7517ae69f95cfbc053be01312b7dba", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d77f291dca1518d7d8e47838695f54b", "Data Age", "DA1004", "Airlock (1982) (Data Age)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4d8396deeabb40b5e8578276eb5a8b6d", "Otto Versand", "781698", "Volleyball (1983) (Otto Versand) (PAL)", "AKA RealSports Volleyball (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4dbd7e8b30e715efc8d71d215aec7fe7", "Bit Corporation", "R320", "Air Raiders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4dbf47c7f5ac767a3b07843a530d29a5", "Ric Pryor", "", "Breaking News (2002) (Ric Pryor) (Hack)", "Hack of Bump 'n' Jump", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4dcc7e7c2ec0738e26c817b9383091af", "", "", "Unknown Title (bin00026 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4dd6c7ab9ef77f2b4950d8fc7cd42ee1", "Retroactive", "", "Qb (V2.04) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4df6124093ccb4f0b6c26a719f4b7706", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, + { "4df9d7352a56a458abb7961bf10aba4e", "", "", "Racing Car (Unknown)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4e01d9072c500331e65bb87c24020d3f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4e02880beeb8dbd4da724a3f33f0971f", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL)", "AKA Flap!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4e15ddfd48bca4f0bf999240c47b49f5", "Avalon Hill, Jean Baer, Jim Jacob", "5001002", "Death Trap (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4e2c884d04b57b43f23a5a2f4e9d9750", "", "", "Baby Center Animation (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4e37992a37ea36489283f7eb90913bbc", "Kris", "", "Hangman Ghost Halloween (Kris) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4e4895c3381aa4220f8c2795d6338237", "", "", "Backwards Cannonball v1 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4e66c8e7c670532569c70d205f615dad", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4e86866d9cde738d1630e2e35d7288ce", "Supergame", "", "River Raid III (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4e99ebd65a967cabf350db54405d577c", "Coleco", "2663", "Time Pilot (1983) (Coleco) [b1]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4eb4fd544805babafc375dcdb8c2a597", "Inspirational Video Concepts, Steve Shustack", "321430", "Red Sea Crossing (1983) (Inspirational Video Concepts)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4edb251f5f287c22efc64b3a2d095504", "Atari", "", "Atari VCS Point-of-Purchase ROM (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4f0071946e80ca68edfdccbac86dcce0", "", "", "Virtual Pet Demo 1 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4f2d47792a06da224ba996c489a87939", "HES - Activision", "223", "Super Action Pak - Pitfall, Barnstorming, Grand Prix, Laser Blast (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4f32b24869d8c1310fecf039c6424db6", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (12-15-82) (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4f618c2429138e0280969193ed6c107e", "Activision, Alan Miller", "AZ-028, AG-028-04", "Robot Tank (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4f634893d54e9cabe106e0ec0b7bdcdf", "Retroactive", "", "Qb (2.14) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4f64d6d0694d9b7a1ed7b0cb0b83e759", "20th Century Fox Video Games, John Russell", "11016", "Revenge of the Beefsteak Tomatoes (1983) (20th Century Fox)", "AKA Revenge of the Cherry Tomatoes", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4f6702c3ba6e0ee2e2868d054b00c064", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen - Ariola", "EAZ-033 - 711 033-725", "Space Shuttle (1983) (Activision) (PAL)", "A Journey Into Space, Eine Reise ins All", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4f781f0476493c50dc578336f1132a67", "", "", "Indy 500 (Unknown) (PAL) (4K)", "Uses Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" }, + { "4f7b07ec2bef5ccffe06403a142f80db", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4f82d8d78099dd71e8e169646e799d05", "", "", "Miniature Golf (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4f89b897444e7c3b36aed469b8836839", "Atari", "CX26190", "BMX Air Master (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4fae08027365d31c558e400b687adf21", "", "", "Qb (V2.17) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "4faeb04b1b7fb0fa25db05753182a898", "", "", "2600 Digital Clock (V x.xx) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4fbe0f10a6327a76f83f83958c3cbeff", "CCE", "C-816", "Keystone Kappers (1983) (CCE)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "4fc1b85b8074b4b9436d097900e34f29", "John K. Harvey", "", "John K. Harvey's Equalizer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "50200f697aeef38a3ce31c4f49739551", "Mystique - American Multiple Industries, Joel H. Martin", "", "Custer's Revenge (1982) (Mystique) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "502044b1ac111b394e6fbb0d821fca41", "", "", "Hangman Invader 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "502168660bfd9c1d2649d415dc89c69d", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "504688d49a41bf03d8a955512609f3f2", "Thomas Jentzsch", "", "SWOOPS! (v0.94) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "50568c80ac61cab789d9923c9b05b68e", "Ebivision", "", "Merlin's Walls - Standard Edition (1999) (Ebivision)", "Image rotated 90 degrees CW", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5069fecbe4706371f17737b0357cfa68", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo) (PAL)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5079bfbc7b8f5770f84215ed2e3bdd1b", "Omegamatrix (2012)", "", "Genesis Button Tester", "", "Homebrew", "", "", "", "", "", "", "", "GENESIS", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "" }, + { "50a410a5ded0fc9aa6576be45a04f215", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "50c7edc9f9dc0369abcdab3b4efeb5e9", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "50ef88f9a5e0e1e6b86e175362a27fdb", "", "", "Multi-Sprite Game V2.4 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "512e874a240731d7378586a05f28aec6", "Tigervision, Rorke Weigandt - Teldec", "7-005", "Marauder (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5131ab3797fe8c127e3e135b18b4d2c8", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "514f911ecff2be5eeff2f39c49a9725c", "Parker Brothers", "931510", "Sky Skipper (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "515046e3061b7b18aa3a551c3ae12673", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "516ffd008057a1d78d007c851e6eff37", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "517592e6e0c71731019c0cebc2ce044f", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "517923e655755086a3b72c0b17b430e6", "Tron", "", "Super Tennis (Tron)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5188fee071d3c5ef0d66fb45c123e4a5", "Gameworld", "133-001", "Encounter at L-5 (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, + { "519f007c0e14fb90208dbb5199dfb604", "Amiga - Video Soft", "", "Depth Charge (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "51c1ddc9d6d597f71fb7efb56012abec", "Bit Corporation", "R320", "Lock 'n' Chase (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "51de328e79d919d7234cf19c1cd77fbc", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "51e390424f20e468d2b480030ce95d7b", "Video Game Program", "", "Fire Bird (Video Game Program) (PAL)", "AKA Phoenix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "51f15b39d9f502c2361b6ba6a73464d4", "", "", "Amanda Invaders (PD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "51f211c8fc879391fee26edfa7d3f11c", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "521f4dd1eb84a09b2b19959a41839aad", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "522b27a8afeb951b5a5a667f8d1a46a1", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "522c9cf684ecd72db2f85053e6f6f720", "Rainbow Vision - Suntek", "SS-008", "Year 1999, The (1983) (Rainbow Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "52385334ac9e9b713e13ffa4cc5cb940", "CCE", "C-804", "Open, Sesame! (1983) (CCE)", "AKA Abre-te, Sesamo!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "523f5cbb992f121e2d100f0f9965e33f", "Joe Grand", "", "SCSIcide (1.30) (CGE 2001 Release) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" }, + { "524693b337f7ecc9e8b9126e04a232af", "", "", "Euchre (19-08-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5256f68d1491986aae5cfdff539bfeb5", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-26-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "525ea747d746f3e80e3027720e1fa7ac", "Activision, Garry Kitchen - Ariola", "EAZ-032 - 771 032-712", "Pressure Cooker (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "525f2dfc8b21b0186cff2568e0509bfc", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "52615ae358a68de6e76467e95eb404c7", "", "", "DJdsl-wopd (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "528400fad9a77fd5ad7fc5fdc2b7d69d", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "52a0003efb3b1c49fcde4dbc2c685d8f", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K) [a]", "", "", "", "", "2K", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "52b448757081fd9fabf859f4e2f91f6b", "", "", "Worm War I (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "52bae1726d2d7a531c9ca81e25377fc3", "", "", "Space Instigators (V1.8 Fixed) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "52e1954dc01454c03a336b30c390fb8d", "Retroactive", "", "Qb (2.14) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "52e9db3fe8b5d336843acac234aaea79", "", "", "Fu Kung! (V0.11) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5305f69fbf772fac4760cdcf87f1ab1f", "Jone Yuan Telephonic Enterprise Co", "", "Ski Run (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5324cf5b6dc17af4c64bf8696c39c2c1", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (8K)", "AKA Lost City of Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "533661e9bccd8a9f80ce3765f282c92f", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5336f86f6b982cc925532f2e80aa1e17", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "PB5060", "Star Wars - Death Star Battle (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "534e23210dd1993c828d944c6ac4d9fb", "M Network, Stephen Tatsumi, Jane Terjung - Kool Aid", "MT4648", "Kool-Aid Man (1983) (M Network)", "AKA Kool Aid Pitcher Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5355f80cacf0e63a49cbf4ade4e27034", "Christian Samuel", "", "Cute Dead Things House (Christian Samuel) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5360693f1eb90856176bd1c0a7b17432", "", "", "Oystron (V2.85) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "536bf56baa70acb17113884ac41f2820", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "537ed1e0d80e6c9f752b33ea7acbe079", "", "", "A-VCS-tec Challenge (beta 5) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5385cf2a04de1d36ab55c73174b84db0", "Paul Slocum", "", "Combat Rock (PD) (Hack)", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "539d26b6e9df0da8e7465f0f5ad863b7", "Atari, Carol Shaw - Sears", "CX2636 - 49-75156", "Video Checkers (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "539f3c42c4e15f450ed93cb96ce93af5", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "53b66f11f67c3b53b2995e0e02017bd7", "CCE", "C-1005", "Super Tennis (1983) (CCE)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "53bd1c7c972ae634c912331a9276c6e3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "53d181cde2e0219b5754caad246fcb66", "", "", "Missile Demo (1998) (Ruffin Bailey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "53e03df47e76329b701641f8bdc206f5", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "53f147b9746fdc997c62f3dd67888ee5", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "540075f657d4b244a1f74da1b9e4bf92", "Bit Corporation", "PGP230", "Festival (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5409d20c1aea0b89c56993aec5dc5740", "", "", "Carnival Shooter (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "541cac55ebcf7891d9d51c415922303f", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5428cdfada281c569c74c7308c7f2c26", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "542c6dd5f7280179b51917a4cba4faff", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5438e84b90e50a5362f01cc843b358d4", "Arcadia Corporation, Scott Nelson", "3 AR-4300", "Fireball (1982) (Arcadia) (Prototype)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "543b4b8ff1d616fa250c648be428a75c", "Warren Robinett", "", "Adventure (1978) (Warren Robinett) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "545048ccb045f9efc6cf2b125cd0dfa8", "Arcadia Corporation, Stephen Harland Landrum, Jon Leupp", "AR-4201", "Sword of Saros (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "54785fa29e28aae6038929ba29d33d38", "", "", "Poker Squares (V0.19) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "54836a8f23913e9a77c7f2665baf36ac", "Bit Corporation", "PG204", "Open, Sesame! (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5494b9ee403d9757f0fd1f749e80214a", "Larry Petit", "", "Xenophobe Arcade (2003) (Larry Petit) (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "54a1c1255ed45eb8f71414dadb1cf669", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "54bafc299423f5a50b8bc3a797914706", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp) (PAL)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "54da3b0b3f43f5b37911c135b9432b49", "", "", "Halloween III Revision (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "54f7efa6428f14b9f610ad0ca757e26c", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "551a64a945d7d6ece81e9c1047acedbc", "Matthias Jaap", "", "Coffee Cup Soccer (Matthias Jaap) (Hack)", "Hack of Pele's Soccer", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5524718a19107a04ec3265c93136a7b5", "Thomas Jentzsch", "", "RealSports Basketball (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "553dbf9358cfd2195e2fa0e08b01fb6a", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (07-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "554fd5775ca6d544818c96825032cf0d", "Atari - Roklan, Bob Curtiss", "", "Firefox (06-01-83) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "557e893616648c37a27aab5a47acbf10", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (01-16-1990) (Atari) (Prototype) (PAL)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "559317712f989f097ea464517f1a8318", "Panda", "100", "Space Canyon (1983) (Panda)", "AKA Space Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "55949cb7884f9db0f8dfcf8707c7e5cb", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "55ace3c775f42eb46f08bb1dca9114e7", "", "", "Shadow Keep (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "55ef6ab2321ca0c3d369e63d59c059c8", "", "", "Pitfall! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "55ef7b65066428367844342ed59f956c", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "56210a3b9ea6d5dd8f417a357ed8ca92", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype) [bad dump]", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "56300ed31fef018bd96768ccc982f7b4", "HES - Activision", "559", "Rad Action Pak - Kung-Fu Master, Freeway, Frostbite (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5641c0ff707630d2dd829b26a9f2e98f", "Joystik", "", "Motocross (Joystik)", "AKA Motocross Racer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5643ee916f7dc760148fca4db3aa7d10", "", "", "Moon Patrol (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5678ebaa09ca3b699516dba4671643ed", "Coleco, Sylvia Day, Henry Will IV", "2459", "Mouse Trap (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "568371fbae6f5e5b936af80031cd8888", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "56f72247eb9ebfd33bfd0cca23ab7ef4", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "571c6d9bc71cb97617422851f787f8fe", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "572d0a4633d6a9407d3ba83083536e0f", "Funvision - Fund. International Co.", "", "Busy Police (Funvision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "575c0fb61e66a31d982c95c9dea6865c", "", "", "Blackjack (Unknown) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "57939b326df86b74ca6404f64f89fce9", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "579baa6a4aa44f035d245908ea7a044d", "Jess Ragan", "", "Galaxian Enhanced Graphics (Jess Ragan) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "57a66b6db7efc5df17b0b0f2f2c2f078", "Retroactive", "", "Qb (V2.08) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "57c5b351d4de021785cf8ed8191a195c", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "5835a78a88f97acea38c964980b7dbc6", "", "", "Cosmic Creeps (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5846b1d34c296bf7afc2fa05bbc16e98", "Atari - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "58513bae774360b96866a07ca0e8fd8e", "Mystique - American Multiple Industries, Joel H. Martin", "1001", "Custer's Revenge (1982) (Mystique)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "585600522b1f22f617652c962e358a5d", "", "", "Multi-Sprite Game V2.2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "585f73010e205ae5b04ee5c1a67e632d", "", "", "Daredevil (V3) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5864cab0bc21a60be3853b6bcd50c59f", "", "", "Commando Raid (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "58746219d8094edff869f0f5c2aeaad5", "Jone Yuan Telephonic Enterprise Co", "", "Bowling (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5894c9c0c1e7e29f3ab86c6d3f673361", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision)", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "589c73bbcd77db798cb92a992b4c06c3", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "58a82e1da64a692fd727c25faef2ecc9", "CCE", "C-824", "Jaw Breaker (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "58c396323ea3e85671e34c98eb54e2a4", "Brian Watson", "", "Color Tweaker (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "58d331c23297ed98663d11b869636f16", "", "", "Fu Kung! (V0.09) (26-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "58e313e2b5613b2439b5f12bb41e3eef", "", "", "Cube Conquest (Demo Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "590ac71fa5f71d3eb29c41023b09ade9", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (01-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "59135f13985b84c4f13cc9e55eec869a", "", "", "Multi-Sprite Game V2.0 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "594437a35603c3e857b5af75b9718b61", "HES - Activision", "", "Robot Tank (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "594dbc80b93fa5804e0f1368c037331d", "Telesys, Alex Leavens", "", "Bouncin' Baby Bunnies (1983) (Telesys) (Prototype)", "AKA Baby Boom Boom, Bouncing Baby Monkeys", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5961d259115e99c30b64fe7058256bcf", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "59734e1cc41822373845a09c51e6ba21", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "598a4e6e12f8238b7e7555f5a7777b46", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "599cbf919d47a05af975ad447df29497", "Jake Patterson", "", "Baubles (V0.002) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "59b70658f9dd0e2075770b07be1a35cf", "Thomas Jentzsch", "", "Surfer's Paradise (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "59d33e00c07665395209c1e55da0b139", "", "", "Imagic Selector ROM (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "59e53894b3899ee164c91cfa7842da66", "Data Age", "", "Survival Run (1983) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "59e96de9628e8373d1c685f5e57dcf10", "PlayAround - J.H.M.", "204", "Beat 'Em & Eat 'Em (1982) (PlayAround)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "59f596285d174233c84597dee6f34f1f", "CCE", "C-811", "River Raid (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a0ff99ba10bd26d542e1d6f59f56850", "Champ Games", "CG-04-P", "Super Cobra Arcade (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5a17e30e6e911e74ccd7b716d02b16c6", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a272012a62becabcd52920348c7c60b", "Star Game", "", "Pitfall (Star Game)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a2f2dcd775207536d9299e768bcd2df", "Otto Versand", "781698", "Flippern (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a4205aeedd3b0588f973f38bbd9dfd4", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a5390f91437af9951a5f8455b61cd43", "Retroactive", "", "Qb (0.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5a6febb9554483d8c71c86a84a0aa74e", "CCE", "C-1003", "Donkey Kong Jr (1983) (CCE)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a734779d797ccef25dc8acfa47244c7", "", "", "Oh No! (Version 2) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a80b857eb8b908ab477ec4ef902edc8", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a81ad4e184050851e63c8e16e3dac77", "Jone Yuan Telephonic Enterprise Co", "Hack", "Sky Diver (Jone Yuan) (Hack)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a8afe5422abbfb0a342fb15afd7415f", "Atari - Bobco, Robert C. Polaro", "CX26155", "Sprint Master (1988) (Atari)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a93265095146458df2baf2162014889", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5a9685c4d51a6c1d6a9544946d9e8dc3", "AtariAge", "", "Grandma's Revenge (AtariAge)", "Can use Driving Controller in right port", "", "", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" }, + { "5a9d188245aff829efde816fcade0b16", "CCE", "C-808", "Phantom Tank (1983) (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5acf9865a72c0ce944979f76ff9610f0", "", "", "Dodge Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5ae73916fa1da8d38ceff674fa25a78a", "CCE", "", "Barnstorming (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5aea9974b975a6a844e6df10d2b861c4", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5af9cd346266a1f2515e1fbc86f5186a", "SEGA", "002-01", "Sub-Scan (1983) (SEGA)", "AKA Subterfuge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b124850de9eea66781a50b2e9837000", "PlayAround - J.H.M.", "205", "Bachelor Party (1982) (PlayAround)", "Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, + { "5b574faa56836da0866ba32ae32547f2", "", "", "Tomb Raider 2600 [REV 03] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b5d04887922b430de0b7b2a21f9cd25", "", "", "Omega Race (Genesis)", "Genesis controller (B is thrust, C is fire)", "Hack of Omega Race", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b6f5bcbbde42fc77d0bdb3146693565", "", "", "Seaquest (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b7ea6aa6b35dc947c65ce665fde624b", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b85e987e2b1618769d97ba9182333d0", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b92a93b23523ff16e2789b820e2a4c5", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "AG-039-04", "Kung-Fu Master (1987) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b98e0536c3f60547dd708ae22adb04b", "Ben Hudman", "", "Donkey Kong Gingerbread Man (Ben Hudman) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5b9c2e0012fbfd29efd3306359bbfc4a", "HES", "", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5babe0cad3ec99d76b0aa1d36a695d2f", "Coleco - Individeo, Ed Temple", "2654", "Looping (1983) (Coleco) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5bba254e18257e578c245ed96f6b003b", "", "", "Music Effects Demo (21-01-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5bbab3f3e4b47e3e23f9820765dbb45c", "", "", "Pitfall! (says 1985) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5bbb75b49b2bccef9c91ff84bb249c80", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5bc9998b7e9a970e31d2cb60e8696cc4", "Jack Kortkamp", "", "Borgwars Asteroids (2003) (Jack Kortkamp) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5bcc83677d68f7ef74c1b4a0697ba2a8", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (16K)", "", "", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5bd79139a0c03b63f6f2cf00a7d385d2", "Marc de Smet", "", "An Exercise In Minimalism (V1) (1999) (Marc de Smet) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5be03a1fe7b2c114725150be04b38704", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5c0227ad63300670a647fcebf595ea37", "Josh", "", "Battle for Naboo (Josh) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5c0520c00163915a4336e481ca4e7ef4", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a1]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5c19f6da638c4c7c1f98d09e63df43e4", "Canal 3 - Intellivision", "", "Cosmic Ark (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5c1b1aa78b7609d43c5144c3b3b60adf", "", "", "Demo Image Series #8 - Two Marios (Different Interlacing) (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5c3a6d27c026f59a96b7af91e8b1bf26", "PlayAround - J.H.M.", "", "PlayAround Demo (PlayAround) (1982)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5c618a50dfa23daac97ba459b9ff5206", "Steve Engelhardt", "", "Berzerk Renegade (2002) (Steve Engelhardt) (Hack)", "Hack of Room of Doom", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5c73693a89b06e5a09f1721a13176f95", "", "", "Wavy Line Test 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5c86e938e0845b9d61f458539e9a552b", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5cbd7c31443fb9c308e9f0b54d94a395", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5ce98f22ade915108860424d8dde0d35", "", "", "Hangman Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5ced13931c21ef4fc77d3fe801a1cbfa", "CCE", "C-828", "Missile Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d0e8a25cbd23e76f843c75a86b7e15b", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-07-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d132d121aabc5235dd039dfc46aa024", "", "", "Basketball (208 in 1) (Unknown) (PAL) (Hack)", "Console ports are swapped", "Hack", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d25df9dc2cde746ceac48e834cf84a7", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "EAZ-033", "Space Shuttle (1983) (Activision) (SECAM)", "A Journey Into Space", "", "", "", "FE", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d2cc33ca798783dee435eb29debf6d6", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d7293f1892b66c014e8d222e06f6165", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a1]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d799bfa9e1e7b6224877162accada0d", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d8f1ab95362acdf3426d572a6301bf2", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ) (PAL)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d8fb14860c2f198472b233874f6b0c9", "", "", "Boing! (PD) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5d9592756425192ec621d2613d0e683d", "CCE", "C-839", "Misterious Thief, A (1983) (CCE) [a]", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5da8fd0b5ed33a360bff37f8b5d0cd58", "Tron", "", "Pole Position (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5dae540347cf0a559962d62604ecf750", "Canal 3 - Intellivision", "", "Freeway (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5db9e5bf663cad6bf159bc395f6ead53", "Goliath - Hot Shot", "83-212", "Time Race (1983) (Goliath) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5dccf215fdb9bbf5d4a6d0139e5e8bcb", "Froggo", "FG1009", "Sea Hunt (1987) (Froggo)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5de8803a59c36725888346fdc6e7429d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5df32450b9fbcaf43f9d83bd66bd5a81", "Eric Ball", "", "Atari Logo Playfield Demo (2001) (Eric Ball) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5df559a36347d8572f9a6e8075a31322", "Digivision", "", "Enduro (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5e0c37f534ab5ccc4661768e2ddf0162", "Telegames - VSS, Ed Salvo", "5667 A106", "Glacier Patrol (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5e1b4629426f4992cf3b2905a696e1a7", "Activision - Bobco, Robert C. Polaro", "AK-049-04", "Rampage! (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5e1b7a6078af428ef056fe85a37a95ca", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5e1cd11a6d41fc15cf4792257400a31e", "Philip R. Frey", "", "Return of Mario Bros (Philip R. Frey) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5e201d6bfc520424a28f129ee5e56835", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5e2495d43b981010304af55efed1e798", "Jone Yuan Telephonic Enterprise Co", "", "Math Gran Prix (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5e43c0391f7412ae64fae6f3742d6ee9", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.27)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" }, + { "5e99aa93d0acc741dcda8752c4e813ce", "", "", "2600 Digital Clock (V b2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5ec73ac7d2ac95ac9530c6d33e713d14", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (2 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5eeb81292992e057b290a5cd196f155d", "Wizard Video Games - VSS, Ed Salvo", "008", "Texas Chainsaw Massacre, The (1983) (Wizard Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5ef303b9f0aa8cf20720c560e5f9baa1", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f1b7d5fa73aa071ba0a3c2819511505", "CCE", "", "Cosmic Commuter (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f2b4c155949f01c06507fb32369d42a", "Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f316973ffd107f7ab9117e93f50e4bd", "", "", "Commando Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f39353f7c6925779b0169a87ff86f1e", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari) [a]", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f46d1ff6d7cdeb4b09c39d04dfd50a1", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f4ebf8a1e5f5f7b9ff3e3c6affff3e6", "Bit Corporation", "R320", "Donkey Kong (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f560837396387455c9dcb05cdd4b053", "Canal 3 - Intellivision", "", "Eggomania (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, + { "5f681403b1051a0822344f467b05a94d", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5f708ca39627697e859d1c53f8d8d7d2", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f73e7175474c1c22fb8030c3158e9b3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f786b67e05fb9985b77d4beb35e06ee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari) (PAL)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f7ae9a7f8d79a3b37e8fc841f65643a", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f7de62a408b9de3a1168898298fd31d", "", "", "Super Cobra (Genesis)", "Genesis controller (B is bomb, C is laser)", "Hack of Super Cobra", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5f950a2d1eb331a1276819520705df94", "20th Century Fox Video Games - Micro Computer Technologies, Jim Collas", "", "Heart Like a Wheel (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "5f9b62350b31be8bd270d9a241cbd50e", "Telegames", "5658 A088", "Football (1988) (Telegames) (PAL)", "AKA Super Challenge Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5faffe1c4c57430978dec5ced32b9f4a", "Dactari - Milmar", "", "Volleyball (Dactari - Milmar)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "5fb71cc60e293fe10a5023f11c734e55", "", "", "This Planet Sucks (Fix) (27-12-2002) (Greg Troutman)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "600d48eef5c0ec27db554b7328b3251c", "", "", "Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6015a9cef783e97e98a2aa2cf070ae06", "Thomas Jentzsch", "", "Battlezone TC (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Battlezone", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "60358edf0c2cc76b1e549e031e50e130", "Manuel Polik", "", "Cyber Goth Galaxian (Manuel Polik) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "603c7a0d12c935df5810f400f3971b67", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6041f400b45511aa3a69fab4b8fc8f41", "Apollo, Ban Tran", "AP-2010", "Wabbit (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "604e09724555807c28108049efe34a13", "", "", "Sokoban (01-01-2003) (Adam Wozniak)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6058e40ce79d7434c7f7477b29abd4a5", "", "", "Rubik's Cube Demo (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "605dcb73d22f4efdb90ef9da2f290f7c", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "605fd59bfef88901c8c4794193a4cbad", "Data Age", "", "Secret Agent (1983) (Data Age) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, + { "606c2c1753051e03c1f1ac096c9d2832", "Jone Yuan Telephonic Enterprise Co", "", "Crackpots (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6076b187a5d8ea7a2a05111c19b5d5cd", "", "", "Fu Kung! (V0.14) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "60a61da9b2f43dd7e13a5093ec41a53d", "VentureVision, Dan Oliver", "VV2001", "Rescue Terra I (1982) (VentureVision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "60bbd425cb7214ddb9f9a31948e91ecb", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "60cd61a2dfccb0e2736434f9792c1672", "Amiga - Video Soft, Frank Ellis, Jerry Lawson", "2110", "3-D Havoc (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "60d304582d33e2957b73eb300a7495bb", "", "", "Jam Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "60e0ea3cbe0913d39803477945e9e5ec", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "PADDLES_IAXDR", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "613abf596c304ef6dbd8f3351920c37a", "", "", "Boring Pac-Man (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6141c095d0aee4e734bebfaac939030a", "Rainbow Vision - Suntek", "SS-017", "Mariana (1983) (Rainbow Vision) (PAL)", "AKA Seaquest", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61426cee013306e7f7367534ab124747", "", "", "One Blue Bar Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "615a3bf251a38eb6638cdc7ffbde5480", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61621a556ad3228f0234f5feb3ab135c", "", "", "Fu Kung! (V0.05 Cuttle Card Compattle Revision) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61631c2f96221527e7da9802b4704f93", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision) [different logo]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61719a8bdafbd8dab3ca9ce7b171b9e2", "", "", "Enduro (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61728c6cfb052e62a9ed088c5bf407ba", "", "", "Sprite Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "619de46281eb2e0adbb98255732483b4", "", "", "Time Warp (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61baadddc2c8f6e5faa57d4d0f285462", "", "", "208-in-1 MDM-Test (PAL) (127 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "61dbe94f110f30ca4ec524ae5ce2d026", "CCE", "C-820", "Space Invaders (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61e0f5e1cc207e98704d0758c68df317", "Star Game", "007", "Tennis (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61ef8c2fc43be9a04fe13fdb79ff2bd9", "", "", "Gas Gauge Demo - Revisited (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6205855cc848d1f6c4551391b9bfa279", "", "", "Euchre (Release Candidate 2) (NTSC) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6238ac888871fec301d1b9fc4fc613c9", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "624e0a77f9ec67d628211aaf24d8aea6", "Panda", "108", "Sea Hawk (1983) (Panda)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "626d67918f4b5e3f961e4b2af2f41f1d", "Atari", "50008", "Diagnostic Test Cartridge 2.0 (1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6272f348a9a7f2d500a4006aa93e0d08", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "62899430338e0538ee93397867d85957", "Gameworld", "133-004", "Airlock (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "62921652f6634eb1a0940ed5489c7e18", "", "", "SCSIcide (V1.09) (2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" }, + { "62992392ea651a16aa724a92e4596ed6", "Eric Mooney", "", "Invaders by Erik Mooney (Beta) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "62d1f50219edf9a429a9f004c19f31b3", "JWDA, Todd Marshall", "", "Euro Gen (02-01-83) (JWDA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "62ee2b8f59e9cd6285bbdb674a952e8b", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype)", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "62f74a2736841191135514422b20382d", "", "", "Pharaoh's Curse (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "YES", "" }, + { "62ffd175cac3f781ef6e4870136a2520", "", "", "2600 Digital Clock (V x.xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63166867f75869a3592b7a94ea62d147", "", "", "Indy 500 (Hack) [a1]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" }, + { "6333ef5b5cbb77acd47f558c8b7a95d3", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (8K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6337927ad909aa739d6d0044699a916d", "Jeffry Johnston", "", "Radial Pong - Version 2 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6339d28c9a7f92054e70029eb0375837", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6342afe9c9ad1b6120b8f6fb040d0926", "", "", "Move a Blue Blob Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6354f9c7588a27109c66905b0405825b", "Thomas Jentzsch", "", "Amidar DS (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6358f7f8bf0483402a080efccf250d61", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (Prototype)", "AKA Termite", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "635cc7a0db33773959d739d04eff96c2", "", "", "Minesweeper (V.90) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6362396c8344eec3e86731a700b13abf", "Panda", "109", "Exocet (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "637efac676ff063f2fbb0abff77c4fa5", "", "", "Noize Maker Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63811ed69bdbc35c69d8aa7806c3d6e9", "Atari", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "638cc82ea96f67674595ba9ae05da6c6", "Rainbow Vision - Suntek", "SS-011", "Super Ferrari (1983) (Rainbow Vision) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63a6eda1da30446569ac76211d0f861c", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63a7445b1d3046d3cdcdbd488dca38d9", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63c5fef3208bb1424d26cf1ab984b40c", "", "", "Analog Clock (V0.1) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63c7395d412a3cd095ccdd9b5711f387", "Eric Ball", "ELB005", "Skeleton+ (PAL)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63d6247f35902ba32aa49e7660b0ecaa", "", "", "Space War (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63e42d576800086488679490a833e097", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63e783994df824caf289b69a084cbf3e", "David Marli", "", "Fat Albert (David Marli) (Hack)", "Hack of Fast Food", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "63e9e612bbee31045f8d184a4e53f8ec", "ATARITALIA", "", "Moby Blues (2002) (ATARITALIA) (Hack)", "Hack of Mario Bros", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "640a08e9ca019172d612df22a9190afb", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "64198bb6470c78ac24fcf13fe76ab28c", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "643e6451eb6b8ab793eb60ba9c02e000", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL) [different tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "645bf7f9146f0e4811ff9c7898f5cd93", "Xonox - K-Tel Software - VSS, Robert Weatherby", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6468d744be9984f2a39ca9285443a2b2", "Atari, Ed Logg, Carol Shaw", "CX26163P", "Reversi (32 in 1) (1988) (Atari) (PAL)", "AKA Othello", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "647162cceb550fd49820e2206d9ee7e8", "", "", "Skeleton (NTSC) (2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "64b8e19c767191ccdc97acc6904c397b", "Jeffry Johnston", "", "Radial Pong - Version 6 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "64ca518905311d2d9aeb56273f6caa04", "CCE", "", "Cubo Magico (CCE)", "AKA Cubicolor", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "64d43859258dc8ca54949e9ff4174202", "Thomas Jentzsch", "", "Lilly Adventure (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "64fab9d15df937915b1c392fc119b83b", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (05-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "650df778c6ce22d3fd1a7c33c565bcc3", "Atari - GCC, Betty Ryan Tylko, Douglas B. Macrae", "CX2694", "Pole Position (1983) (Atari)", "Genesis controller (B is high gear, C is low gear, left difficulty switch swaps gear buttons)", "Hack of Pole Position", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "651d2b6743a3a18b426bce2c881af212", "CCE", "C-812", "Pac Man (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6522717cfd75d1dba252cbde76992090", "Home Vision - Gem International Corp. - VDI", "VCS83102", "War 2000 (1983) (Home Vision) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6538e454b0498ad2befe1ef0f87815c0", "Joe Grand", "", "SCSIcide (v1.2) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" }, + { "65490d61922f3e3883ee1d583ce10855", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "65562f686b267b21b81c4dddc129d724", "", "", "Euchre (28-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "655c84e5b951258c9d20f0bf2b9d496d", "", "", "2600_2003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "656dc247db2871766dffd978c71da80c", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1981) (Sears)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, + { "6588d192d9a8afce27b44271a2072325", "Bit Corporation", "R320", "Basketball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "65917ae29a8c9785bb1f2acb0d6aafd0", "", "", "Junkosoft One Year Demo (1999) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6596b3737ae4b976e4aadb68d836c5c7", "Digivision", "", "Defender (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "659a20019de4a23c748ec2292ea5f221", "Retroactive", "", "Qb (V2.05) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "65a6f1255fe22468a8bf84ff28a4d289", "Akor", "", "Super TV Boy (1995) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "65b106eba3e45f3dab72ea907f39f8b4", "Christian Software Development - HomeComputer Software, Dan Schafer, Glenn Stohel, Jon Tedesco - Sparrow", "GCG 1001T", "Music Machine, The (1983) (Sparrow)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "65ba1a4c643d1ab44481bdddeb403827", "Quelle", "876.013 4", "Katastrophen-Einsatz (1983) (Quelle) (PAL)", "AKA M.A.S.H.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "65bd29e8ab1b847309775b0de6b2e4fe", "Coleco, Ed English", "2667", "Roc 'n Rope (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "65c6406f5af934590097c8c032ebb482", "", "", "Three Hugger (Pave Demo) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6604f72a966ca6b2df6a94ee4a68eb82", "", "", "MegaMania (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "662eca7e3d89175ba0802e8e3425dedb", "", "", "Hangman Pac-Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66362890eb78d6ea65301592cce65f5b", "", "", "Euchre (13-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "663ef22eb399504d5204c543b8a86bcd", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "4L1720, 4L1721, 4L1722, 4L2276", "Wizard of Wor (1982) (CBS Electronics) (PAL)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "664d9bfda6f32511f6b4aa0159fd87f5", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6651e2791d38edc02c5a5fd7b47a1627", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (04-05-1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "665b8f8ead0eef220ed53886fbd61ec9", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66706459e62514d0c39c3797cbf73ff1", "Video Gems", "VG-05", "Treasure Below (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6672de8f82c4f7b8f7f1ef8b6b4f614d", "Videospielkassette - Ariola", "PGP237", "Angeln I (Ariola) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "667a70b028f581d87648693b873bc962", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "668dc528b7ea9345140f4fcfbecf7066", "Gakken", "001", "Pooyan (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6697f177847c70505824422e76aad586", "", "", "Tennis (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "669840b0411bfbab5c05b786947d55d4", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66b89ba44e7ae0b51f9ef000ebba1eb7", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (01-18-1983) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66b92ede655b73b402ecd1f4d8cd9c50", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66bc1bef269ea59033928bac2d1d81e6", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "66c2380c71709efa7b166621e5bb4558", "Parker Brothers, Dave Engman, Dawn Stockbridge", "931509", "Tutankham (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66c4e0298d4120df333bc2f3e163657e", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66f49b3248791b9803fa3e2f4165d072", "Bit Corporation", "R320", "Football (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "66fcf7643d554f5e15d4d06bab59fe70", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6706a00f9635508cfeda20639156e66e", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "672012d40336b403edea4a98ce70c76d", "", "", "Spider Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "675ae9c23fa1aae376cea86cad96f9a5", "", "", "Poker Squares (V0.25) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "67631ea5cfe44066a1e76ddcb6bcb512", "", "", "Termool (Unknown) (PAL)", "AKA Turmoil", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "67684a1d18c85ffa5d82dab48fd1cb51", "Tigervision, Warren Schwader - Teldec", "7-003", "Threshold (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "678c1d71a1616d9d022f03d8545b64bb", "", "", "Demo Image Series #11 - Donald And Mario (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "67931b0d37dc99af250dd06f1c095e8d", "CommaVid, Irwin Gaines", "CM-004", "Room of Doom (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "679d30c7886b283cbe1db4e7dbe5f2a6", "Colin Hughes", "", "Puzzle (Colin Hughes) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "679e910b27406c6a2072f9569ae35fc8", "Data Age", "DA1002", "Warplock (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 40", "", "", "YES", "" }, + { "67bd3d4dc5ac6a42a99950b4245bdc81", "Retroactive", "", "Qb (2.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "67c05ae94bf8b83a666c3ae2c4bc14de", "Atari", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "67cdde4176e0447fc45a71e0a1cdd288", "Telegames - VSS, Ed Salvo", "5665 A016", "Glacier Patrol (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "67ce6cdf788d324935fd317d064ed842", "Retroactive", "", "Qb (V2.09) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "67cf913d1df0bf2d7ae668060d0b6694", "", "", "Hangman Monkey 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "67f90d74fd0b72fdc6d9b92436780ea9", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6803fa7c2c094b428b859a58dc1dd06a", "Retroactive", "", "Qb (0.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6805734a0b7bcc8925d9305b071bf147", "Bit Corporation", "PGP229", "Kung Fu (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Karate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "681206a6bde73e71c19743607e96c4bb", "", "", "Casino (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6833c26f385e866f3a0fa0dff311216e", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "683bb0d0f0c5df58557fba9dffc32c40", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "683dc64ef7316c13ba04ee4398e2b93a", "Ed Federmeyer", "", "Edtris (1995) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "68449e4aaba677abcd7cde4264e02168", "", "", "Horizonal Color Bars Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6847ce70819b74febcfd03e99610243b", "", "", "Ruby Runner 4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "68489e60268a5e6e052bad9c62681635", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "68597264c8e57ada93be3a5be4565096", "Data Age", "DA1005", "Bugs (1982) (Data Age)", "Uses the Paddle Controllers", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, + { "685e9668dc270b6deeb9cfbfd4d633c3", "CommaVid, Irwin Gaines - Ariola", "CM-004 - 712 004-720", "Room of Doom (1982) (CommaVid) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "68760b82fc5dcf3fedf84376a4944bf9", "CCE", "C-860", "Laser Gate (1983) (CCE)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "687c23224e26f81c56e431c24faea36d", "", "", "Qb (Simple Background Animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "68878250e106eb6c7754bc2519d780a0", "CCE", "C-809", "Squirrel (1983) (CCE)", "AKA Snail Against Squirrel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "68ac69b8e1ba83af8792f693f5ae7783", "Digivision", "", "Fathon (Digivision)", "AKA Fathom", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "68c80e7e1d30df98a0cf67ecbf39cc67", "Hozer Video Games", "", "Gunfight 2600 - One Step Forward & Two Steps Back (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "68c938a2a2b45c37db50509f1037fe6e", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "68cd2adc6b1fc9a1f263ab4561112f30", "Thomas Jentzsch", "", "Boulderdash Demo (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "68feb6d6ff63e80df1302d8547979aec", "", "", "Starfield Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "690a6049db78b9400c13521646708e9c", "King Tripod Enterprise Co.", "SS - 007", "Space Raid (King Tripod) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6913c90002636c1487538d4004f7cac2", "Atari - CCW", "CX26131", "Monster Cise (1984) (Atari) (Prototype)", "Uses the Keypad Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "691d67910b08b63de8631901d1887c1f", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "692202772d8b38ccf85a90c8003a1324", "", "", "Zi - The Flie Buster (2002) (Fernando Mora) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "693137592a7f5ccc9baae2d1041b7a85", "", "", "Qb (V2.02) (Stella) (2001) (Retroactive) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6936aa6763835f62ac13d1aaa79b9f91", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6979f30204149be3e227558cffe21c1d", "Atari", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6982854657a2cc87d712f718e402bf85", "Zellers", "", "Earth Attack (Zellers)", "AKA Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "69877da5caded48315e3e45882a303d5", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "698f569eab5a9906eec3bc7c6b3e0980", "SpkLeader", "", "Demons! (2003) (SpkLeader) (Hack)", "Hack of Phoenix", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "69974dd5d6420b90898cde50aec5ef39", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "69df0411d4d176e558017f961f5c5849", "CCE", "C-831", "Cosmic Ark (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "69e79b1352b9ee1754bbe63b4a7062c3", "Barry Laws Jr.", "", "Pink Floyd - The Wall (2003) (Barry Laws Jr.) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "69ebf910ab9b63e5b8345f016095003b", "", "", "Maze Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "69edfb4e1810a523311b3e250fc1e275", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "69fac82cd2312dd9ce5d90e22e2f070a", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a03c28d505bab710bf20b954e14d521", "", "", "Pressure Gauge 2 Beta (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a07836c382195dd5305ce61d992aaa6", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo) (Prototype)", "Uses the Paddle Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "6a091b8ffeacd0939850da2094b51564", "", "", "Vertically Scrolling Playfield (02-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a222c26bcece3a510ddda21398f72c6", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a2c68f7a77736ba02c0f21a6ba0985b", "Atari, Larry Wagner, Bob Whitehead", "", "Computer Chess (07-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a3b0c33cf74b1e213a629e3c142b73c", "Cody Pittman", "", "Cory The Interviewer (Cody Pittman) (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a76d5f0ed721639474aa9bbde69ebf0", "", "", "Play Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6a82b8ecc663f371b19076d99f46c598", "Activision, Larry Miller - Ariola", "EAX-026, EAX-026-04B, EAX-026-04I - 711 026-725", "Enduro (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a882fb1413912d2ce5cf5fa62cf3875", "Video Game Cartridge - Ariola", "TP-605", "Dragon Defender (Ariola) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6a8c6940d3be6fd01274363c4d4b298e", "", "", "Spy Hunter (Genesis)", "Genesis controller (C is oil/smoke)", "Hack of Spy Hunter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a9b30ca46b0dba9e719f4cbd340e01c", "", "", "Frostbite (Unknown) (PAL) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6a9e0c72fab92df70084eccd9061fdbd", "CCE", "C-835", "Beany Bopper (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6aa66e9c3eea76a0c40ef05513497c40", "", "", "Hangman Ghost Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6ac3fd31a51730358708c7fdc62487f8", "Matthias Jaap", "", "PC Invaders (Matthias Jaap) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6aca52e11b597ab84b33d5252e1cd9d1", "Bit Corporation", "R320", "Tac-Scan (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, + { "6ae4dc6d7351dacd1012749ca82f9a56", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125, CX26127", "Track and Field (1984) (Atari)", "Uses the Track & Field Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b01a519b413f8cfa2f399f4d2841b42", "", "", "Aphex Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b1fc959e28bd71aed7b89014574bdc2", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b4eb5b3df80995b8d9117cb7e9aeb3c", "Gameworld, J. Ray Dettling", "133-006", "Journey Escape (1983) (Gameworld) (PAL)", "AKA Rock 'n' Roll Escape", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6b683be69f92958abe0e2a9945157ad5", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Steven B. Sidley, Tom Sloper", "VC2007", "Entombed (1983) (U.S. Games)", "Released as Name That Game for a contest (winning name was Entombed)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6b6ca32228ae352b4267e4bd2cddf10c", "", "", "Pac-Man 4 (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b71f20c857574b732e7a8e840bd3cb2", "", "", "Frostbite (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b72b691ea86f61438ed0d84c4d711de", "", "", "Fishing Derby (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b75f8fa4fd011a6698c58315f83d2ac", "Thomas Jentzsch", "", "Sprintmaster DC (TJ)", "Uses the Driving Controllers, Hack of Sprintmaster (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" }, + { "6b7a56b6ac2ca4bf9254474bf6ed7d80", "", "", "Horizonal Color Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b7e1c11448c4d3f28160d2de884ebc8", "Zirok", "", "Fast Food (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6b8fb021bb2e1f1e9bd7ee57f2a8e709", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum) (PD) [a]", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6bb09bc915a7411fe160d0b2e4d66047", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6bb22efa892b89b69b9bf5ea547e62b8", "Dynacom", "", "Megamania (1982) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6bde3f6ac31aceef447ce57d4d2c2ec0", "Piero Cavina", "", "Mondo Pong V1 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "6c128bc950fcbdbcaf0d99935da70156", "Digitel", "", "Volleyball (1983) (Digitel)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6c1553ca90b413bf762dfc65f2b881c7", "Quelle", "343.073 3", "Winterjagd (1983) (Quelle) (PAL)", "AKA Ski Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6c1f3f2e359dbf55df462ccbcdd2f6bf", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6c25f58fd184632ca76020f589bb3767", "Dynacom", "", "Beat 'Em & Eat 'Em (1983) (Dynacom)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "6c449db9bbbd90972ad1932d6af87330", "", "", "20 Sprites at Once Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6c658b52d03e01828b9d2d4718a998ac", "", "", "Hangman Invader Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6c76fe09aa8b39ee52035e0da6d0808b", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, + { "6c85098518d3f94f7622c42fd1d819ac", "Suntek", "SS-028", "Firebug (1983) (Suntek) (PAL)", "AKA Spinning Fireball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6c91ac51421cb9fc72c9833c4f440d65", "ITT Family Games", "554-33 375", "Cosmic Town (1983) (ITT Family Games) (PAL)", "AKA Base Attack (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6c9a32ad83bcfde3774536e52be1cce7", "", "", "Space Treat (NTSC) (13-08-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6cab04277e7cd552a3e40b3c0e6e1e3d", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (Prototype)", "AKA Targ", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6cbe945e16d9f827d0d295546ac11b22", "", "", "Gunfight 2600 - AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6ccd8ca17a0e4429b446cdcb66327bf1", "", "", "RPG Engine (12-05-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6cd1dc960e3e8d5c5e0fbe67ab49087a", "", "", "Vertical Playfield Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6cd506509e8fd5627f55603780e862a8", "Greg Troutman", "", "Dark Mage (SuperCharger) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6ce2110ac5dd89ab398d9452891752ab", "Funvision - Fund. International Co.", "", "Persian Gulf War (Funvision)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6cea35ded079863a846159c3a1101cc7", "", "", "Atlantis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6ceb7d6a54e9a5e62d26874d1cc88dbc", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6cf054cd23a02e09298d2c6f787eb21d", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6d218dafbf5a691045cdc1f67ceb6a8f", "Robin Harbron", "", "6 Digit Score Display (1998) (Robin Harbron) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6d475019ea30d0b29f695e9dcfd8f730", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 2) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6d74ebaba914a5cfc868de9dd1a5c434", "", "", "Fortress (Smooth Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6d842c96d5a01967be9680080dd5be54", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6d8a04ee15951480cb7c466e5951eee0", "Zirok", "", "Kanguru (1983) (Zirok)", "AKA Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6d9afd70e9369c2a6bff96c4964413b7", "", "", "Time Warp (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6dda84fb8e442ecf34241ac0d1d91d69", "Atari - GCC, Douglas B. Macrae", "CX2677", "Dig Dug (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6de924c2297c8733524952448d54a33c", "CCE", "C-1006", "Moon Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6dfad2dd2c7c16ac0fa257b6ce0be2f0", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6e179eee3d4631a7434d40cf7aeea6e8", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6e19428387686a77d8c8d2f731cb09e0", "", "", "Purple Cross Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6e372f076fb9586aff416144f5cfe1cb", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6e59dd52f88c00d5060eac56c1a0b0d3", "Atari, Bob Smith", "CX2648", "Video Pinball (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6e5d5ba193d2540aec2e847aafb2a5fb", "Retroactive", "", "Qb (2.14) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6e7ed74082f39ad4166c823765a59909", "", "", "Poker Squares (V0.14) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6e7efb0ed13ec28a00d19572de9c9f03", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6eb10fd23c7161751d18b9e8484c0004", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco) (Prototype)", "AKA Smurf, Smurf Action", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6ed5012793f5ddf4353a48c11ea9b8d3", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "01 70", "", "", "", "" }, + { "6ed6bda5c42b2eb7a21c54e5b3ace3e3", "Canal 3 - Intellivision", "", "Ice Hockey (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6efe876168e2d45d4719b6a61355e5fe", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6f084daf265599f65422ef4173b69bc7", "", "", "Music Kit (V2.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6f2aaffaaf53d23a28bf6677b86ac0e3", "U.S. Games Corporation - Vidtec - JWDA, Garry Kitchen", "VC1001", "Space Jockey (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6f3e3306da2aa6e74a5e046ff43bf028", "", "", "Defender Arcade (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6f744f14aac04f7e1ea0d3f4bafcb3e4", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a3]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6f74ed915ffe73b524ef0f63819e2a1d", "Eckhard Stolberg", "", "An Exercise In Minimalism (V2) (1999) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6fa0ac6943e33637d8e77df14962fbfc", "Imagic, Rob Fulop", "", "Cubicolor (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6fac680fc9a72e0e54255567c72afe34", "", "", "Superman (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6fbd05b0ad65b2a261fa154b34328a7f", "", "", "Boardgame Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6fc0176ccf53d7bce249aeb56d59d414", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6fc27a9233fc69d28d3f190b4ff80f03", "", "", "UFO #6 (Charles Morgan) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6fc394dbf21cf541a60e3b3631b817f1", "Imagic, Bob Smith", "720020-2A, IA3611P", "Dragonfire (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "6fd7c7057eeab273b29c7aafc7429a96", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6fe67f525c39200a798985e419431805", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "6ff4156d10b357f61f09820d03c0f852", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 60", "", "", "", "" }, + { "6ffc95108e5add6f9b8abcaf330be835", "Charles Morgan", "", "TP Bug (Charles Morgan) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "700a786471c8a91ec09e2f8e47f14a04", "Activision", "", "Hard-Head (1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "703d32062436e4c20c48313dff30e257", "", "", "Moving Maze Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "703f0f7af350b0fa29dfe5fbf45d0d75", "Bit Corporation", "P460", "4 Game in One Dark Green (1983) (BitCorp) (PAL)", "Rodeo Champ, Bobby is Going Home, Open Sesame, Festival", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "705fe719179e65b0af328644f3a04900", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "706e3cc4931f984447213b92d1417aff", "", "", "Joustpong (06-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "707ecd80030e85751ef311ced66220bc", "", "", "Double-Height 6-Digit Score Display (Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7096a198531d3f16a99d518ac0d7519a", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "709910c2e83361bc4bf8cd0c20c34fbf", "Rainbow Vision - Suntek", "SS-006", "Netmaker (1983) (Rainbow Vision) (PAL)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "70a43fbdb1c039283ee5048d99842469", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "70a8480cfaf08776e5420365732159d2", "Rob Kudla", "", "Horizontally Scrolling Playfield Thing (Rob Kudla) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "70ce036e59be92821c4c7fd735ec6f68", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "70d14c66c319683b4c19abbe0e3db57c", "", "", "Oystron (V2.82) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "710497df2caab69cdcc45e919c69e13f", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "713fde2af865b6ec464dfd72e2ebb83e", "", "", "Challenge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "71464c54da46adae9447926fdbfc1abe", "M Network - INTV - APh Technological Consulting, Bruce Pedersen", "MT5663", "Lock 'n' Chase (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "714e13c08508ee9a7785ceac908ae831", "Home Vision - Gem International Corp. - VDI", "VCS83123", "Parachute (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "715dbf2e39ba8a52c5fe5cdd927b37e0", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "715dd9e0240638d441a3add49316c018", "Atari", "", "128-in-1 Junior Console (Chip 2 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7187118674ff3c0bb932e049d9dbb379", "Zirok", "", "Keystone Keypers (1983) (Zirok)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "718ae62c70af4e5fd8e932fee216948a", "Data Age, J. Ray Dettling", "112-006", "Journey Escape (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "718ee85ea7ec27d5bea60d11f6d40030", "Thomas Jentzsch", "", "Ghostbusters II (1992) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7197b6cbde6ecd10376155e6b848e80d", "Piero Cavina", "", "Multi-Sprite Game V2.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "71b193f46c88fb234329855452dfac5b", "Digitel", "", "Atlantis (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "71d005b60cf6e608d04efb99a37362c3", "Atari, Larry Kaplan", "CX2643", "Codebreaker (1978) (Atari) (PAL) (4K) [a]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "71f09f128e76eb14e244be8f44848759", "Funvision - Fund. International Co.", "", "Time Race (Funvision) (PAL)", "AKA Time Warp", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "71f8bacfbdca019113f3f0801849057e", "Atari, Dan Hitchens", "CX26126", "Elevator Action (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72097e9dc366900ba2da73a47e3e80f5", "", "", "Euchre (15-06-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "721a5567f76856f6b50a6707aa8f8316", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72305c997f2cec414fe6f8c946172f83", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "724613effaf7743cbcd695fab469c2a8", "", "", "Super-Ferrari (Unknown)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "728152f5ae6fdd0d3a9b88709bee6c7a", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72876fd7c7435f41d571f1101fc456ea", "Quelle", "688.383 9", "Die Ente und der Wolf (1983) (Quelle) (PAL)", "AKA Pooyan", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72a46e0c21f825518b7261c267ab886e", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72a5b5052272ac785fa076709d16cef4", "", "", "KC Munckin (29-01-2003) (J. Parlee)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72a63bcb5eb31bd0fd5e98ed05125ec1", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72bda70c75dfa2365b3f8894bace9e6a", "Thomas Jentzsch", "", "Atlantis (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72d0acb5de0db662de0360a6fc59334d", "", "", "Cosmic Ark (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72db1194b1cc7d45b242f25eb1c148d3", "", "", "Pac-Man (1981) (Atari) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72fd08deed1d6195942e0c6f392e9848", "HES", "0701-406", "2 Pak Special - Wall Defender, Planet Patrol (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "72ffbef6504b75e69ee1045af9075f66", "Atari, Richard Maurer - Sears", "CX2632 - 49-75153", "Space Invaders (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73158ea51d77bf521e1369311d26c27b", "Zellers", "", "Challenge (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73521c6b9fed6a243d9b7b161a0fb793", "Atari, Tom Reuterdahl", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "736388d73198552d77d423962000006f", "Dactari", "", "Tennis (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73a710e621d44e97039d640071908aef", "", "", "Barber Pole Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73aa02458b413091ac940c0489301710", "Rainbow Vision - Suntek", "SS-016", "Boom Bang (1983) (Rainbow Vision) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73b4e8f8b04515d91937510e680214bc", "", "", "Rubik's Cube Demo 3 (24-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73c545db2afd5783d37c46004e4024c2", "CBS Electronics - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf - Schtroumpfs (1983) (CBS Electronics) (PAL)", "Pitufo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73c839aff6a055643044d2ce16b3aaf7", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73cb1f1666f3fd30b52b4f3d760c928f", "", "", "Mines of Minos (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "73e66e82ac22b305eb4d9578e866236e", "Jone Yuan Telephonic Enterprise Co", "", "Unknown Datatech Game (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "73efa9f3cbe197f26e0fb87132829232", "CCE", "C-858", "Tennis (1983) (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "74023e0f2e739fc5a9ba7caaeeee8b6b", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "740a7fa80f52cc7287ba37677afb6b21", "", "", "Double Dragon (PAL) (Genesis)", "Genesis controller (C is jumpkick)", "Hack of Double Dragon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "740b47df422372fbef700b42cea4e0bf", "", "", "Dizzy Wiz (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "740f39e71104e90416c29a73560b9c6b", "Atari", "TE016643", "Diagnostic Test Cartridge 2.6P (1982) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7412f6788087d7e912c33ba03b36dd1b", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "742de93b8d849220f266b627fbabba82", "", "", "SCSIcide (25-02-2001) (Chris Wilkson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7450ae4e10ba8380c55b259d7c2b13e8", "", "", "Register Twiddler Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7454786af7126ccc7a0c31fcf5af40f1", "", "", "Phantom Tank (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7465b06b6e25a4a6c6d77d02242af6d6", "Atari", "CX26193", "8 in 1 (01-16-92) (Atari) (Prototype)", "Game 2 is Centipede, but doesn't work", "Prototype", "", "", "8IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7481f0771bff13885b2ff2570cf90d7b", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "749fec9918160921576f850b2375b516", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "74d072e8a34560c36cacbc57b2462360", "Sancho - Tang's Electronic Co.", "TEC002", "Seahawk (1982) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "74ebaca101cc428cf219f15dda84b6f8", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "74f623833429d35341b7a84bc09793c0", "Zellers", "", "Radar (Zellers)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75028162bfc4cc8e74b04e320f9e6a3f", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (02-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7511c34518a9a124ea773f5b0b5c9a48", "", "", "Donkey Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75169c08b56e4e6c36681e599c4d8cc5", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network)", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "YES", "", "", "AUTO 55", "", "", "", "" }, + { "752da1c0acd7d132ccfb0b1067f53cf6", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "753375d183c713cfa0aa7298d1f3067b", "Arcadia Corporation, Steve Hales, Stephen Harland Landrum", "AR-4102", "Suicide Mission (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7550b821ee56fb5833dca2be88622d5a", "", "", "Multiple Moving Objects Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75511bb694662301c9e71df645f4b5a7", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "755fed16b48e81de05130708a905d00d", "SnailSoft", "", "Comitoid beta 3 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "756ca07a65a4fbbedeb5f0ddfc04d0be", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7574480ae2ab0d282c887e9015fdb54c", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7576dd46c2f8d8ab159d97e3a3f2052f", "Goliath - Hot Shot", "83-112", "Time Machine (1983) (Goliath) (PAL)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "757f529026696e13838364dea382a4ed", "Activision, David Crane - Ariola", "EAX-014, PAX-014, EAX-014-04B, EAX-014-04I - 711 014-720", "Grand Prix (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75893a9dc5de4b91cc426959b82a1da0", "Champ Games", "CG-02-P", "Conquest Of Mars (2010) (PAL60)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75a303fd46ad12457ed8e853016815a0", "ZiMAG - Emag - Vidco", "715-111 - GN-060", "Immies & Aggies (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75b22fdf632d76e246433db1ebccd3c4", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75b557be7f08db84ec5b242207b9f241", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75e276ba12dc4504659481c31345703a", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75e8d8b9e9c5c67c2226dbfd77dcfa7d", "", "", "2600 Digital Clock (V b1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75ea128ba96ac6db8edf54b071027c4e", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "75ea60884c05ba496473c23a58edf12f", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) (PAL) [a]", "ROM must be started in bank 0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "75ee371ccfc4f43e7d9b8f24e1266b55", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (11-09-1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7608abdfd9b26f4a0ecec18b232bea54", "Atari, Bob Whitehead", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7623a639a6fffdb246775fe2eabc8d01", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7628d3cadeee0fd2e41e68b3b8fbe229", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7648e72a5b5899076688df18a1ddcf72", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) (Prototype)", "Black Box", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "764ce6801f28a9ad36f11de3e57c053b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "76809eb1ee0db8a318308a5cdda0f4e2", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "769ddc995dbb9edb8167efcea9f34a7c", "", "", "H.E.R.O. (Genesis)", "Genesis controller (B is laser, C is dynamite)", "Hack of H.E.R.0.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "76a9bf05a6de8418a3ebc7fc254b71b4", "VideoSoft, Jerry Lawson, Dan McElroy", "VS1008", "Color Bar Generator (1984) (VideoSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "76c685d1a60c0107aa54a772113a2972", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "76c88341017eae660efc6e49c4b6ab40", "", "", "Indiana Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "76ee917d817ef9a654bc4783e0273ac4", "Otto Versand", "311377", "Fox & Goat (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Nuts", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "76f53abbbf39a0063f24036d6ee0968a", "M Network, David Akers, Joe 'Ferreira' King, Patricia Lewis Du Long, Jeff Ratcliff - INTV", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "76f66ce3b83d7a104a899b4b3354a2f2", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "77057d9d14b99e465ea9e29783af0ae3", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision)", "AKA Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7732e4e4cc2644f163d6650ddcc9d9df", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7761418d46af069b8cd80c29fe6cd814", "Dion Olsthoorn", "RetroN 77 edition", "Amoeba Jump (R77) (DionoiD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7778ac65d775a079f537e97cbdad541c", "", "", "Spider Fighter (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "777aece98d7373998ffb8bc0b5eff1a2", "", "", "2600 Collison Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "77887e4192a6b0a781530e6cf9be7199", "Atari", "CX2604", "Space War (1978) (Atari) [b1]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "77be57d872e3f5b7ecf8d19d97f73281", "", "", "Basketball (208 in 1) (Unknown) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "77cd9a9dd810ce8042bdb9d40e256dfe", "Kyle Pittman", "", "Evil Dead (2003) (Kyle Pittman) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "77d0a577636e1c9212aeccde9d0baa4b", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "PADDLES_IAXDR", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "78297db7f416af3052dd793b53ff014e", "", "", "Poker Squares (V0.17) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7836794b79e8060c2b8326a2db74eef0", "", "", "RIOT RAM Test (26-11-2002) (Dennis Debro)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "784176346e9422733d55c427230e5bad", "Activision, Alex DeMeo", "", "Title Match Pro Wrestling (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "784abfdb31d5341e5bd404d8d2a71c3b", "Alessandro Ciceri", "", "MagiCard (TV format conversion) (alex_79) (PAL)", "MagiCard PAL conversion hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7860716fa5dbc0fffab93fb9a4cb4132", "", "", "Hangman Monkey Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7867ee819b53d69cfcfe740f7ddca574", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "787ebc2609a31eb5c57c4a18837d1aee", "Prescott", "", "Vault Assault (19xx) (Prescott)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "78821ef76ebc3934850d1bc1b9e4f4b0", "HES - Activision", "542", "Hot Action Pak - Ghostbusters, Tennis, Plaque Attack (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "78963290052fd17c6c7998305ab3a6a0", "", "", "Push (V0.08) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "78b84cfb1c57b0488d674d2374e656e6", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "78c2de58e42cd1faac2ea7df783eaeb3", "", "", "Fu Kung! (V0.07) (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "79004f84bdeee78d142e445057883169", "CCE", "C-830", "Planet Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "791bc8aceb6b0f4d9990d6062b30adfa", "Activision, David Crane - Ariola", "EAX-018, EAX-018-04B, EAX-018-04I - 711 018-725", "Pitfall! (1982) (Activision) (PAL)", "Abenteuer im Urwald (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "791c88eca9836af8c34bf32b07cb58a7", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2 (PAL60)", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7926083ad423ed685de3b3a04a914315", "Barry Laws Jr.", "", "Face Invaders 2 (Barry Laws Jr.) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "792b1d93eb1d8045260c840b0688ec8f", "Kroko", "", "3E Bankswitch Test (TIA @ $00)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7972e5101fa548b952d852db24ad6060", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "798b8921276eec9e332dfcb47a2dbb17", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "798cc114f1623c14085868cd3494fe8e", "", "", "Pins Revenge (Atari Freak 1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7991e1797e5e9f311fd957e62d889dff", "Joe Grand", "", "SCSIcide (v1.1) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" }, + { "7996b8d07462a19259baa4c811c2b4b4", "", "", "Math Gran Prix (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "79ab4123a83dc11d468fb2108ea09e2e", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "AZ-037-04", "Beamrider (1984) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "79b649fb812c50b4347d12e7ddbb8400", "", "", "Red Pong Number 2 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "79c27f90591e3fdc7d2ed020ecbedeb3", "CCE", "C-815", "Seaquest (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "79d4af56036ec28f298cad964a2e2494", "", "", "Hangman Pac-Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "79d6f61da3c64688ac8e075667f8a39f", "", "", "Tie-Fighters (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "79e5338dbfa6b64008bb0d72a3179d3c", "M Network - INTV, David Akers, Patricia Lewis Du Long", "MT4313", "Star Strike (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "79fcdee6d71f23f6cf3d01258236c3b9", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a09299f473105ae1ef3ad6f9f2cd807", "Atari, Steve Wright", "CX2616P", "Pele's Soccer (1981) (Atari) (PAL)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a2af383014f5d810ad26d322823549d", "", "", "FlickerSort Demo (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a5463545dfb2dcfdafa6074b2f2c15e", "20th Century Fox Video Games - Sirius Software, Mark Turmell", "11007", "Turmoil (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a63d7ea3f2851bcf04f0bb4ba1a3929", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a64a8b727c8215d945e37d565ca95a5", "Atari, Warren Robinett", "CX2606", "Slot Racers (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a64b5a6e90619c6aacf244cdd7502f8", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 1) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a7f6ab9215a3a6b5940b8737f116359", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7a93d0c029eaa72236523eedc3f19645", "", "", "20 Sprites at Once Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ab0917107b6ec768a5ebaadf28c497a", "", "", "Santa's Helper (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "7ab210f448de518fa61a5924120ba872", "", "", "Fortress (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ab2f190d4e59e8742e76a6e870b567e", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 65", "", "", "", "" }, + { "7ac4f4fb425db38288fa07fb8ff4b21d", "Goliath", "83-213", "Space Eagle (1983) (Goliath) (PAL)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ad257833190bc60277c1ca475057051", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7ad782952e5147b88b65a25cadcdf9e0", "Imagic, Dave Johnson", "720119-1A, 03211", "Kwibble (1983) (Imagic) (Prototype)", "AKA Quick Step! Beta", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7adbcf78399b19596671edbffc3d34aa", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7af40c1485ce9f29b1a7b069a2eb04a7", "Amiga - Video Soft", "3120", "Mogul Maniac (1983) (Amiga)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b24bfe1b61864e758ada1fe9adaa098", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b33407b2b198af74906b936ce1eecbb", "King Atari", "", "Ghostbuster 2 (King Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7b3cf0256e1fa0fdc538caf3d5d86337", "CommaVid, Joseph Biel", "CM-009", "Stronghold (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b43c32e3d4ff5932f39afcb4c551627", "Syncro, Daniel Wolf", "", "Kamikaze Saucers (1983) (Syncro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b4be337ac4d73eda75c848355f6f480", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b5207e68ee85b16998bea861987c690", "Atari, Carol Shaw", "CX26163P", "3-D Tic-Tac-Toe (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b57318c489ff178f7ff500da1ec9e8c", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b6f3348dbf71ada88db0fdaf7feefe0", "", "", "3-D Corridor (Pink Spiral) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b79beb378d1b4471def90ceccf413de", "", "", "Pitfall Cupcake (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b7b4ac05232490c28f9b680c72998f9", "Zellers", "", "Freeway (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b8a481e0c5aa78150b5555dff01f64e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7b938c7ddf18e8362949b62c7eaa660a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ba07d4ea18bf3b3245c374d8720ad30", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7bb286cb659d146af3966d699b51f509", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (04-03-1989) (Atari) (Prototype)", "AKA Saving Mary", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7bc4fd254ec8c0a25a13f02fd3f762ff", "Retroactive", "", "Qb (V1.00) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7c00e7a205d3fda98eb20da7c9c50a55", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo)", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7c4a499d343fca0cef2d59dd16af621a", "", "", "Poker Card Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7c757bb151269b2a626c907a22f5dae7", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7c7a4a2d505c2d0c75337c44711d8d54", "Atari, Warren Robinett", "", "Elf Adventure (04-22-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7c9b3b8b25acf2fe3b8da834f69629c6", "", "", "I Robot (1984) (Atari) (Prototype) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ca7a471d70305c673fedd08174a81e8", "Tim Snider", "", "Venture II (2001) (Tim Snider)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7cc77f6745e1f2b20df4a4327d350545", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ccf350354ee15cd9b85564a2014b08c", "", "", "Big Dig (13-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7cd379da92c93679f3b6d2548617746a", "", "", "Demo Image Series #5 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7cd900e9eccbb240fe9c37fa28f917b5", "Jone Yuan Telephonic Enterprise Co", "", "Bi! Bi! (Jone Yuan) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ced6709f091e79a2ab9575d3516a4ac", "Activision, Steve Cartwright - Ariola", "EAX-027 - 711 027-722", "Plaque Attack (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7cedffa0db65d610568b90aeca705ac6", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7cf3a9267cdb95aba91abc5838d61cc5", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d0b49ea4fe3a5f1e119a6d14843db17", "Gameworld, J. Ray Dettling", "133-008", "Frankenstein's Monster (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d1034bcb38c9b746ea2c0ae37d9dff2", "Atari, Brad Stewart", "", "Morse Code Tutor (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d3cdde63b16fa637c4484e716839c94", "CCE", "", "Road Runner (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d483b702c44ee65cd2df22cbcc8b7ed", "Atari, Warren Robinett", "", "Elf Adventure (05-25-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d5c3b7b908752b98e30690e2a3322c2", "Dactari - Milmar", "", "Freeway (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d726fa494f706784bafeb1b50d87f23", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-27-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d8287e8423a56d4f8cef10435d97179", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d903411807704e725cf3fafbeb97255", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (Reaction) (1982) (Imagic) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d93071b3e3616093a6b5a98b0315751", "", "", "Gunfight 2600 - Music & Bugfixes 2 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d940d749e55b96b7b746519fa06f2de", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7d9c96b215d1941e87b6fb412eb9204f", "", "", "Othello (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7da9de8d62fcdd3a2c545b2e720c2a61", "CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7dbc8fa2e488e3f6b87fbe0f76c5b89f", "Ed Federmeyer", "", "Sound X (1996) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7dc03a1f56d0e6a8aae3e3e50d654a08", "", "", "Hozer Video Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7dcbfd2acc013e817f011309c7504daa", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7dd9c5284422f729066ab22a284c8283", "CCE", "C-833", "Target Practice (1983) (CCE) [a]", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ded20e88b17c8149b4de0d55c795d37", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.26)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" }, + { "7dfd100bda9abb0f3744361bc7112681", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7e2fe40a788e56765fe56a3576019968", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "AK-050-04", "Double Dragon (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7e464186ba384069582d9f0c141f7491", "PlayAround - J.H.M.", "206", "General Re-Treat (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7e4783a59972ae2cd8384f231757ea0b", "Atari - Imagineering, Dan Kichen", "CX26139P", "Crossbow (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7e51a58de2c0db7d33715f518893b0db", "CBS Electronics, E.F. Dreyer, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7e52a95074a66640fcfde124fffd491a", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673", "Phoenix (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7e7c4c59d55494e66eef5e04ec1c6157", "Baroque Gaming (Brian Eno)", "", "Warring Worms (2002) (Baroque Gaming)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7e8aa18bc9502eb57daaf5e7c1e94da7", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7e9da5cb84d5bc869854938fe3e85ffa", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7e9f088e15b2af9ff3411991393e6b1f", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (12-28-1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7eab0284a0cd1043461d446a08d08cec", "Jone Yuan Telephonic Enterprise Co", "", "Basic Math (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ead257e8b5a44cac538f5f54c7a0023", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7eaf009a892f03d90682dc1e67e85f07", "Fabrizio Zavagli", "", "Bounce! (18-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7eafc9827e8d5b1336905939e097aae7", "Atari, Mark R. Hahn", "", "Elk Attack (1987) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7eba20c2291a982214cc7cbe8d0b47cd", "Imagic, Dave Johnson", "720119-1A, 03211", "Quick Step! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ed61a18cebdeca0a93be1f5461731e5", "Dactari", "", "Skiing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ed7130a6e4020161836414332b11983", "", "", "Fu Kung! (V0.05 Cuttle Card Compatible) (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7edc8fcb319b3fb61cac87614afd4ffa", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ef3ca08abde439c6ccca84693839c57", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "7ef74879d7cb9fa0ef161b91ad55b3bb", "CCE", "", "Vanguard (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f0209cfcc3d181715463f4d6451cecf", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (05-15-1983) (Atari) (Prototype)", "AKA RealSports Driving", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f07cd2e89dda5a3a90d3ab064bfd1f6", "Videospielkassette - Ariola", "PGP234", "Boxen (Ariola) (PAL)", "AKA Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f430c33044e0354815392b53a9a772d", "HES", "773-891", "2 Pak Special - Cavern Blaster, City War (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f525b07bc98080cc8950f7284e52ede", "Atari", "", "128-in-1 Junior Console (Chip 4 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f54fa6aa824001af415503c313262f2", "HES", "", "Boom Bang (HES) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f6533386644c7d6358f871666c86e79", "CommaVid, Irwin Gaines", "CM-008", "Cakewalk (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f790939f7eaa8c47a246c4283981f84", "", "", "This Planet Sucks Demo 3 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7f819454734ddf93f83fefcffcd3e212", "Jone Yuan Telephonic Enterprise Co", "", "Outlaw (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7f9fbe3e00a21ea06e6ae5e0e5db2143", "", "", "Skate Boardin' (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7fcd1766de75c614a3ccc31b25dd5b7a", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "7fcd5fb59e88fc7b8473c641f44226c3", "CCE", "C-807", "Space Tunnel (1983) (CCE)", "AKA O Tunel Espacial", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ff53f6922708119e7bf478d7d618c86", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "7ffc2d80fd49a124808315306d19868e", "Ishido", "", "Domino (Ishido) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "801ba40f3290fc413e8c816c467c765c", "Hozer Video Games", "", "Gunfight 2600 - Westward Ho! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "803393ed29a9e9346569dd1bf209907b", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (02-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "804ed85eadf1ce3e93721547cbea7592", "CCE", "", "Fishing Derby (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8055b9c2622136fd91edfea6df642daf", "Activision", "", "Unknown Activision Game #1 (1983) (Activision) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "805f9a32ef97ac25f999a25014dc5c23", "SnailSoft", "", "Balthazar (SnailSoft)", "AKA Babylon 5", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8068e07b484dfd661158b3771d6621ca", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "807841df228ee8aab0a06ee639ce5a8a", "Coleco - Project Guild - GMA, Michael Green, Anthony R. Henderson, Gary Littleton", "2455", "Turbo (1982) (Coleco) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "807a8ff6216b00d52aba2dfea5d8d860", "John Payson", "", "Strat-O-Gems Deluxe (2005) (J. Payson)", "Uses the AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "", "" }, + { "808c3b1e60ee0e7c65205fa4bd772221", "CCE", "", "Defender (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "80cd42881e670e4b74a9ccd10d0d7b2e", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "80cec82239913cb8c4016eb13749de44", "David Marli", "", "Invaders from Space by David Marli (Space Invaders Hack)", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "80dcbe1b55f12be731a224a53ee4ad5f", "Bit Corporation", "R320", "Amidar (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "80e1410ec98089e0733cc09e584dba4b", "Dynamics", "DY-293005", "Jumping Jack (1983) (Dynamics) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "80e52315919bd8a8b82a407ccd9bb13f", "", "", "Euchre (Jul 28) (2002) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "80e5400470ac788143e6db9bc8dd88cf", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-XX-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "80f7bf7418a462e8687ecefeaf6eb9c2", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8101efafcf0af32fedda4579c941e6f4", "", "", "Okie Dokie (4K) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "81073d0377a2badef8d5e74fc44fc323", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL60) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "8108162bc88b5a14adc3e031cf4175ad", "Suntek", "SS-030", "Skydiver (1983) (Suntek) (PAL)", "AKA Parachute", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8108ad2679bd055afec0a35a1dca46a4", "", "", "Maze Craze (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" }, + { "810d8952af5a6036fca8d0c4e1b23db6", "Tiger Vision - Eram", "", "Keystone (Tiger Vision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "81254ebce88fa46c4ff5a2f4d2bad538", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "81341f00b61ab37d19d1529f483d496d", "", "", "Fu Kung! (V0.04) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "813985a940aa739cc28df19e0edd4722", "Imagic, Bob Smith", "720000-201, 720102-1B, IA3201", "Star Voyager (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "81414174f1816d5c1e583af427ac89fc", "Thomas Jentzsch", "", "Treasure Below (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "814210c0e121f7dbc25661b93c06311c", "", "", "Joustpong (16-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "81591a221419024060b890665beb0fb8", "Atari, Carla Meninsky, Ed Riddle", "CX2611, CX2611P", "Indy 500 (1977) (Atari) (PAL)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" }, + { "8190b403d67bf9792fe22fa5d22f3556", "", "", "Sky Diver (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "819aeeb9a2e11deb54e6de334f843894", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "81a010abdba1a640f7adf7f84e13d307", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "81b3bf17cf01039d311b4cd738ae608e", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "M8776, M8793", "Gorf (1982) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "81f4f0285f651399a12ff2e2f35bab77", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "822a950f27ff0122870558a89a49cad3", "", "", "Space Jockey (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "82337e5fe0f418ca9484ca851dfc226a", "Thomas Jentzsch", "", "Robot City (V1.0) (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "826481f6fc53ea47c9f272f7050eedf7", "Imagic, Dennis Koble", "720103-1A, IA3203", "Atlantis II (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "827a22b9dffee24e93ed0df09ff8414a", "CBS Electronics, Stuart Ross", "", "Wings (10-10-1983) (CBS Electronics) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8290daea8391f96d7c8e1482e184d19c", "Eckhard Stolberg", "", "Frame Timed Sound Effects (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "82bf0dff20cee6a1ed4bb834b00074e6", "Suntek", "SS-035", "Panda (1983) (Quest) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "82c25d1c35e6ac6f893d1d7c2fc2f9c8", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "82de957d155fc041fc6afb8315a28550", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco) (Prototype)", "2K", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "82e7aab602c378cffdd8186a099e807e", "", "", "Space Robot (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "82efe7984783e23a7c55266a5125c68e", "CCE", "C-837", "Pizza Chef (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "834a2273e97aec3181ee127917b4b269", "Quelle", "043.151 0, 874.382 5", "Die hungrigen Froesche (1983) (Quelle) (PAL)", "AKA Frogs and Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "835759ff95c2cdc2324d7c1e7c5fa237", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11011", "M.A.S.H (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8372eec01a08c60dbed063c5524cdfb1", "", "", "Cross Force (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8388d6fe59c38c0b3a6ab2c58420036a", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (12-06-1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "83b8c01c72306d60dd9b753332ebd276", "", "", "Bank Heist (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "83bdc819980db99bf89a7f2ed6a2de59", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "83d15fb9843d9f84aa3710538403f434", "", "", "Gunfight 2600 - Release Candidate (2001) (MP) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "83e1b9f22f29259679e1018bc04cc018", "Bit Corporation", "R320", "Fast Eddie (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "83f05ececae8be59ba1e51135f4bdcbf", "", "", "Demo Image Series #13 - Mario (4K Interleaved Chronocolour) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "83f50fa0fbae545e4b88bb53b788c341", "Atari, Larry Kaplan - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "83fafd7bd12e3335166c6314b3bde528", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "840a5a2eaea24d95d289f514fd12f9bb", "", "", "GBImprov (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "841057f83ce3731e6bbfda1707cbca58", "Champ Games", "CG-04-N", "Super Cobra Arcade (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "841b7bc1cad05f5408302308777d49dc", "Activision", "", "Unknown Activision Game (10-22-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "84290e333ff7567c2380f179430083b8", "Imagic, Dave Johnson", "13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "843435eb360ed72085f7ab9374f9749a", "Joe Grand", "", "SCSIcide (1.31) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" }, + { "84535afb9a69712ec0af4947329e08b8", "CCE", "C-868", "Bingo (1983) (CCE) (PAL)", "AKA Dice Puzzle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8454ed9787c9d8211748ccddb673e920", "Froggo", "FG1002", "Spiderdroid (1987) (Froggo)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8490e1014c2baa0d3a3a08854e5d68b3", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "84db818cd4111542a15c2a795369a256", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "850ffd5849c911946b24544ea1e60496", "", "", "Invasion (07-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "851cc1f3c64eaedd10361ea26345acea", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85227160f37aaa29f5e3a6c7a3219f54", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8530caaaf40acbdcd118c282b5f8a37a", "", "", "This Planet Sucks Demo 2 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8538c5e3ee83267774480649f83fa8d6", "", "", "Escape Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "853c11c4d07050c22ef3e0721533e0c5", "", "", "Oink! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85470dcb7989e5e856f36b962d815537", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85478bb289dfa5c63726b9153992a920", "", "", "Candi (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "854b68b93e7123a3be42b5a2a41f75d7", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85502d69fe46b7f54ef2598225678b47", "Jone Yuan Telephonic Enterprise Co", "", "Super-Ferrari (Jone Yuan)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85564dd0665aa0a1359037aef1a48d58", "ITT Family Games", "554-33 367", "Laser Base (1983) (ITT Family Games) (PAL) [a]", "AKA The End of the World (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8556b42aa05f94bc29ff39c39b11bff4", "Atari, Craig Nelson - Sears", "CX2617 - 49-75183", "Backgammon (1979) (Atari)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 80", "", "", "", "" }, + { "855a42078b14714bcfd490d2cf57e68d", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8597f66dd37d9c855663804669d69d7a", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85a4133f6dcf4180e36e70ad0fca0921", "CCE", "C-827", "Chopper Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85b1bca93e69f13905107cc802a02470", "Atari, Craig Nelson", "CX2617, CX2617P", "Backgammon (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 80", "", "", "", "" }, + { "85bbefb90e16bf386b304c1e9a1f6084", "Champ Games", "CG-02-P", "Conquest Of Mars (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85e48d68c8d802e3ba9d494a47d6e016", "", "", "Ship Demo (V 15) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "85e564dae5687e431955056fbda10978", "Milton Bradley Company - Renaissance Technology, Ty Roberts", "4362", "Survival Run (1983) (Milton Bradley)", "AKA Cosmic Commander", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "86128001e69ab049937f265911ce7e8a", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Lochjaw (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8619da7f6796cedff59e5aa20712fb4e", "Thomas Jentzsch", "", "Sadistroids (v1.2) (2003) (Thomas Jentzsch)", "Supports Driving Controller in right port", "", "", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "", "", "YES", "30" }, + { "862cf669cbced78f9ed31a5d375b2ebe", "", "", "Gunfight 2600 - Flicker acceptance (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8644352b806985efde499ae6fc7b0fec", "CCE", "C-801", "Mr. Postman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8654d7f0fb351960016e06646f639b02", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83106", "Ski Hunt (1983) (Home Vision) (PAL)", "AKA Skiiing Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "866e5150c995c4ae5172e5207ba948c7", "Canal 3 - Intellivision", "", "Stampede (Canal 3) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "869abe0426e6e9fcb6d75a3c2d6e05d1", "", "", "Stampede (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "86b4aa76bbeb70e1a4f9211a9880ba8e", "", "", "Incoming (1 Player Version) (05-11-2002) (Ben Larson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8712cceec5644aacc2c21203d9ebe2ec", "Retroactive", "", "Qb (V0.10) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8726c17ee7b559cb7bf2330d20972ad0", "", "", "Cave Demo (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "873fb75a7788ba0f4ae715229a05545e", "", "", "Euchre (Improved Colors) (PAL) (26-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8747ba79cd39fa83a529bb26010db21b", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [different speed and colors]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8749a0d088df25218c149dc325abc7ca", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a5]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "874c76726f68c166fcfac48ce78eef95", "", "", "Red Pong Number 2 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8764462d7d19a33b0717af22b99fc88f", "CCE", "", "Sky Jinks (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "87662815bc4f3c3c86071dc994e3f30e", "Intellivision Productions - M Network, Patricia Lewis Du Long, Stephen Tatsumi", "", "Swordfight (1983) (Intellivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "876a953daae0e946620cf05ed41989f4", "Retroactive", "", "Qb (V2.08) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "877a5397f3f205bf6750398c98f33de1", "Erik Eid", "", "Euchre (Beta) (PAL) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8786c1e56ef221d946c64f6b65b697e9", "20th Century Fox Video Games, David Lubar", "11015", "AKA Space Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8786f229b974c393222874f73a9f3206", "Activision, Larry Miller - Ariola", "EAX-021, EAX-021-04I - 711 021-720", "Spider Fighter (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8786f4609a66fbea2cd9aa48ca7aa11c", "Goliath", "5", "Open Sesame (1983) (Goliath) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "87b460df21b7bbcfc57b1c082c6794b0", "Dennis Debro", "", "Climber 5 (20-03-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "87b6a17132fc32f576bc49ea18729506", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "87bea777a34278d29b3b6029833c5422", "Thomas Jentzsch", "", "Polaris (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "87e79cd41ce136fd4f72cc6e2c161bee", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "87f020daa98d0132e98e43db7d8fea7e", "20th Century Fox Video Games - Sirius, David Lubar", "11001", "Worm War I (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "883258dcd68cefc6cd4d40b1185116dc", "Activision, David Crane - Ariola", "EAZ-030, EAZ-030-04B, EAZ-030-04I - 711 030-725", "Decathlon (1983) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8874b68751fd2ba6d3306a263ae57a7d", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 1) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8885d0ce11c5b40c3a8a8d9ed28cefef", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, + { "888debb162d7d1ae71025b4ab794257f", "", "", "Interleaved ChronoColour - Nude Art (17-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "88a6c9c88cb329ee5fa7d168bd6c7c63", "CCE", "C-1007", "Jungle Hunt (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "88d300a38bdd7cab9edad271c18cd02b", "Funvision - Fund. Int'l Co.", "", "Pac Kong (Funvision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "88d7b6b3967de0db24cdae1c7f7181bd", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "88d8a1accab58cf1abb043613cf185e9", "Ultravison", "", "Sabotage (Ultravison)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "88dce4037471424bb38ab6841aaa8cab", "", "", "Double-Height 6-Digit Score Display (Two Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "88ed87c011f699dd27321dbe404db6c8", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "88f74ec75ef696e7294b7b6ac5ca465f", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8905d54f48b8024fc718ed643e9033f7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (05-24-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "890c13590e0d8d5d6149737d930e4d95", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8917f7c1ac5eb05b82331cf01c495af2", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8933976f2029c0d8492ebd8f4eb21492", "", "", "Synthcart Plus (09-02-2003) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8953bc11352d794431d3303e31d3b892", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (02-17-1983) (Tigervision) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "896ec58f26e930e02f5e4f046602c3a1", "", "", "Synthcart (Beta) (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "898143773824663efe88d0a3a0bb1ba4", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision) [FE]", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "898748d5eaac3164b0391a64ae1e0e32", "", "", "Hangman Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "898b5467551d32af48a604802407b6e8", "Bit Corporation", "PG208", "Snail Against Squirrel (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "89a65b83203980d5d4d60f52a584a5b8", "", "", "Marble Craze (PAL) (02-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "89a68746eff7f266bbf08de2483abe55", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "89afff4a10807093c105740c73e9b544", "", "", "Pooyan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "89eaba47a59cbfd26e74aad32f553cd7", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8a159ee58b2f0a54805162984b0f07e5", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8a183b6357987db5170c5cf9f4a113e5", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (01-11-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8a42e2c7266439d8997a55d0124c912c", "", "", "Hangman Invader Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8a49cf1785e3dea2012d331a3ad476e1", "", "", "Boulderdash (10 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8a6c84f481acf42abcb78ba5064ad755", "128-in-1 Junior Console", "", "Street Racer (128-in-1 Junior Console) (PAL) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 75", "", "", "", "" }, + { "8a8e401369e2b63a13e18a4d685387c6", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8a9d874a38608964f33ec0c35cab618d", "Chris Cracknell", "", "Rescue Bira Bira (Chris Cracknell)", "Hack of Jungle Fever", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8a9d953ac3db52a313a90d6a9b139c76", "", "", "Hangman Invader Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8aad33da907bed78b76b87fceaa838c1", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8ac18076d01a6b63acf6e2cab4968940", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8af58a9b90b25907da0251ec0facf3b8", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8b04e9d132b8e30d447acaa6bd049c32", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8b40a9ca1cfcd14822e2547eaa9df5c1", "Parker Brothers - Western Technologies, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8b504b417c8626167a7e02f44229f0e7", "Retroactive", "", "Qb (V1.00) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8b556c3d9ca8e5e6e665bd759b93ffae", "", "", "Synthcart (2002) (Paul Slocum) (PAL) [!]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8b5b1e3a434ebbdc2c2a49dc68f46360", "CBS Electronics - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8b7ca29a55432f886cee3d452fb00481", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8b8152d6081f31365406cb716bd95567", "Atari", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8b8789c6669a4cee86c579a65332f852", "Digivision", "", "Plaque Attack (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8bbfd951c89cc09c148bfabdefa08bec", "UA Limited", "", "Pleiades (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8bc0d2052b4f259e7a50a7c771b45241", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) [a]", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8bd8f65377023bdb7c5fcf46ddda5d31", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8bebac614571135933116045204f0f00", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ) (PAL)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "", "", "TRAKBALL", "", "", "", "", "", "", "", "", "YES", "" }, + { "8c103a79b007a2fd5af602334937b4e1", "Thomas Jentzsch", "", "Laser Base (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8c136e97c0a4af66da4a249561ed17db", "", "", "Poker Squares (V0.27) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8c146c61817edd376bc1354c7f1ddc63", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8c1cc284edba691139d6626d062c606f", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL60) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "8c2fa33048f055f38358d51eefe417db", "Home Vision - Gem International Corp. - VDI", "VCS83137", "Teddy Apple (1983) (Home Vision) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8c36ed2352801031516695d1eeefe617", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8c7e5e2329f4f4e06cbcc994a30fd352", "Data Age", "DA1004", "Airlock (1982) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8c8a26ed57870daba8e13162d497bad1", "HES", "", "2 Pak Special - Dolphin, Oink (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8c8b15b3259e60757987ed13cdd74d41", "Supergame", "71", "River Raid (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8c941fa32c7718a10061d8c328909577", "Digivision", "", "River Raid (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8ccaa442d26b09139685f5b22bf189c4", "Retroactive", "", "Qb (V1.01) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8ccf63141a029603572d1056e772990e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8cd26dcf249456fe4aeb8db42d49df74", "Atari - Imagineering, Dan Kichen", "CX26139", "Crossbow (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8ce9126066f2ddd5173e9f1f9ce1494e", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "", "", "TRAKBALL", "", "", "", "", "", "", "", "", "YES", "" }, + { "8cf0d333bbe85b9549b1e6b1e2390b8d", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8d00a38f4c8f8800f1c237215ac243fc", "", "", "3-D Corridor (Green) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8d1e2a6d2885966e6d86717180938f87", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8d8b7d7b983f75debbdaac651e814768", "", "", "Demo Image Series #15 - Three Marios (PAL) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8d9a06101ebb0f147936356e645309b8", "", "", "Grid Pattern Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8da51e0c4b6b46f7619425119c7d018e", "Atari - Imagineering, David Lubar", "CX26183", "Sentinel (1991) (Atari)", "Uses the Light Gun Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8db152458abaef3cfa7a4e420ddbda59", "", "", "Keystone Kapers (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8df4be9ddc54ac363b13dc57ceaf161a", "Scott Stilphen", "", "Asteroids SS (Scott Stilphen) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8e0ab801b1705a740b476b7f588c6d16", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e42674972d6805068fc653e014370fd", "", "", "Skeleton (PAL) (15-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e48ea6ea53709b98e6f4bd8aa018908", "CBS Electronics, Stuart Ross", "", "Wings (06-03-1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8e4cd60d93fcde8065c1a2b972a26377", "Imagic, Dan Oliver", "720118-2A, 13208, EIX-007-04I", "Laser Gates (1983) (Imagic) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e4fa8c6ad8d8dce0db8c991c166cdaa", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e512ad4506800458f99dec084fc2c64", "Bob Montgomery, Nathan Strum", "", "Reindeer Rescue (2005)", "2005 AtariAge Holiday Cart", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e7241bfc8380aac3c0ef1b6881cdded", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (09-01-81) (Atari) (Prototype)", "Time Freeze", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8e737a88a566cc94bd50174c2d019593", "Quelle", "343.173 1", "Feuerwehr im Einsatz (1983) (Quelle) (PAL)", "AKA Fire Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e822b39a71c84ac875f0107fb61d6f0", "", "", "Hangman Ghost Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e879aa58db41edb67cbf318b77766c4", "Thomas Jentzsch", "", "Cosmic Commuter (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8e887d1ba5f3a71ae8a0ea16a4af9fc9", "", "", "Skeleton (V1.1) (PAL) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8ed5a746c59571feb255eaa7d6d0cf98", "", "", "Carnival (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8ed73106e2f42f91447fb90b6f0ea4a4", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8ee3f64dc0f349adc893fe93df5245d8", "", "", "Euchre (20-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8ef96ace4a1d6dfb65926c1e868b0188", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f33bce5ba1053dcf4cea9c1c69981e4", "", "", "Jawbreaker (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f53a3b925f0fd961d9b8c4d46ee6755", "", "", "Astrowar (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f5ac5139419c5d49bacc296e342a247", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (12-22-1982) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f60551db6d1535ef0030f155018c738", "", "", "Space War (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f613ea7c32a587d6741790e32872ddd", "", "", "Troll Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f88309afad108936ca70f8b2b084718", "Spectravision - Spectravideo - Quelle", "SA-203 - 413.223 9", "Cross Force (1982) (Spectravision) (PAL)", "AKA Kreuzfeuer (Cross Fire)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f90590dba143d783df5a6cff2000e4d", "", "", "Gopher (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8f98519a91dbbf4864f135a10050d9ed", "Silvio Mogno", "", "Rainbow Invaders (non-playable demo) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8fa47e5242776e841df7e708b12eb998", "", "", "Sea Hawk (Genesis)", "Genesis controller (C drops bomb)", "Hack of Sea Hawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8fbabaa87941cdf3a377c15e95bdb0f3", "", "", "Meteor Smasher (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8fe00172e7fff4c1878dabcf11bb8dce", "Quelle", "689.302 8", "Hili Ball (1983) (Quelle) (PAL)", "AKA Racquetball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "8febdd9142960d084ab6eeb1d3e88969", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "8fffc8f15bb2e6d24e211884a5479aa5", "Retroactive", "", "Qb (V1.00) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9007c3cbb55ce05ad7d1c34d4906750a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (03-18-1983) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9048ccb7e0802cd8fa5bfc2609f292d8", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9057694dce8449521e6164d263702185", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "90578a63441de4520be5324e8f015352", "Bit Corporation", "PGP204", "Open Sesame (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9072c142728a3a3d994956d03bfacba2", "Fabrizio Zavagli", "", "Crash Dive (Fabrizio Zavagli) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "90a3c3255f2a54225cdcb50831f8793a", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "90b1799dddb8bf748ee286d22e609480", "", "", "Ship Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "90b647bfb6b18af35fcf613573ad2eec", "AtariAge (Chris Walton)", "", "Juno First (2009)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "YES", "" }, + { "90ccf4f30a5ad8c801090b388ddd5613", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "90d77e966793754ab4312c47b42900b1", "Imagic, Brad Stewart", "720105-2A, IA3400P, EIX-005-04I", "Fire Fighter (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "90f502cbf4438a95f69f848cef36eb64", "Digitel", "", "River Raid II (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "910dd9bf98cc5bc080943e5128b15bf5", "", "", "Gunfight 2600 - Improved AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "911d385ee0805ff5b8f96c5a63da7de5", "Thomas Jentzsch", "", "Jammed (V0.1) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "913d5d959b5021f879033c89797bab5e", "", "", "Robot Player Graphic (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "914a8feaf6d0a1bbed9eb61d33817679", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "91925abce3a29e33b6a8b81482f4f5af", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9193b6fff6897d43274741d4f9855b6d", "", "", "M.A.S.H (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "91a3749ff7b7e72b7fa09e05396a0e7b", "", "", "Gunfight 2600 - Final Run Part 2 (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "91b007f33f9b790be64f57220ec52e80", "Jone Yuan Telephonic Enterprise", "", "Laser Blast (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "91c2098e88a6b13f977af8c003e0bca5", "Atari - GCC", "CX2676", "Centipede (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "91d1c82ceaf8af2add3973a3c34bc0cb", "", "", "Starfield Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "91f0a708eeb93c133e9672ad2c8e0429", "", "", "Oystron (V2.9) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "91fdb6541f70c40b16aabf8308123be8", "", "", "Interlacing Game (19-08-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9222b25a0875022b412e8da37e7f6887", "Panda", "106", "Dice Puzzle (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9245a84e9851565d565cb6c9fac5802b", "Bomb - Onbase", "CA282", "Great Escape (1983) (Bomb)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "927d422d6335018da469a9a07cd80390", "Activision, Carol Shaw - Ariola", "EAX-020, EAX-020-04B, EAX-020-04I - 711 020-720", "River Raid (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9281eccd7f6ef4b3ebdcfd2204c9763a", "Retroactive", "", "Qb (2.15) (Retroactive) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9295570a141cdec18074c55dc7229d08", "Telegames", "7045 A015", "Bump 'n' Jump (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "929e8a84ed50601d9af8c49b0425c7ea", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp) (PAL)", "AKA Dishaster, Dancing Plates, Tanzende Teller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "92a1a605b7ad56d863a56373a866761b", "U.S. Games Corporation - Western Technologies, Dave Hampton", "VC2006", "Raft Rider (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "92d1b6cb8a1b615266c4088a58464779", "Bit Corporation", "R320", "Fishing Derby (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "92d1f6ac179ebe5963868d6bc1bdda8d", "HES", "498", "Smash Hit Pak - Frogger, Boxing, Seaquest, Skiing, Stampede (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "92e72f7cc569584c44c9530d645ae04e", "Canal 3 - Intellivision", "", "Spider Fighter (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "931b91a8ea2d39fe4dca1a23832b591a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9333172e3c4992ecf548d3ac1f2553eb", "Konami", "RC 101-X 02", "Strategy X (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93420cc4cb1af1f2175c63e52ec18332", "Tim Snider", "", "Blair Witch Project (Tim Snider) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9364ad51c321e0f15c96a8c0aff47ceb", "Atari, Rob Fulop", "CX2638", "Missile Command (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "936ef1d6f8a57b9ff575dc195ee36b80", "", "", "Pac Kong (Unknown)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "936f555b4b1a2cd061b659ff63f4f5f2", "HES, David Lubar", "535", "My Golf (1990) (HES) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "937736d899337036de818391a87271e0", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-12-1983) (Atari) (Prototype)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "939ce554f5c0e74cc6e4e62810ec2111", "ZiMAG - Emag - Vidco", "711-111 - GN-020", "Dishaster (1983) (ZiMAG)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "93acd5020ae8eb5673601e2edecbc158", "Chris Cracknell", "", "Video Time Machine (Chris Cracknell)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93b9229fc0ea4fb959d604f83f8f603c", "Thomas Jentzsch", "", "Amidar DS (Fast Enemies) (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93c4b910f7649b3e998bb6d8527c6f4a", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype) [fixed]", "Fix for un-initialized 'X' register", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93c52141d3c4e1b5574d072f1afde6cd", "Imagic, Mark Klein", "720112-1A, 03213", "Subterranea (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93c8d9d24f9c5f1f570694848d087df7", "Digivision", "", "Galaxian (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93c9f9239a4e5c956663dd7affa70da2", "Quelle", "626.610 0", "Billard (1983) (Quelle) (PAL)", "AKA Trick Shot", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "93db185c3b3dc382f3aecd6a2fea7fd9", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93dc15d15e77a7b23162467f95a5f22d", "CCE", "", "Sky Jinks (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93e276172b521c4491097f8b1393eea7", "Atari", "", "Diagnostic Test Cartridge 4.2 (06-01-1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "93eb1795c8b1065b1b3d62bb9ec0ccdc", "JSK", "", "Custer's Viagra (JSK) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "94102febc53b4a78342d11b645342ed4", "", "", "Joustpong (14-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9433770890f087bfcf3e50122694d8c0", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9436b7ad131b5a1f7753ce4309ba3dee", "Kyle Pittman", "", "War of The Worlds (Kyle Pittman) (Hack)", "Hack of Defender", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "943798452ceba9357e2c56303cadb4f7", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.28)", "", "New Release, supports BoosterGrip and Genesis (switched by Color/B+W)", "", "", "", "", "", "", "", "JOYSTICK", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" }, + { "9446940866c9417f210f8552cf6c3078", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL60) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "94507dee401b0a072a481c00d7699ffe", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9469d18238345d87768e8965f9f4a6b2", "CCE", "", "Ms. Pac-Man (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "947317a89af38a49c4864d6bdd6a91fb", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "94b92a882f6dbaa6993a46e2dcc58402", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "94d90f63678e086f6b6d5e1bc6c4c8c2", "Digivision", "", "Seaquest (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "94e3fbc19107a169909e274187247a9d", "", "2402-044-01", "2-in-1 Freeway and Tennis (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "94e4c9b924286038527f49cdc20fda69", "Retroactive", "", "Qb (V2.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "94e7cc6342d11e508e7e8b2ddf53c255", "", "", "Missile Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "94ff6b7489ed401dcaaf952fece10f67", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-31-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "951e8cec7a1a1d6c01fd649e7ff7743a", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9526e3db3bdfbc27989a9cbfd0ee34bf", "", "", "Atari Logo Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "95351b46fa9c45471d852d28b9b4e00b", "Atari, Tom Rudadahl", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "955c408265ad6994f61f9b66657bbae9", "", "", "Quadrun (Video Conversion) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "956496f81775de0b69a116a0d1ad41cc", "CCE", "", "Alien (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "956b99511c0f47b3a11d18e8b7ac8d47", "", "", "Bones (Arcade Golf Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "95956108289a917f80667eccd3ce98a9", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "95a69cf8c08ef1522b050529464f0bca", "", "", "Grid Pattern Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "95a89d1bf767d7cc9d0d5093d579ba61", "PlayAround - J.H.M.", "204", "Lady in Wading (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "95e1d834c57cdd525dd0bd6048a57f7b", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "95e542a7467c94b1e4ab24a3ebe907f1", "Suntek", "SS-021", "Dragon Defender (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "95fd6097dc27c20666f039cfe34f7c69", "", "", "Oh No! (Version 1) (17-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "961112b74a920a5242e233480326c356", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "962ffd3eaf865230a7a312b80e6c5cfd", "Imagic, Wilfredo 'Willy' Aguilar, Michael Becker, Rob Fulop", "13205", "Fathom (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "96662271ae50b6859017bffbdda75525", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo (2011)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "96670d0bf3610da2afcabd8e21d8eabf", "", "", "Boring Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "966b11d3c147d894dd9e4ebb971ea309", "", "", "Marble Craze Song (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "966c955e4aaca7082d9ffb9a68e3f3ed", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9671b658286e276cc4a3d02aa25931d2", "", "", "Hangman Ghost Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "968efc79d500dce52a906870a97358ab", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "969b968383d9f0e9d8ffd1056bcaef49", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "96bcb3d97ce4ff7586326d183ac338a2", "", "", "Revenge of the Apes (Hack) [h2]", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "96e798995af6ed9d8601166d4350f276", "20th Century Fox Video Games - Videa, David Ross", "11029", "Meltdown (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "96eccc2277043508a6c481ea432d7dd9", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ) (PAL)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "", "", "ATARIMOUSE", "", "", "", "", "", "", "", "", "YES", "" }, + { "96f806fc62005205d851e758d050dfca", "", "", "Push (V0.05) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "97184b263722748757cfdc41107ca5c0", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9718b85ac5a55cbc7348963c63ffa35a", "Robby", "", "Demon Attack (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "972486110933623039a3581db308fda6", "", "", "Xeno Plus (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "97327d6962f8c64e6f926f79cd01c6b9", "", "", "Jawbreaker (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "977294ae6526c31c7f9a166ee00964ad", "Atari - GCC, Douglas B. Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9784290f422e7aeeab4d542318bd9a1f", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" }, + { "97842fe847e8eb71263d6f92f7e122bd", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-1A, 03206", "Solar Storm (1983) (Imagic)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, + { "97933c9f20873446e4c1f8a4da21575f", "", "", "Racquetball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "97a9bb5c3679d67f5c2cd17f30b85d95", "Atari", "", "Colors (1980) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "97cd63c483fe3c68b7ce939ab8f7a318", "Thomas Jentzsch", "", "Robot City (V0.21) (15-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "97d0151beb84acbe82aa6db18cd91b98", "Steve Engelhardt", "", "Lunar Attack (2002) (Steve Engelhardt) (Hack)", "Hack of Z-Tack", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "97d079315c09796ff6d95a06e4b70171", "Activision, Garry Kitchen", "AZ-032", "Pressure Cooker (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "97e47512f89e79818d988d078dc90410", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "97f4da9f1031486f4e588f1e53572e53", "SpiceWare - Darrell Spice Jr.", "", "Draconian", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9813b9e4b8a6fd919c86a40c6bda8c93", "Atari", "CX26177", "Ikari Warriors (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9831efc7f4cb8ffb4df0082bab2f07a3", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9848b5ef7a0c02fe808b920a2ac566d2", "Skyworks Technology Inc.", "", "Baseball (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9853089672116117258097dbbdb939b7", "Hozer Video Games", "", "Gunfight 2600 - Cowboy Hair (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98555b95cb38e0e0b22b482b2b60a5b6", "", "", "Spinning Fireball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "98ba601a60172cb46c5bf9a962fd5b1f", "", "", "Gorilla Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98ccd15345b1aee6caf51e05955f0261", "Retroactive", "", "Qb (V2.03) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "98e5e4d5c4dd9a986d30fd62bd2f75ae", "", "", "Air-Sea Battle (Unknown) (Hack) (4K)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98e6e34af45a0664597972c3bb31180f", "", "", "Space Instigators (V1.7) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98e7caaab8ec237558378d2776c66616", "Bradford W. Mott", "", "HMOVE Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98ea10c47c13f1b3306c7b13db304865", "", "", "Jam Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98ec0fa4199b9c01f7b8fa3732e43372", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98ef1593624b409b9fb83a1c272a0aa7", "CCE", "C-831", "Cosmic Ark (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98f63949e656ff309cefa672146dc1b8", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "98fa3ad778a668a79449350de4b3b95b", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9905f9f4706223dadee84f6867ede8e3", "HES", "", "Challenge (HES) (PAL)", "Surfer's Paradise if right difficulty = 'A'", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9912d06eea42200a198dd3e2be18c601", "Imagic, Michael Greene", "IA3312", "No Escape! (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "991d57bbcd529ad62925098e0aec1241", "", "", "Gunfight 2600 - The Final Kernel (MP) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9945a22f60bbaf6d04a8d73b3cf3db75", "Activision, Dan Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9947f1ebabb56fd075a96c6d37351efa", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics)", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "A", "", "", "BOOSTERGRIP", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "" }, + { "9962034ea7b3d4a905d0991804670087", "", "", "Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9989f974c3cf9c641db6c8a70a2a2267", "Eckhard Stolberg", "", "Colours Selector (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "99a24d7bb31d49b720b422550b32c35f", "", "", "Hangman Ghost Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "99ac89241365b692255ba95d745edd91", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (18-03-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "99f7c6c26046bbe95f1c604b25da8360", "SnailSoft", "", "Comitoid beta 2 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9a01115206f32eb0b539c7e5a47ccafa", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9a165c39af3f050fdee6583fdfcdc9be", "Zirok", "", "Mario Bros. (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9a21fba9ee9794e0fadd7c7eb6be4e12", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9a25b3cfe2bbb847b66a97282200cca2", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, + { "9a4274409216ff09ecde799f2a56ac73", "CCE", "C-801", "Mr. Postman (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9ab72d3fd2cc1a0c9adb504502579037", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9ad362179c2eea4ea115c7640b4b003e", "", "", "Barnstorming (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" }, + { "9ad36e699ef6f45d9eb6c4cf90475c9f", "Imagic, Dennis Koble", "720103-1A, 720103-1B, IA3203, IX-010-04", "Atlantis (1982) (Imagic)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9aeb5206c5bf974892a9cc59f1478db3", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9af615951e9719df2244bc77fc50cb95", "Dactari - Milmar", "", "Defender (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9afdfe1cff7f37f1c971fe3f0c900606", "Funvision - Fund. International Co.", "", "Plug Attack (Funvision)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9b150a42fc788960fbb4cbe250259ee2", "Kroko", "", "3E Bankswitch Test (TIA @ $40)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9b21d8fc78cc4308990d99a4d906ec52", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9b246683f44c963a50e41d6b485bee77", "", "", "Boring (PAL) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9bb136b62521c67ac893213e01dd338f", "Xonox - Beck-Tech", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9bd4e0d5f28ba6da417c26649171f8e4", "", "", "Hangman Pac-Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9be58a14e055b0e7581fc4d6c2f6b31d", "", "", "Adventure (Color Scrolling) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9c27ef3bd01c611cdb80182a59463a82", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9c40bf810f761ffc9c1b69c4647a8b84", "", "", "2 in 1 - Frostbite, River Raid (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9c6d65bd3b477aace0376f705b354d68", "", "", "RPG Kernal (18-04-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9c6faa4ff7f2ae549bbcb14f582b70e4", "U.S. Games Corporation, Garry Kitchen, Paul Willson - Vidtec", "VC1002", "Sneak 'n Peek (1982) (U.S. Games)", "AKA Hide 'n Seek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9c6fd6ed3599978ab7b6f900484b9be6", "Andrew Wallace", "", "Laseresal 2002 (PAL60) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9c729017dd2f9ccbadcb511187f80e6b", "", "", "J-Pac (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9c7fa3cfcaaafb4e6daf1e2517d43d88", "", "", "PIEROXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9ca2deb61318eba4fb784d4bf7441d8b", "", "", "Purple Bar Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9cbb07f1993a027bc2f87d5205457ec9", "", "", "Eckhard Stolberg's Scrolling Text Demo 1 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d0befa555f003069a21d2f6847ad962", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d1556ae5890398be7e3d57449774b40", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d2938eb2b17bb73e9a79bbc06053506", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d2f05d0fe8b2dfcf770b02eda066fc1", "", "", "Push (V0.06) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d33d31fb1de58c5460d8a67b57b36da", "", "", "Star Voyager (Genesis)", "Genesis controller (C is secondary lasers)", "Hack of Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d37a1be4a6e898026414b8fee2fc826", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5665", "Super Challenge Baseball (1982) (M Network)", "AKA Big League Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d4bc7c6fe9a7c8c4aa24a237c340adb", "Dennis Debro", "", "Climber 5 (16-04-2003) (Dennis Debro)", "For Philly Classic 4", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d522a3759aa855668e75962c84546f7", "Atari, Tom Rudadahl", "CX2634, CX2634P", "Golf (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9d7f04618bb4043f531d087e3aaa7ac8", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9de0d45731f90a0a922ab09228510393", "20th Century Fox Video Games - Sirius, Mark Turmell", "11003", "Fast Eddie (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9dec0be14d899e1aac4337acef5ab94a", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9e01f7f95cb8596765e03b9a36e8e33c", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9e135f5dce61e3435314f5cddb33752f", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9e192601829f5f5c2d3b51f8ae25dbe5", "PlayAround - J.H.M.", "201", "Cathouse Blues (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9e2c7299c69b602443d327c7dad51cbf", "Charles Morgan", "", "Xaxyrax Road (Charles Morgan) (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9e437229136f1c5e6ef4c5f36178ed18", "Funvision - Fund. International Co.", "", "Grand Prize (Funvision)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9e5007131695621d06902ab3c960622a", "Sega", "", "Tac Scan (1983) (Sega) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "YES", "" }, + { "9e792a59f8795664cbaaff1ba152d731", "", "", "Bullet Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9e904e2eaa471c050c491289b8b80f60", "", "", "How to Draw a Playfield II (1997) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9ea8ed9dec03082973244a080941e58a", "Eric Mooney, Piero Cavina", "", "INV+", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9ec1b259a1bcffa63042a3c2b3b90f0a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9eca521db1959156a115dee85a405194", "", "", "Fu Kung! (V0.08) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9ed0f2aa226c34d4f55f661442e8f22a", "", "", "Nuts (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9eeb40f04a27efb1c68ba1d25e606607", "Kyle Pittman", "", "Rambo II (2003) (Kyle Pittman) (Hack)", "Hack of Double Dragon", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9efa877a98dd5a075e058214da428abb", "Hozer Video Games", "", "SCSIcide (1.32) (Hozer Video Games)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" }, + { "9efb4e1a15a6cdd286e4bcd7cd94b7b8", "20th Century Fox Video Games, John W.S. Marvin", "", "Planet of the Apes (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9f2d58dce1b81c6ba201ed103507c025", "", "", "Fu Kung! (V0.02) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9f48eeb47836cf145a15771775f0767a", "Atari, Warren Robinett", "CX2620", "Basic Programming (1979) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9f5096a6f1a5049df87798eb59707583", "20th Century Fox Video Games, Mark Klein", "11036", "Entity, The (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9f52271759f8a2004d207b2247ae0bb3", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (03-12-84) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9f59eddf9ba91a7d93bce7ee4b7693bc", "Thomas Jentzsch", "", "Montezuma's Revenge (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9f8fad4badcd7be61bbd2bcaeef3c58f", "Parker Brothers, Charlie Heath", "PB5330", "Reactor (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "9f901509f0474bf9760e6ebd80e629cd", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9f93734c68f6479eb022cab40814142e", "", "", "Push (V0.07) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9f982421b9b4320ede00fe4aa2e812f4", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "9f9ee0f60c119c831e80694b6678ca1a", "Jeffry Johnston", "", "Radial Pong - Version 8 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9fa0c664b157a0c27d10319dbbca812c", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "9fc2d1627dcdd8925f4c042e38eb0bc9", "Atari - GCC, John Allred, Mike Feinstein", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "E68E28752D3C54EDD3CCDA42C27E320C", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a0028f057d496f22b549fd8deecc6f78", "Joe Grand", "", "SCSIcide Pre-release 6 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a00ec89d22fcc0c1a85bb542ddcb1178", "CCE", "C-1012", "Phoenix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a00ee0aed5c8979add4c170f5322c706", "Barry Laws Jr.", "", "Egghead (Barry Laws Jr.) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a0185c06297b2818f786d11a3f9e42c3", "", "", "International Soccer (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a025a8f83a42a4d6d46c4887e799bfac", "Hozer Video Games", "", "Gunfight 2600 - Descissions had to be made (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a0297c4788f9e91d43e522f4c561b4ad", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "a0563dd6d8215c38c488fbbd61435626", "", "", "Ship Demo (V 1501) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a0675883f9b09a3595ddd66a6f5d3498", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a075ad332942740c386f4c3814925ece", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a0d502dc8b90b1d7daa5f6effb10d349", "", "", "Demo Image Series #5 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a0e2d310e3e98646268200c8f0f08f46", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a100eff2d7ae61ca2b8e65baf7e2aae8", "David Marli", "", "Muncher (David Marli) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a11099b6ec24e4b00b8795744fb12005", "Activision - Bobco, Robert C. Polaro", "EAK-049-04B", "Rampage! (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a1403fef01641dcd3980cac9f24d63f9", "Dactari - Milmar", "", "Atlantis (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a14d8a388083c60283e00592b18d4c6c", "", "", "Tunnel Demo (28-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a15b5831a1fab52e4c416068c85ec011", "Hozer Video Games", "", "Gunfight 2600 - The Good, The Bad, The Ugly (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a174cece06b3abc0aec3516913cdf9cc", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1980) (Sears) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a1770ef47146ab7b12e2c4beccd68806", "Digitel", "", "Kaystone Kapers (1983) (Digitel)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a184846d8904396830951217b47d13d9", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a189f280521f4e5224d345efb4e75506", "Atari - Thomas Jentzsch", "", "Obelix (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a1bcbe0bfe6570da2661fc4de2f74e8a", "Imagic - Advanced Program Technology, Rob Fulop", "", "Actionauts (Microbots) (1984-2008) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a1ca372388b6465a693e4626cc98b865", "Quelle", "176.543 7", "Der Vielfrass (1983) (Quelle) (PAL)", "AKA Fast Food", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a1ead9c181d67859aa93c44e40f1709c", "American Videogame - Dunhill Electronics, Darrell Wagner, Todd Clark Holm, John Simonds", "", "Tax Avoiders (1986) (American Videogame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a1f9159121142d42e63e6fb807d337aa", "Quelle - Otto Versand", "700.223 1 - 781627", "Der moderne Ritter (1983) (Quelle) (PAL)", "AKA Fast Eddie", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a204cd4fb1944c86e800120706512a64", "Coleco, Rob Harris", "2511", "Smurfs Save the Day (1983) (Coleco)", "Uses the Kid Vid Controller", "", "", "", "", "", "", "", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "", "", "" }, + { "a20b7abbcdf90fbc29ac0fafa195bd12", "Quelle - Otto Versand", "719.383 2 - 649635, 781393, 781784, 986404", "Motocross (1983) (Quelle) (PAL)", "AKA Motorcross", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a20d931a8fddcd6f6116ed21ff5c4832", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a2170318a8ef4b50a1b1d38567c220d6", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a1]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2276822c772f72073a8a40a72a1ca52", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2424c1a0c783d7585d701b1c71b5fdc", "", "", "Video Pinball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a25bb76e9e773117e567fd4300b1bb23", "", "", "Interleaved ChronoColour Demo (NTSC) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a28d872fc50fa6b64eb35981d0f4bb8d", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a29df35557f31dfea2e2ae4609c6ebb7", "Atari", "", "Circus Atari (1980) (Atari) (Joystick)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a29fc854838e08c247553a7d883dd65b", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2a384d3a16d5be50afd12906f146827", "Bit Corporation", "R320", "Flash Gordon (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2aae759e4e76f85c8afec3b86529317", "", "", "Boom Bang (Unknown)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2d7cc2e5419a9e4ab91fdb26339b726", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2de0fc85548871279ed2a3c1325c13e", "George Veeder", "", "Cat and Mouse (George Veeder) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2eb84cfeed55acd7fece7fefdc83fbb", "", "", "Kool Aid Man (Fixed) (15-11-2002) (CT)", "HMOVE handling fixed in this version", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2f296ea2d6d4b59979bac5dfbf4edf0", "", "", "Warring Worms (28-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a2f9e3b6aaa23b6dc06099cdd5b51b31", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (PAL60) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a302b922a8dbec47743f28b7f91d4cd8", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a30ece6dc4787e474fbc4090512838dc", "Zellers", "", "Circus (Zellers)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a310494ad5ba2b5b221a30d7180a0336", "", "", "Demo Image Series #6 - Mario (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a336beac1f0a835614200ecd9c41fd70", "Atari, Christopher H. Omarzu, Robert Vieira", "CX26121", "Zoo Keeper Sounds (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a34560841e0878c7b14cc65f79f6967d", "Multivision, Michael Case", "", "Harem (1982) (Multivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a3486c0b8110d9d4b1db5d8a280723c6", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (08-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a35d47898b2b16ec641d1dfa8a45c2b7", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a3873d7c544af459f40d58dfcfb78887", "", "", "Tennis (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a3b9d2be822eab07e7f4b10593fb5eaa", "", "", "GREGXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a3c1c70024d7aabb41381adbfb6d3b25", "Telesys, Alex Leavens", "1005", "Stargunner (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a3d7c299fbcd7b637898ee0fdcfc47fc", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "a3f2a0fcf74bbc5fa763b0ee979b05b1", "Quelle", "873.790 0", "Eishockey-Fieber (1983) (Quelle) (PAL)", "AKA Ice Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a3f8aebb38182749cb8da85cfbc63d7c", "", "", "Tennis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a3fee8ce15525ea00d45a06f04c215d1", "Aaron Curtis", "", "AStar (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a406d2f6d84e61d842f4cb13b2b1cfa7", "Tigervision, John Harris - Teldec", "7-002", "Jawbreaker (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a412c8577b2d57b09185ae51739ac54f", "Arcadia Corporation, Dennis Caswell", "AR-4000", "Phaser Patrol (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a41450333f8dd0e96e5e9f0af3770ae9", "", "", "Basic Math (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a422194290c64ef9d444da9d6a207807", "M Network - APh Technological Consulting, Hal Finney", "MT5667", "Dark Cavern (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a428068d3e51498907d97cec40000515", "Bit Corporation", "R320", "Sky Alien (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a47878a760f5fa3aa99f95c3fdc70a0b", "", "", "Demo Image Series #5 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4790224bd5afabd53cbe93e46a7f241", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a47e26096de6f6487bf5dd2d1cced294", "Atari", "CX2643", "Codebreaker (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a484638990de7b12c62947c79dafa4c6", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL60) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a499d720e7ee35c62424de882a3351b6", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "009-01", "Up 'n Down (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4aa7630e4c0ad7ebb9837d2d81de801", "", "", "Atari 2600 Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4ab331e8768eafdc20ce8b0411ff77a", "", "", "Demo Image Series #1 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4b9423877a0b86ca35b52ca3c994ac5", "CCE", "C-805", "Sea Monster (1983) (CCE)", "O Monstro Marinho", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4b99aa5ed85cfdb7d101923147de035", "Jim Goebel", "", "Pac-Law (Jim Goebel) (Hack)", "Hack of Outlaw", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4c08c4994eb9d24fb78be1793e82e26", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4d026a5c200ef98518ebb77719fe8dc", "Kyle Pittman", "", "SpongeBob SquarePants (2003) (Kyle Pittman) (Hack)", "Hack of Revenge of the Beefsteak Tomatoes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4e885726af9d97b12bb5a36792eab63", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4ecb54f877cd94515527b11e698608c", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (12-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4f1cea2c8479284e2a2292f8d51b5fa", "", "", "Gunfight 2600 - The Final Kernel Part 2 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a4ff39d513b993159911efe01ac12eba", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a511f7ee13e4b35512f9217a677b4028", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a5262fe6d01d6a1253692682a47f79dd", "", "", "JKH Text Scrolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a537879d8e82e1061d3ad800479d3b84", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a539b9fd1ba57e46442b3e9351e6383b", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack) [a]", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a56b642a3d3ab9bbeee63cd44eb73216", "Carrere Video - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV - Teldec - Prism", "USC2001", "Gopher (1983) (Carrere Video) (PAL)", "AKA Vossicht Whlmaus!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a5855d73d304d83ef07dde03e379619f", "Atari, David Crane", "", "Boggle (08-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a58b11148c18d85e4c2aef4ff46ade67", "", "", "Video Chess (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a591b5e8587aae0d984a0f6fe2cc7d1c", "", "", "Globe Trotter Demo (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a5b7f420ca6cc1384da0fed523920d8e", "", "", "Adventure (New Graphics) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a5c96b046d5f8b7c96daaa12f925bef8", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a5e9ed3033fb2836e80aa7a420376788", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a60598ad7ee9c5ccad42d5b0df1570a1", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a6127f470306eed359d85eb4a9cf3c96", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a6239810564638de7e4c54e66b3014e4", "Personal Games Company, Robert Anthony Tokar", "", "Birthday Mania (1984) (Personal Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a62e3e19280ff958407e05ca0a2d5ec7", "", "", "Hangman Ghost Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a6737c81542a99ee71cb5f5ff14703d9", "", "", "Scrolling Playfield 3 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a69f5b1761a8a11c98e706ec7204937f", "", "", "Pharaoh's Curse (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a6ed8d72ed691fd3aad5b6974fa17978", "Bit Corporation", "R320", "Bank Heist (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a74689a08746a667a299b0507e1e6dd9", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a7523db9a33e9417637be0e71fa4377c", "Videospielkassette - Ariola", "PGP238", "Gangster (Ariola) (PAL)", "AKA Outlaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a7673809068062106db8e9d10b56a5b3", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118, CX26118P", "Millipede (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a779b9fa02c62d00d7c31ed51268f18a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a7a58e9291aefa1064e933071f60d4ef", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a7b584937911d60c120677fe0d47f36f", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5661", "Armor Ambush (1982) (M Network)", "AKA Tank Battle", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a7b96a8150600b3e800a4689c3ec60a2", "Atari, Mike Lorenzen - Sears", "CX2630 - 49-75122", "Circus Atari (1980) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, + { "a7bf8353f77caca407ef85c2698fdff2", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a7cf2b9afdbb3a161bf418dbcf0321dc", "Barry Laws Jr.", "", "Attack Of The Mutant Space Urchins (2002) (Barry Laws Jr.) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a7d2e9408bb7cd70139ecced407ff238", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a7ed7dc5cbc901388afa59030fb11d26", "Atari, Warren Robinett", "CX2606, CX2606P", "Slot Racers (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a7ef44ccb5b9000caf02df3e6da71a92", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8101cb667e50a46165c6fb48c608b6b", "", "", "Kung Fu Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a81697b0c8bbc338ae4d0046ede0646b", "CCE", "", "Gravitar (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a81b29177f258494b499fbac69789cef", "Greg Thompson", "", "Console Wars (Greg Thompson) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a83b070b485cf1fb4d5a48da153fdf1a", "Apollo", "AP-2011", "Pompeii (1983) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8435ec570141de5d833c4abec499e55", "", "", "Happy Birthday Demo (2001) (Dennis Debro) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8633050a686270fcf6c0cc4dcbad630", "Zirok", "", "Phoenix (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a867b76098786c4091dba2fcee5084c3", "", "", "Dragrace (Hack)", "Hack of Dragster", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a875f0a919129b4f1b5103ddd200d2fe", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (PAL)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8916734ff8c64ec3342f4c73fd5b57d", "Atari", "", "Stand Alone Test Cart (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a89a3e0547d6887279c34aba4b17a560", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype)", "", "Prototype", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8a703e073183a89c94d4d99b9661b7f", "Franklin Cruz", "", "Spice Invaders (Franklin Cruz) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8b3ea6836b99bea77c8f603cf1ea187", "CCE", "C-861", "Boxing (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8c447efbec3a2b5d08b05a09999bd92", "", "", "MegaCart Menu", "", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "a8c48b4e0bf35fe97cc84fdd2c507f78", "Puzzy - Bit Corporation", "PG201", "Seamonster (1982) (Puzzy)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8d0a4a77cd71ac601bd71df5a060e4c", "", "", "Space Shuttle (1983) (Activision) [t2] (Fuel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8d4a9500b18b0a067a1f272f869e094", "", "", "Red And White Checkerboard Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8e49d7e24ce293629ca29614862821b", "", "", "Enduro (Genesis)", "Genesis controller (B is acceleration, C is brakes)", "Hack of Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a91d0858a52de3a2e6468437212d93e8", "", "", "Q-bert (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a936d80083e99d48752ad15c2b5f7c96", "", "", "Room of Doom (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a93e8ea1f565c3c1e86b708cf0dc2fa9", "Jess Ragan", "", "Kabul! (Jess Ragan) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "a94528ae05dd051894e945d4d2349b3b", "Genus", "", "River Raid (Genus)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a94b8ca630f467b574b614808d813919", "HES", "773-883", "2 Pak Special - Space Voyage, Fire Alert (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a9531c763077464307086ec9a1fd057d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a957dbe7d85ea89133346ad56fbda03f", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "a97733b0852ee3096300102cb0689175", "CCE", "C-834", "Fast Eddie (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a9784c24cddb33bd0d14442b97784f3d", "Thomas Jentzsch", "", "Omega Race DC (2003) (TJ) (Omega Race Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a98b649912b6ca19eaf5c2d2faf38562", "", "", "This Planet Sucks (Greg Troutman) (PAL) [!]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a995b6cbdb1f0433abc74050808590e6", "Imagic, Rob Fulop, Bob Smith", "720106-1A, IA3600", "Riddle of the Sphinx (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a9cb638cd2cb2e8e0643d7a67db4281c", "M Network - INTV - APh Technological Consulting, Larry Zwick", "MT5861", "Air Raiders (1983) (M Network)", "AKA Air Battle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a9d9e19d0c89fb31780b5d63e1f8c6a4", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a9e3c23599c0d77151602f8e31daf879", "", "", "Kung Fu Master (Genesis)", "Genesis controller (C is extra kick modes)", "Hack of Kung Fu Master", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aa1c41f86ec44c0a44eb64c332ce08af", "Spectravideo, David Lubar", "SA-218", "Bumper Bash (1983) (Spectravideo)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aa2c4b32656bde9a75042a4d158583e1", "", "", "Oystron X (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aa5cfe3b20395aba1d479135943ad85c", "", "", "Defender (Hack) (Unknown)", "", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aa7bb54d2c189a31bb1fa20099e42859", "CBS Electronics, Ed English", "4L4478", "Mr. Do! (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "aa8c75d6f99548309949916ad6cf33bc", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aa8e4b2cb8a78ffe6b20580033f4dec9", "", "", "Bitmap Demo (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aaac0d277eda054861e613c59c2e4ff2", "JWDA, Todd Marshall", "", "Music Demo (JWDA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aab840db22075aa0f6a6b83a597f8890", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83124", "Racing Car (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aad61898633f470ce528e3d7ef3d0adb", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aad91be0bf78d33d29758876d999848a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1981) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aaea37b65db9e492798f0105a6915e96", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" }, + { "aafc79ffc32c4c9b2d73c8ada7602cfe", "", "", "Planet Patrol (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab10f2974dee73dab4579f0cab35fca6", "ITT Family Games", "", "Wilma Wanderer (1983) (ITT Family Games) (PAL)", "AKA Lilly Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab2cfcaad3daaf673b2b14fdbb8dac33", "M Network - INTV, David Akers, Joe King, Patricia Lewis Du Long, Jeff Ratcliff", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab2ea35dcc1098c87455bb8210b018cf", "", "", "Fu Kung! (V0.04 Single Line Resolution) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab301d3d7f2f4fe3fdd8a3540b7a74f5", "Jone Yuan Telephonic Enterprise Co", "", "IQ 180 (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab434f4c942d6472e75d5490cc4dd128", "HES", "773-875", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab48c4af46c8b34c3613d210e1206132", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo V2 (2014)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab4ac994865fb16ebb85738316309457", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari)", "Console ports are swapped", "Common", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab56f1b2542a05bebc4fbccfc4803a38", "Activision - Imagineering, Dan Kitchen, David Lubar", "AK-048-04", "River Raid II (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab5bf1ef5e463ad1cbb11b6a33797228", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab60ea7b707c58d356cad858eb18db43", "", "", "Tazer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ab8d318da4addd39c65b7f9c408df2a6", "", "", "Star Trek (Genesis)", "Genesis controller (B is phaser, C is warp)", "Hack of Star Trek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "abb740bea0a6842831b4f53112fb8145", "", "", "Qb (V1.01) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "abb741c83f665d73c86d90a7d9292a9b", "Telegames", "", "Space Attack (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "abc64037ca5d5b04ae8a7eedbca3ed74", "", "", "Green and Yellow Number 1 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "abe40542e4ff2d1c51aa2bb033f09984", "Absolute Entertainment, David Crane", "EAZ-042-04B, EAZ-042-04I", "Skate Boardin' (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ac05c0e53a5e7009ddd75ed4b99949fc", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ac0ddbcff34d064009591607746e33b8", "Thomas Jentzsch", "", "Atlantis FH (2003) (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ac26d7d37248d1d8eac5eccacdbef8db", "", "", "Snail Against Squirrel (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ac3dd22dd945724be705ddd2785487c2", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ac53b83e1b57a601eeae9d3ce1b4a458", "Retroactive", "", "Qb (2.15) (Retroactive) (NTSC)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ac5f78bae0638cf3f2a0c8d07eb4df69", "", "", "Minesweeper (V.99) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ac7c2260378975614192ca2bc3d20e0b", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ac9adbd6de786a242e19d4bec527982b", "Activision, Alan Miller - Ariola", "EAG-012-04I, EAX-012, EAX-012-04B - 711 012-720", "Ice Hockey (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aca09ffea77174b148b96b205109db4d", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "acaa27d214039d89d7031609aafa55c3", "", "", "Sprite Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "acb6787b938079f4e74313a905ec3ceb", "", "", "Chronocolor Donkey Kong (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "acb7750b4d0c4bd34969802a7deb2990", "Parker Brothers, Ed Temple", "PB5310", "Amidar (1982) (Parker Bros)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "acb962473185d7a652f90ed6591ae13b", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (16K)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ace319dc4f76548659876741a6690d57", "Atari, Steve Wright", "CX2616", "Pele's Soccer (1981) (Atari)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ad2e6bfb3b9b9b36ba8bf493ce764c49", "", "", "2600 Collison Demo 1 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ad42e3ca3144e2159e26be123471bffc", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ad72d616030a17634ff29ce8680d3c4c", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ad7e97c19bd25d5aa3999430845c755b", "", "", "Sprite Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ad8072675109d13fdd31a2e0403d5cff", "Funvision - Fund. International Co.", "", "Tank City (Funvision)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "adb770ff70e9adf08bbb907a7eccd240", "", "", "Inv Demo 3 (2001) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "adb79f9ac1a633cdd44954e2eac14774", "Digivision", "", "Frostbite (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "adf1afac3bdd7b36d2eda5949f1a0fa3", "Quelle - Otto Versand", "495.463 2 - 746381", "Angriff der Luftflotten (1983) (Quelle) (PAL)", "AKA Paris Attack, M.A.D.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "adfbd2e8a38f96e03751717f7422851d", "Champ Games", "CG-01-N", "Lady Bug (NTSC)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ae047e9468bda961d8e9e9d8ff52980f", "", "", "Tunnel Demo (Red Spiral) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ae0d4f3396cb49de0fabdff03cb2756f", "Retroactive", "", "Qb (V2.02) (PAL) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ae10527840a1ac24de43730645ed508d", "Charles Morgan", "", "Planet Invaders (Charles Morgan) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ae18c11e4d7ed2437f0bf5d167c0e96c", "", "", "Multi-Color Demo 3 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ae2f1f69bb38355395c1c75c81acc644", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-23-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ae465044dfba287d344ba468820995d7", "", "", "Inca Gold (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ae4be3a36b285c1a1dff202157e2155d", "Spectravideo", "SA-210", "Master Builder (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ae682886058cd6981c4b8e93e7b019cf", "Retroactive", "", "Qb (V0.12) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ae6cb335470788b94beb5787976e8818", "", "", "Mortal Kurling (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ae83541cf4a4c0bce0adccd2c1bf6288", "", "", "Maze 003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ae97cf8ed21f4154b4360a3cf6c95c5e", "", "", "Teleterm 2600 (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aeb104f1e7b166bc0cbaca0a968fde51", "", "", "Ms. Pac-Man (1999) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aec9b885d0e8b24e871925630884095c", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aed0b7bd64cc384f85fdea33e28daf3b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "aed82052f7589df05a3f417bb4e45f0c", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "af6ab88d3d7c7417db2b3b3c70b0da0a", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "af6f3e9718bccfcd8afb421f96561a34", "Atari, Tod Frye", "CX2695", "Xevious (01-18-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "afb3bc45c6a82739cc82582127cd96e6", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dungeon (11-22-1985) (Atari) (Prototype)", "Dark Chambers Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "afc194534c1b346609ef05eff6d3cef6", "Jone Yuan Telephonic Enterprise Co", "", "Boxing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "afd2cf258d51ae4965ee21abba3627ab", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (12-08-1982) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "afe4eefc7d885c277fc0649507fbcd84", "Atari", "CX26163P", "Ant Party (32 in 1) (1988) (Atari) (PAL)", "AKA Cosmic Swarm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "afe776db50e3378cd6f29c7cdd79104a", "Thomas Jentzsch", "", "Bobby is Going Home (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "afe88aae81d99e0947c0cfb687b16251", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "aff8cba0f2d2eb239953dd7116894a08", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b00088418fc891f3faa3d4ddde6ace94", "", "", "Unknown Title (bin00007 (200102)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b00a8bc9d7fe7080980a514005cbad13", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b00e8217633e870bf39d948662a52aac", "Konami", "RC 102-X 02", "Marine Wars (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b011d8fdc450597c0762c2c0010a9b17", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b049fc8ac50be7c2f28418817979c637", "Activision - Imagineering, Dan Kitchen, David Lubar", "EAK-048-04, EAK-048-04B", "River Raid II (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b06050f686c6b857d0df1b79fea47bb4", "Activision", "AIZ-001", "Moonsweeper (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b061e98a4c854a672aadefa233236e51", "Atari, Warren Robinett", "CX2620, CX2620P", "Basic Programming (1979) (Atari) (PAL)", "Uses Keypad Controllers", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b095009004df341386d22b2a3fae3c81", "", "", "Sub-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b09b79c9628878be051e89f7f1e77378", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "b0a9c6f6c8014c4023e0341ba11ca35e", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009) (PAL)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b0ba51723b9330797985808db598fc31", "Atari, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b0c47e426c7f799aee2c40422df8f56a", "", "", "Space Treat (PAL) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b0c9cf89a6d4e612524f4fd48b5bb562", "Atari - GCC", "CX2663", "Combat Two (1982) (Atari) (Prototype)", "AKA Super Combat", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b0e1ee07fbc73493eac5651a52f90f00", "Colin Hughes", "", "Tetris 2600 (Colin Hughes)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b1276417fb0f79bc52e741bb8f4d8360", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (NTSC) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b129d7541cff79ebe33852a83057c524", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (NTSC) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b12a7f63787a6bb08e683837a8ed3f18", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic) [fixed]", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b1339c56a9ea63122232fe4328373ac5", "Goliath - Hot Shot", "83-215", "Dream Flight (1983) (Goliath) (PAL)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b1486e12de717013376447ac6f7f3a80", "Spectravideo, Mark Turmell, Quelle", "SA-217, SA-217C - 413.723 8", "Gas Hog - Piraten Schiff (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b15026b43c6758609667468434766dd8", "Retroactive", "", "Qb (0.06) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b16cd9784589219391c839cb68c47b9c", "Video Soft, Jerry Lawson, Dan McElroy", "", "Golf Diagnostic (1983) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b17b9cc4103844dcda54f77f44acc93a", "Quelle", "377.943 6", "Stopp die Gangster (1983) (Quelle) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b182d9708e00709830caab9cf8205ca0", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b1a6c96e9093352106bc335e96caa154", "Joe Grand", "", "SCSIcide Pre-release 1 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b1b20536aef4eed9c79dc5804f077862", "", "", "Euchre (NTSC) (09-11-2001) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b1c14b5ac896400cc91c8e5dd67acb59", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b1d1e083dc9e7d9a5dc1627869d2ade7", "CCE", "C-1004", "Mario's Bros. (1983) (CCE)", "AKA Mario Bros.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b1e2d5dc1353af6d56cd2fe7cfe75254", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b1fd0b71de9f6eeb5143a97963674cb6", "", "", "Multi-Color Demo 7 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b227175699e372b8fe10ce243ad6dda5", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b23ebf427713dd0198b7ef47dbd07ef4", "Jone Yuan Telephonic Enterprise Co", "", "Sky Diver (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b24f6a5820a4b7763a3d547e3e07441d", "CCE", "C-823", "Demon Attack (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b25841173f058380b1771aacd5e7cdf3", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b26506fbf411009e5e3f7365f442960e", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b2737034f974535f5c0c6431ab8caf73", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b2761efb8a11fc59b00a3b9d78022ad6", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b290c2b139344fcff5b312c71b9ac3b2", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b29359f7de62fed6e6ad4c948f699df8", "Goliath", "3", "Phantom Tank (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b2a6f31636b699aeda900f07152bab6e", "", "", "Space Instigators (Public Release 2) (06-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b2ab209976354ad4a0e1676fc1fe5a82", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a3]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b2d1e63f7f22864096b7b6c154151d55", "Fabrizio Zavagli", "", "Bounce! (17-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b2d3bcee001cff2bd2d8a21b2cb55109", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (08-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b2d5d200f0af8485413fad957828582a", "Atari - Bobco, Robert C. Polaro", "CX26155P", "Sprint Master (1988) (Atari) (PAL)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b2f0d7217147160b2f481954cedf814b", "", "", "Marquee Drawer (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b3017e397f74efd53caf8fae0a38e3fe", "Retroactive", "", "Qb (2.12) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b311ab95e85bc0162308390728a7361d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b31dc989f594764eacfa7931cead0050", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b31e9487efc06f18dfc3d7ebadf54416", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b31f178aa0d569cccac7959f84e0a724", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-13-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b3203e383b435f7e43f9492893c7469f", "Gameworld", "133-003", "Sssnake (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b36040a2f9ecafa73d835d804a572dbf", "Digitel", "", "Pac Man (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b37f0fe822b92ca8f5e330bf62d56ea9", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b392964e8b1c9c2bed12246f228011b2", "", "", "Name This Game (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b4030c38a720dd84b84178b6ce1fc749", "M Network - APh Technological Consulting, Kevin Miller", "MT5687", "International Soccer (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b40dea357d41c5408546e4e4d5f27779", "Digivision", "", "Spider Fighter (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b41fdd4a522e1d5a2721840028684ac2", "", "", "Green and Yellow Number 1 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b42df8d92e3118dc594cecd575f515d7", "Mystique - American Multiple Industries", "1003", "Burning Desire (1982) (Mystique) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b438a6aa9d4b9b8f0b2ddb51323b21e4", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames) (PAL)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b451307b8b5e29f1c5f2cf064f6c7227", "", "", "Demo Image Series #6 - Mario (Fixed) (26-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b49331b237c8f11d5f36fe2054a7b92b", "", "", "Condor Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b4a4c87840613f102acb5b3a647d0a67", "", "", "Mobile 48 Sprite Kernel (04-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b4daedb43511521db9036d503b3c1b69", "", "", "Sokoban (01-01-2003) (Adam Wozniak) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b4e2fd27d3180f0f4eb1065afc0d7fc9", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, William O. Sheppard", "5002002", "London Blitz (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b4f05e544834d0238a0c263491775edf", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b4f31ea8a6cc9f1fd4d5585a87c3b487", "Mystique - American Multiple Industries, Joel H. Martin", "", "Beat 'Em & Eat 'Em (1982) (Mystique) (PAL)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "b4f87ce75f7329c18301a2505fe59cd3", "Videospielkassett - Ariola", "PGP232", "Autorennen (Ariola) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b50ae55aac93fbed258bc5a873edd2cb", "Recompile", "", "E.T. The Extra-Terrestrial (Recompile) (Hack)", "www.neocomputer.org/projects/et", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b5110f55ed99d5279f18266d001a8cd5", "Eckhard Stolberg", "", "Auto-mobile Demo (2001) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b56264f738b2eb2c8f7cf5a2a75e5fdc", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b5657d4c1c732fbb6af150668464247f", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b59417d083b0be2d49a7d93769880a4b", "Pet Boat", "", "Donkey Kong (1983) (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b59fd465abf76f64c85652ff29d5952d", "VentureVision, Dan Oliver", "", "Innerspace (1983) (VentureVision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b5a1a189601a785bdb2f02a424080412", "Imagic, Dennis Koble", "720021-1A, IA3410", "Shootin' Gallery (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b5cb9cf6e668ea3f4cc2be00ea70ec3c", "CommaVid, Irwin Gaines - Ariola", "CM-005 - 712 005-720", "Mines of Minos (1982) (CommaVid) (PAL)", "AKA Im Labyrinth des Roboters", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b5cdbab514ea726a14383cff6db40e26", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL) [a]", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b5efe0271d2214e4d5dc798881486884", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (06-14-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b6166f15720fdf192932f1f76df5b65d", "Amiga - Video Soft", "3130", "Off Your Rocker (1983) (Amiga) (Prototype)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b64426e787f04ff23ee629182c168603", "Dynacom", "", "Plaque Attack (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b65d4a38d6047735824ee99684f3515e", "Dynacom", "", "MegaBoy (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b676a9b7094e0345a76ef027091d916b", "Thomas Jentzsch", "", "Mission Survive (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b6812eaf87127f043e78f91f2028f9f4", "Simage", "", "Eli's Ladder (1984) (Simage)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b6821ac51c4c1dcb283f01be2f047dc1", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (25-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b6960be26bee87d53ba4e2e71cfe772f", "", "", "3-D Corridor (Spiral Words) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b6d52a0cf53ad4216feb04147301f87d", "Imagic, Michael Greene", "720055-1A, IA3312", "No Escape! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b6e40bce550672e5495a8cdde7075b8b", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b702641d698c60bcdc922dbd8c9dd49c", "Atari, Ian Shepard", "CX26163P", "Space War (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b719ada17771a8d206c7976553825139", "Ron Corcoran", "", "DUP Space Invaders (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b731d35e4ac6b3b47eba5dd0991f452f", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (Final) (08-01-2003) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b7345220a0c587f3b0c47af33ebe533c", "Quelle", "176.433 1", "Landungskommando (1983) (Quelle) (PAL)", "AKA Strategy X", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b76fbadc8ffb1f83e2ca08b6fb4d6c9f", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b77468d586957d1b7fb4cccda2684f47", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b7903268e235310dc346a164af4c7022", "Thomas Jentzsch", "", "Cat Trax (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b79fe32320388a197ac3a0b932cc2189", "Imagic, Bob Smith", "13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b7a7e34e304e4b7bc565ec01ba33ea27", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b7b1d3ce07e75976c43a2dca3866237e", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b7d0aae399781b3c18679debda6d32b1", "Thomas Jentzsch", "", "Three.s (v1.02)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b7d7c76e37f372f4e4979b380ed95a58", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b7e459d5416eeb196aaa8e092db14463", "", "", "Push (V0.02) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b7f184013991823fc02a6557341d2a7a", "", "", "Blue Rod Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b80d50ecee73919a507498d0a4d922ae", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b816296311019ab69a21cb9e9e235d12", "Atari, Bob Whitehead - Sears", "CX2652 - 6-99816, 49-75151", "Casino (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b822fba8b7c8a97ea4e92aeb2c455ef9", "Dactari", "", "Freeway (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b83579c4450fcbdf2b108903731fa734", "", "", "Mission 3,000 A.D. (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b83df1f32b4539c324bdf94851b4db55", "Angelino", "", "One On One by Angelino (Basketball Hack)", "Hack of Basketball (1978) (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b86552198f52cfce721bafb496363099", "Apollo, Tim Martin", "AP-2007", "Kyphus (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b86a12e53ab107b6caedd4e0272aa034", "Funvision - Fund. International Co.", "", "Treasure Hunting (Funvision)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b879e13fd99382e09bcaf1d87ad84add", "Zellers", "", "Time Warp (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b8865f05676e64f3bec72b9defdacfa7", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b897f9e3f939b9f21566d56db812a84e", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b8e715223ba65cf716b3620a90ca3ec1", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b8ed78afdb1e6cfe44ef6e3428789d5f", "Data Age, J. Ray Dettling", "112-007", "Bermuda Triangle (1983) (Data Age)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b9232c1de494875efe1858fc8390616d", "Panda", "110", "Harbor Escape (1983) (Panda)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b9336ed6d94a5cc81a16483b0a946a73", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "b955eb0e2baf7a437c186bddd4c49958", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL60) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b958d5fd9574c5cf9ece4b9421c28ecd", "Piero Cavina", "", "Multi-Sprite Game V1.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b95a6274ca0e0c773bfdc06b4c3daa42", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b98cc2c6f7a0f05176f74f0f62c45488", "Spectravideo", "SV-010", "CompuMate (1983) (Spectravideo)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "", "", "COMPUMATE", "", "", "", "", "", "", "", "", "YES", "" }, + { "b9b4612358a0b2c1b4d66bb146767306", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b9d1e3be30b131324482345959aed5e5", "Activision - Boston Design Center, Rex Bradford", "", "Kabobber (07-25-1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "b9f6fa399b8cd386c235983ec45e4355", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL)", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, + { "b9f9c0fed0db08c34346317f3957a945", "SuperVision", "405, 427, 806, 808, 813, 816", "Chopper Command (SuperVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ba257438f8a78862a9e014d831143690", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2002", "Squeeze Box (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ba317f83cdfcd58cbc65aac1ccb87bc5", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ba3a17efd26db8b4f09c0cf7afdf84d1", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ba3b0eebccc7b791107de5b4abb671b4", "Thomas Jentzsch", "", "Thrust (V0.9) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ba657d940a11e807ff314bba2c8b389b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bac28d06dfc03d3d2f4a7c13383e84ee", "Supergame", "", "Demon Attack (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bae1a23f9b6acdadf465cfb330ba0acb", "Atari - GCC, Doug Macrae", "CX2677", "Dig Dug (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bae66907c3200bc63592efe5a9a69dbb", "Spectravision - Spectravideo - Quelle", "SA-201 - 412.783 3", "Gangster Alley (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "baf4ce885aa281fd31711da9b9795485", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bb18189021d58362d9e4d317cd2e28b7", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL) (4K)", "AKA Dragster Rennen", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bb2b83fff97604f74ada565e0b5bae94", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bb5049e4558daade0f87fed69a244c59", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [no copyright]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "bb579404924c40ca378b4aff6ccf302d", "", "", "Lightbulb Lightens, The (PD) (Non Functional)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bb6a5a2f7b67bee5d1f237f62f1e643f", "", "", "Demo Image Series #5 - Animegirl (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bb745c893999b0efc96ea9029e3c62ca", "Play Video", "", "Planet Patrol (1982) (Play Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bb756aa98b847dddc8fc170bc79f92b2", "", "", "Golf (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bb9112d478a1a922d2c289a752bba695", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bbf8c7c9ed280151934aabe138e41ba7", "Amiga", "1130", "Power Play Arcade Video Game Album V (1984) (Amiga) (Prototype)", "Mogul Maniac, Surf's Up, Off Your Rocker, S.A.C. Alert", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc24440b59092559a1ec26055fd1270e", "", "", "Private Eye (1984) (Activision) [a]", "", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc3057a35319aae3a5cd87a203736abe", "CCE", "C-845", "Time Warp (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc33c685e6ffced83abe7a43f30df7f9", "Dynacom", "", "Seaquest (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc4cf38a4bee45752dc466c98ed7ad09", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari) (PAL)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc526185ad324241782dc68ba5d0540b", "", "", "Dodge Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc5389839857612cfabeb810ba7effdc", "Atari, Tod Frye", "CX2671", "SwordQuest - WaterWorld (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc703ea6afb20bc089f04d8c9d79a2bd", "", "", "Gunfight 2600 - Not mergeable with Colbert wizardry... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bc97d544f1d4834cc72bcc92a37b8c1b", "", "", "Sky Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bcb31f22856b0028c00d12f0e4c0a952", "Canal 3 - Intellivision", "", "Thunderground (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bcb73b534ed7c613ac379ecd726effb5", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bccb4e2cfad5efc93f6d55dc992118ce", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bce4c291d0007f16997faa5c4db0a6b8", "Quelle", "292.651 7", "Weltraumtunnel (1983) (Quelle) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bce93984b920e9b56cf24064f740fe78", "Atari", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bcef7880828a391cf6b50d5a6dcef719", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bd1bd6f6b928df17a702def0302f46f4", "", "", "Binary To Decimal Routine (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bd39598f067a1193ae81bd6182e756d1", "Telegames", "", "Night Stalker (1988) (Telegames) (PAL)", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bd430c2193045c68d1a20a018a976248", "", "", "Pac Ghost Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bd551ff1264f5c367a3ad7cf0d2f266c", "Bit Corporation", "R320", "SpaceMaster X-7 (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bda1463e02ae3a6e1107ffe1b572efd2", "Atari, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bdb4b584ddc90c9d2ec7e21632a236b6", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack)", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bdbaeff1f7132358ea64c7be9e46c1ac", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bdc381baf7c252c63739c5e9ed087a5c", "", "", "Vertical Ship Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bdecc81f740200780db04a107c3a1eba", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bdf1996e2dd64baf8eff5511811ca6ca", "Tron", "", "H.E.R.O. (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be060a704803446c02e6f039ab12eb91", "Parker Brothers, Rex Bradford, Sam Kjellman", "931501", "Star Wars - The Empire Strikes Back (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be1922bd8e09d74da471287e1e968653", "Cropsy", "", "Hangman Pacman Demo (Cropsy) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be2870a0120fd28d25284e9ccdcbdc99", "", "", "Tomb Raider 2600 [REV 01] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be35d8b37bbc03848a5f020662a99909", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be3f0e827e2f748819dac2a22d6ac823", "Puzzy - Bit Corporation", "PG202", "Space Tunnel (1982) (Puzzy)", "AKA Le Tunnel de L'Estace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be41463cd918daef107d249f8cde3409", "", "", "Berzerk (Voice Enhanced) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be561b286b6432cac71bccbae68002f7", "", "", "Counter Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "be929419902e21bd7830a7a7d746195d", "Activision, Garry Kitchen", "AX-025, AX-025-04", "Keystone Kapers (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "becd908f9d7bb361982c3dc02d6475c6", "Kyle Pittman", "", "THX-1138 (Kyle Pittman) (Hack)", "Hack of Berserk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bedfbde71fb606601f936b5b057f26f7", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "befce0de2012b24fd6cb8b53c17c8271", "", "", "Push (V0.03) (No Illegal Opcodes) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bf1970b692275b42c4ec0683588eb062", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bf52327c2197d9d2c4544be053caded1", "HES - Activision", "AG-930-04, AZ-030", "Decathlon (HES) (PAL) (16K)", "AKA Activision Decathlon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bf84f528de44225dd733c0e6a8e400a0", "CCE", "", "Demons to Diamonds (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" }, + { "bf976cf80bcf52c5f164c1d45f2b316b", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bfa58198c6b9cd8062ee76a2b38e9b33", "", "", "20 Sprites at Once Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bfb73aabb2489316cd5882c3cd11d9f9", "AtariAge, Chris Walton & Thomas Jentzsch", "165", "Star Castle Arcade (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "bff8f8f53a8aeb1ee804004ccbb08313", "", "", "Droid Demo 22 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "bffe34516aaa3cbf5d307eab382a7e95", "", "", "Euchre (Release Candidate) (PAL) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c00734a2233ef683d9b6e622ac97a5c8", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (03-30-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c00b65d1bae0aef6a1b5652c9c2156a1", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "c02e1afa0671e438fd526055c556d231", "Atari", "", "A-Team (Atari) (Prototype) (PAL60)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c032c2bd7017fdfbba9a105ec50f800e", "Activision, Charlie Heath", "", "Thwocker (04-09-1984) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c033dc1d7b6fde41b9cadce9638909bb", "", "", "Skeleton (V1.1) (06-09-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c0589bb73858924389077fa3c2e9441a", "SOLID Corp. (D. Scott Williamson)", "CX2655-014", "Star Castle 2600 (SolidCorp) [014]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c05f367fa4767ceb27abadf0066df7f4", "Thomas Jentzsch", "", "TomInv (31-07-2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c08d0cee43077d3055febb00e5745c1d", "HES - Activision", "", "Super Hit Pak - River Raid, Sky Jinks, Grand Prix, Fishing Derby, Checkers (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c0a68837c60e15d1fc5a40c9a62894bc", "Arcadia Corporation, Kevin Norman", "7 AR-4103", "Killer Satellites (1983) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c0c7eddefce9015346db88ade3e1e096", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics) (Prototype) (4K)", "RAM must be zero'ed to start correctly", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c0d2434348de72fa6edcc6d8e40f28d7", "SEGA - Beck-Tech, Steve Beck", "010-01", "Tapper (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1034a5bfb0bb13cc5bdf86cc58989a7", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c118854d670289a8b5d5156aa74b0c49", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c11e8473c652619ac6166900150ce215", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" }, + { "c126656df6badfa519cc63e681fb3596", "Ron Corcoran", "", "Space Invaders (2002) (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c15042e54c7408498f051d782aaa8945", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c150c76cbde2c9b5a97eb5399d46c64f", "", "", "Unknown Title (xxx00000 (200203)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c16c79aad6272baffb8aae9a7fff0864", "U.S. Games Corporation - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2001", "Gopher (1982) (U.S. Games)", "AKA Gopher Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c16fbfdbfdf5590cc8179e4b0f5f5aeb", "", "", "Wall Break (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c17bdc7d14a36e10837d039f43ee5fa3", "Spectravision - Spectravideo", "SA-203", "Cross Force (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1a83f44137ea914b495fc6ac036c493", "Atari, Carla Meninsky", "CX2660", "Star Raiders (1982) (Atari) (PAL)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1b038ce5cb6d85e956c5509b0e0d0d8", "", "", "Rotating Colors Demo 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1b1049b88bcd98437d8872d1d62ba31", "", "", "Demo Image Series #4 - Donald (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1b7aeabc3ec41556d924c8372a9ba5b", "Atari, Robert C. Polaro", "", "Dukes of Hazard (1980) (Atari) (Prototype)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1cb228470a87beb5f36e90ac745da26", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1e6e4e7ef5f146388a090f1c469a2fa", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1f209d80f0624dada5866ce05dd3399", "Telegames", "", "Deadly Discs (1988) (Telegames) (PAL)", "AKA TRON - Deadly Discs", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c1fdd44efda916414be3527a47752c75", "Parker Brothers, John Emerson", "PB5920", "G.I. Joe - Cobra Strike (1983) (Parker Bros)", "Uses the Paddle (left) and Joystick (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c20f15282a1aa8724d70c117e5c9709e", "Video Gems", "VG-02", "Surfer's Paradise (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c21450c21efb7715746e9fa87ad6f145", "Hozer Video Games", "", "Gunfight 2600 - It could've been soooo cool, but... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c216b91f5db21a093ded6a5aaec85709", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c221607529cabc93450ef25dbac6e8d2", "Eckhard Stolberg", "", "Color Test (26-09-2002) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c225379e7c4fb6f886ef9c8c522275b4", "Video Mania", "", "Frostbite (1983) (Video Mania)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c225abfb584960efe1f359fc94b73379", "", "", "Joustpong (21-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2410d03820e0ff0a449fa6170f51211", "", "", "Pac-Man (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c246e05b52f68ab2e9aee40f278cd158", "Thomas Jentzsch", "", "Star Wars - Ewok Adventure (Thomas Jentzsch) (Prototype)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2778507b83d9540e9be5713758ff945", "", "", "Island Flyer Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c28b29764c2338b0cf95537cc9aad8c9", "", "", "Multi-Color Demo 4 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c29d17eef6b0784db4586c12cb5fd454", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c29f8db680990cb45ef7fef6ab57a2c2", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2a37f1c7603c5fd97df47d6c562abfa", "Roger Williams", "", "Bar-Score Demo (2001) (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2b5c50ccb59816867036d7cf730bf75", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c2bcd8f2378c3779067f3a551f662bb7", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2c7a11717e255593e54d0acaf653ee5", "", "", "Chopper Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2c8eb642765137bb82b83a65232961f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2dea467f4a02fa1f06d66f52bc12e6e", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c2fbef02b6eea37d8df3e91107f89950", "Champ Games", "CG-02-N", "Conquest Of Mars (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c31a17942d162b80962cb1f7571cd1d5", "Home Vision - Gem International Corp. - VDI", "VCS83112", "Sky Alien (1983) (Home Vision) (PAL)", "AKA Sky Aliem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3205e3707f646e1a106e09c5c49c1bf", "", "", "Unknown Title (bin00003 (200206)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3472fa98c3b452fa2fd37d1c219fb6f", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c370c3268ad95b3266d6e36ff23d1f0c", "Atari, Alan Miller", "CX2641, CX2641P", "Surround (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3a9550f6345f4c25b372c42dc865703", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3aeb796fdaf9429e8cd6af6346f337e", "", "", "If It's Not One Thing It's Another (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3bbc673acf2701b5275e85d9372facf", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (07-21-1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3e4aa718f46291311f1cce53e6ccd79", "", "", "Hangman Ghost 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3ef5c4653212088eda54dc91d787870", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c3f53993ade534b0982ca3a286c85bb5", "", "", "Full Screen Bitmap Drawing System (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c4060a31d61ba857e756430a0a15ed2e", "Thomas Jentzsch", "", "Pick 'n Pile (2003) (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c41e7735f6701dd50e84ee71d3ed1d8f", "Dynacom", "", "Spider Fighter (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c43bd363e1f128e73ba5f0380b6fd7e3", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c446288fe62c0c2737639fd788ae4a21", "", "", "Mark's Sound Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c450a285daa7a3b65188c2c3cf04fb3e", "Wizard Video Games", "007", "Halloween (1983) (Wizard Video Games) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c469151655e333793472777052013f4f", "", "", "Base Attack (Unknown) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c471b97446a85304bbac021c57c2cb49", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software) (PAL)", "AKA Bubbles, Soap Suds, The Emphysema Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c47244f5557ae12c61e8e01c140e2173", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c47b7389e76974fd0de3f088fea35576", "Funvision - Fund. International Co.", "", "Mighty Mouse (Funvision)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c482f8eebd45e0b8d479d9b71dd72bb8", "Retroactive", "", "Push (V0.03) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c49fe437800ad7fd9302f3a90a38fb7d", "Atari, Dan Hitchens, Mimi Nyden", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c4b73c35bc2f54b66cd786f55b668a82", "Arcadia Corporation, Stephen Harland Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c4bbbb0c8fe203cbd3be2e318e55bcc0", "", "", "Atlantis (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c4bc8c2e130d76346ebf8eb544991b46", "Imagic", "", "Imagic Selector ROM (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c4d888bcf532e7c9c5fdeafbb145266a", "", "", "Space Robot (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c504a71c411a601d1fc3173369cfdca4", "Retroactive", "", "Qb (V2.02) (Stella) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c5124e7d7a8c768e5a18bde8b54aeb1d", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c517144e3d3ac5c06f2f682ebf212dd7", "Tigervision - Teldec", "7-008 - 3.60006 VG", "Miner 2049er (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c529e63013698064149b9e0468afd941", "", "", "S.I.PLIX 2 (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "c52d9bbdc5530e1ef8e8ba7be692b01e", "Atari, Robert C. Polaro", "CX26130", "Holey Moley (02-29-1984) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5301f549d0722049bb0add6b10d1e09", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" }, + { "c5387fc1aa71f11d2fa82459e189a5f0", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL)", "AKA Weltraum-Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c53c0d10c74325deae9ba84074281983", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c541a5f6fc23b40a211196dd78233780", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1981) (Atari) (Prototype) (4K)", "Uses Joystick (left) and Keypad (right) Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "c54b4207ce1d4bf72fadbb1a805d4a39", "Billy Eno", "", "Sniper (Feb 30) (2001) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c560a3ecb7b751021953819efcfe5b41", "Omegamatrix", "", "Ghostbusters (Genesis)", "Genesis controller", "", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c569e57dca93d3bee115a49923057fd7", "", "", "Pac-Space (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c58708c09ccb61625cda9d15ddcd8be6", "SPIKE the Percussionist", "", "NOIZ Invaders (SPIKE) (2002) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5930d0e8cdae3e037349bfa08e871be", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c59633dbebd926c150fb6d30b0576405", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5a76bafc4676edb76e0126fb9f0fb2d", "Charles Morgan", "", "Zero Patrol (Charles Morgan) (Hack)", "Hack of Moon Patrol", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5bab953ac13dbb2cba03cd0684fb125", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c5bf03028b2e8f4950ec8835c6811d47", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a2]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5c7cc66febf2d4e743b4459de7ed868", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1983) (Atari) (PAL) [a]", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5d2834bf98e90245e545573eb7e6bbc", "CCE", "", "Snoopy and the Red Baron (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5dd8399257d8862f3952be75c23e0eb", "Atari - GCC", "CX2680", "RealSports Tennis (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5f71dfbdca9cc96b28643ff4d06aa6f", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c5fe45f2734afd47e27ca3b04a90213c", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "c63a98ca404aa5ee9fcff1de488c3f43", "Atari", "CX26145", "Venture (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c6556e082aac04260596b4045bc122de", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c6688781f4ab844852f4e3352772289b", "Atari, Tod Frye", "CX2695", "Xevious (08-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c67ff409f28f44883bd5251cea79727d", "", "", "Gunfight 2600 - Music & Bugfixes 1 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c689148ad9275667924ab334107b517e", "Jone Yuan Telephonic Enterprise Co", "", "Space Raid (Jone Yuan)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c68a6bafb667bad2f6d020f879be1d11", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c6ae21caceaad734987cb24243793bd5", "CCE", "", "Frostbite (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c6c63da3bc2e47291f63280e057061d0", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c6d48c6ae6461e0e82753540a985ac9e", "Ed Federmeyer", "", "Edtris (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c6d7fe7a46dc46f962fe8413c6f53fc9", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype) [a]", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c6db733e0b108c2580a1d65211f06dbf", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (07-09-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c738fc3f5aae1e8f86f7249f6c82ac81", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (16K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, + { "c73ae5ba5a0a3f3ac77f0a9e14770e73", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c745487828a1a6a743488ecebc55ad44", "Rainbow Vision - Suntek", "SS-002", "Galactic (1983) (Rainbow Vision) (PAL)", "AKA The Challenge of.... Nexar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c74bfd02c7f1877bbe712c1da5c4c194", "Thomas Jentzsch", "", "River Raid Tanks (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c7600d72247c5dfa1ec1a88d23e6c85e", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c77c35a6fc3c0f12bf9e8bae48cba54b", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c77d3b47f2293e69419b92522c6f6647", "Panda", "101", "Tank Brigade (1983) (Panda)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c7900a7fe95a47eef3b325072ad2c232", "Larry Petit", "", "Super Congo Bongo (2003) (Larry Petit) (Hack)", "Hack of Bongo", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c7d5819b26b480a49eb26aeb63cc831e", "Bit Corporation", "PGP210", "Ice Hockey (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Hockey, Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c7e43ad79c5e5c029d9f5ffde23e32cf", "", "", "PAL-NTSC Detector (15-11-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c7eab66576696e11e3c11ffff92e13cc", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c7f13ef38f61ee2367ada94fdcc6d206", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c82ec00335cbb4b74494aecf31608fa1", "CCE", "", "E.T. - The Extra-Terrestrial (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c830f6ae7ee58bcc2a6712fb33e92d55", "Atari, Michael Kosaka", "CX2687", "Tempest (01-05-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c866c995c0d2ca7d017fef0fc0c2e268", "Retroactive", "", "Qb (2.00) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c880c659cdc0f84c4a66bc818f89618e", "Thomas Jentzsch", "", "Open Sesame (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c89c3138a99fd1fd54367d65f75b0244", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c8c7da12f087e8d16d3e6a21b371a5d3", "", "", "Demo Image Series #9 - Genius (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c8e90fc944596718c84c82b55139b065", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype) [a]", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c8fa5d69d9e555eb16068ef87b1c9c45", "Atari", "CX26144", "Donkey Kong Junior (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c90788d9aa71a78bcc78c015edb22c54", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL60) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c9196e28367e46f8a55e04c27743148f", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c92cfa54b5d022637fdcbdc1ef640d82", "Retroactive", "", "Qb (V2.05) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c98e8c918a40b4d3a243dd6c49196330", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (PAL60) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "c9b7afad3bfd922e006a6bfc1d4f3fe7", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c9c25fc536de9a7cdc5b9a916c459110", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c9d02d3cfeef8b48fb71cb4520a4aa84", "", "", "Euchre (More for less) (PAL) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c9e721eb29c940c2e743485b044c0a3f", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "c9f6e521a49a2d15dac56b6ddb3fb4c7", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" }, + { "ca09fa7406b7d2aea10d969b6fc90195", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ca4f8c5b4d6fb9d608bb96bc7ebd26c7", "M Network - INTV - APh Technological Consulting, Hal Finney, Glenn Hightower, Peter Kaminski", "MT4317", "Adventures of TRON (1983) (M Network)", "AKA Tron Joystick", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ca50cc4b21b0155255e066fcd6396331", "Suntek", "SS-031", "UFO Patrol (1983) (Suntek) (PAL)", "AKA X'Mission", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ca53fc8fd8b3c4a7df89ac86b222eba0", "CCE", "C-812", "Pac Man (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ca54de69f7cdf4d7996e86f347129892", "PlayAround - J.H.M.", "201", "Philly Flasher (1982) (PlayAround)", "Uses the Paddle Controllers, AKA Beat 'Em & Eat 'Em", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" }, + { "ca7aaebd861a9ef47967d31c5a6c4555", "Atari, Bob Whitehead", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ca7abc774a2fa95014688bc0849eee47", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ca7f166a94eed1a349dec6d6a358bcad", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cac9928a84e1001817b223f0cecaa3f2", "Amiga - Video Soft, Jerry Lawson, Dan McElroy", "", "3-D Genesis (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cad982c9b45bc5eff34e4ea982d5f1ca", "", "", "Song (17-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cade123747426df69570a2bc871d3baf", "Gakken", "011", "Marine Wars (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cae8f83c06831ec7bb6a3c07e98e9342", "Colin Hughes", "", "Tetris 2600 (Colin Hughes) [o1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cb18d8d5fbdcb1cd7bd36c5423348859", "", "", "RAM-Pong (NTSC) v1.0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cb24210dc86d92df97b38cf2a51782da", "Video Gems", "VG-01", "Missile Control (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cb4a7b507372c24f8b9390d22d54a918", "ITT Family Games", "554-37 338", "Peter Penguin (1983) (ITT Family Games) (PAL)", "AKA Frisco (Pumuckl-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cb8399dc0d409ff1f531ef86b3b34953", "", "", "Demo Image Series #12 - Luigi And Mario (01-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cb9626517b440f099c0b6b27ca65142c", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "cb96b0cf90ab7777a2f6f05e8ad3f694", "Silvio Mogno", "", "Rainbow Invaders", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cb9b2e9806a7fbab3d819cfe15f0f05a", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "931513", "Star Wars - Death Star Battle (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cba56e939252b05df7b7de87307d12ca", "", "", "Playfield Text Demo (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cbad928e10aeee848786cc55394fb692", "", "", "Fu Kung! (V0.06a Cuttle Cart Compatible) (15-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cbb0ee17c1308148823cc6da85bff25c", "", "", "Rotating Colors Demo 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cbc373fbcb1653b4c56bfabba33ea50d", "CCE", "", "Super Voleyball (CCE)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cbced209dd0575a27212d3eee6aee3bc", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cbd981a23c592fb9ab979223bb368cd5", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1982) (Atari)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cbe5a166550a8129a5e6d374901dffad", "Atari, Carla Meninsky - Sears", "CX2610 - 49-75127", "Warlords (1981) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, + { "cbeafd37f15e0dddb0540dbe15c545a4", "", "", "Black and White Fast Scolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cc03c68b8348b62331964d7a3dbec381", "Jone Yuan Telephonic Enterprise Co", "", "Marauder (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cc12581e079cd18330a89902625b8347", "Dave Neuman", "", "Space Battle (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cc1939e4769d0c157ace326efcfdcf80", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cc2973680c150886cce1ed8693c3aca2", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL) (4K)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cc3d942c6958bd16b1c602623f59e6e1", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cc7138202cd8f6776212ebfc3a820ecc", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (03-30-1983) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "cc724ebe74a109e39c0b2784ddc980ca", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cc74ddb45d7bc4d04c2e6f1907416699", "", "", "Colour Display Programme (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cca33ae30a58f39e3fc5d80f94dc0362", "", "", "Okie Dokie (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ccb56107ff0492232065b85493daa635", "Bit Corporation", "PG206 [demonstration cartridge]", "Bobby Is Going Home (1983) (BitCorp) (PAL) [demo cart]", "AKA Bobby geht Heim", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ccb5fa954fb76f09caae9a8c66462190", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1001", "Malagai (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ccb807eb79b0ed0f5fdc460445ef703a", "", "", "Superman (Stunt_Cycle_Rules!) (Hack)", "Hack of Superman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ccbd36746ed4525821a8083b0d6d2c2c", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [no copyright]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cccfe9e9a11b1dad04beba46eefb7351", "", "", "Poker Squares (V0.25) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ccd6ce508eee4b3fca67212833edcd85", "Otto Versand", "746422", "Hot Wave (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Ram It", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ccd92a269a4c2bd64d58cf2c0114423c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (09-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd032ab6764b55438a7b0bfb5e78595a", "", "", "Hangman Pac-Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd139ae6d09f3665ad09eb79da3f9e49", "Eric Mooney", "", "Invaders by Erik Mooney (4-24-97) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd34b3b3ef9e485201e841ba71beb253", "Bradford W. Mott", "", "Hit HMOVE At Various Cycles After WSYNC Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd38ad19f51b1048d8e5e99c86a2a655", "", "", "Demo Image Series #5 - Flag (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd399bc422992a361ba932cc50f48b65", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (Preview) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd3e26786136a4692fd2cb2dfbc1927e", "", "", "Multiple Moving Objects Demo 2 (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd4423bd9f0763409bae9111f888f7c2", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd4ded1ede63c4dd09f3dd01bda7458c", "Future Video Games", "", "Laser Gate (Future Video Games) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd568d6acb2f14477ebf7e59fb382292", "Videospielkassette - Ariola", "PGP235", "Fussball (Ariola) (PAL)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd5af682685cfecbc25a983e16b9d833", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (05-08-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd88ef1736497288c4533bcca339f881", "SEGA - Teldec", "005-10", "Buck Rogers - Planet of Zoom (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cd8fa2e9f6255ef3d3b9b5a4f24a54f7", "", "", "Daredevil (V2) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cd98be8a48ebf610c9609a688b9c57f2", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia) (Prototype)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cd9fea12051e414a6dfe17052067da8e", "Paul Slocum", "", "Marble Craze Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cda38714267978b9a8b0b24bee3529ae", "", "", "Space Instigators (V1.6) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cdadb57b34438805ee322ff05bd3d43e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cdb81bf33d830ee4ee0606ee99e84dba", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "cdc1a5c61d7488eadc9aba36166b253d", "Retroactive", "", "Qb (V0.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cddabfd68363a76cd30bee4e8094c646", "Computer Magic - CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce17325834bf8b0a0d0d8de08478d436", "", "", "Boring Freeway (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce1cbe159b9ae5992dacf09371de5e13", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (01-19-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce243747bf34a2de366f846b3f4ca772", "Home Vision - Gem International Corp. - VDI", "", "Jacky Jump (1983) (Home Vision) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce4bbe11d682c15a490ae15a4a8716cf", "", "", "Okie Dokie (Older) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce5524bb18e3bd8e092273ef22d36cb9", "Carrere Video - JWDA, Todd Marshall, Wes Trager, Henry Will IV - Teldec - Prism", "USC1004", "Commando Raid (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce5cc62608be2cd3ed8abd844efb8919", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce64812eb83c95723b04fb56d816910b", "Retroactive", "", "Qb (V2.04) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ce6c4270f605ad3ce5e82678b0fc71f8", "", "", "Vertical Rainbow Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce82a675c773ff21e0ffc0a4d1c90a71", "", "", "Defender 2 (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ce8467ae2a3a5bc88ca72a2ce44ce28c", "SOLID Corp. (D. Scott Williamson)", "CX2655-015", "Star Castle 2600 (SolidCorp) (PAL) [015]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ce89529d6e98a13ddf3d84827bbdfe68", "", "", "Kung Fu Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ce904c0ae58d36d085cd506989116b0b", "Telegames", "5687 A279", "International Soccer (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cea9f72036dc6f7af5eff52459066290", "Retroactive", "", "Qb (2.07) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ceba7965a93c689bdecdb46a5b2ac0c1", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cedbd67d1ff321c996051eec843f8716", "Ultravision", "1044", "Karate (1982) (Ultravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cef01595000627ee50863d4290372c27", "", "", "Many Blue Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cef2287d5fd80216b2200fb2ef1adfa8", "Milton Bradley Company", "4363", "Spitfire Attack (1983) (Milton Bradley)", "AKA Flight Commander)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cf0c593c563c84fdaf0f741adb367445", "Retroactive", "", "Qb (V0.05) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cf3a9ada2692bb42f81192897752b912", "", "", "Air Raiders (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cf3c2725f736d4bcb84ad6f42de62a41", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL) [a]", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cf507910d6e74568a68ac949537bccf9", "SEGA, Jeff Lorenz", "003-01", "Thunderground (1983) (SEGA)", "AKA Underground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cf63ffac9da89ef09c6c973083061a47", "CCE", "C-859", "MASH (1983) (CCE)", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cf9069f92a43f719974ee712c50cd932", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cfad2b9ca8b8fec7fb1611d656cc765b", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL) [demo cart]", "demonstration cartridge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cfb3260c603b0341d49ddfc94051ec10", "Dactari - Milmar", "", "Boxing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfb83a3b0513acaf8be4cae1512281dc", "Starpath Corporation", "", "Going-Up (1983) (Starpath) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfc226d04d7490b69e155abd7741e98c", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari) (PAL)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfce5596a7e8ca13529e9804cad693ef", "Canal 3 - Intellivision", "", "Tennis (Canal 3) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfd5518c71552b8bb853b0e461e328d7", "Bit Corporation", "R320", "Spider Fighter (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfd6a8b23d12b0462baf6a05ef347cd8", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfdb4d0427a1ea8085c6bc6eb90259d8", "", "", "Gunfight 2600 - Release Candidate (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfe2185f84ce8501933beb5c5e1fd053", "", "", "Football (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfe62ed7125ff9fae99b4c8a367c0399", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfee10bd7119f10b136921ced2ee8972", "", "", "Space Instigators (V1.8) (19-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cfef1a2d1f6a5ee7a5e1f43f3056f112", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cff1e9170bdbc29859b815203edf18fa", "Retroactive", "", "Push (V0.01) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cff578e5c60de8caecbee7f2c9bbb57b", "George Veeder", "", "Suicide Adventure (George Veeder) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "cff9950d4e650094f65f40d179a9882d", "Paul Slocum", "", "Mr. Roboto (Paul Slocum) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "cfffc4b97d01cc3e7b9f47575f7b11ec", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) (PAL60)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d00f6f8ba89559e4b20972a478fc0370", "Spiceware", "SW-01", "Medieval Mayhem (PAL)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" }, + { "d010e3dfe7366e47561c088079a59439", "Retroactive", "", "Qb (V0.10) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d026716b3c5be2c951cc4c064317c524", "", "", "Fu Kung! (V0.06) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0498baca989e792db4b8270a02b9624", "", "", "Pac Ghost Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d071d2ec86b9d52b585cc0382480b351", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d078674afdf24a4547b4b32890fdc614", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d078d25873c5b99f78fa267245a2af02", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0796a0317abf9018d6745086bef411f", "Edward Smith", "", "Alien Attack (2018)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d08fccfbebaa531c4a4fa7359393a0a9", "Activision, David Crane, Bob Whitehead", "", "Venetian Blinds Demo (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d090836f0a4ea8db9ac7abb7d6adf61e", "Hozer Video Games", "", "Yahtzee (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d09935802d6760ae58253685ff649268", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d09a7504ee8c8717ac3e24d263e7814d", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d09f1830fb316515b90694c45728d702", "Imagic, Brad Stewart", "720105-1A, IA3400", "Fire Fighter (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0a379946ed77b1b126230ca68461333", "Ataripoll", "", "Atari Invaders (Ataripoll) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0af33865512e9b6900714c26db5fa23", "Telegames", "", "Armor Ambush (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0b26e908370683ad99bc6b52137a784", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo - RCA Video Jeux", "AP-2004", "Lost Luggage (1982) (Apollo) (PAL)", "AKA La valise piegee", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0b9df57bfea66378c0418ec68cfe37f", "20th Century Fox Video Games - Sirius, Grady Ward", "11002", "Beany Bopper (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0b9f705aa5f61f47a748a66009ae2d2", "", "", "Synthcart (14-01-2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d0cb28e1b7bd6c7f683a0917b59f707e", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0cdafcb000b9ae04ac465f17788ad11", "Quelle - Otto Versand", "732.273 8 - 600273, 781644", "Lilly Adventure (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0e05ba5f10e3df3023c5ee787f760ef", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0e15a3ce322c5af60f07343594392af", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) (4K)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d0e9beb2347595c6c7d158e9d83d2da8", "Retroactive", "", "Qb (2.00) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d100b11be34a1e5b7832b1b53f711497", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d15655fe355fa57dd541487dc5725145", "Rentacom", "", "Vanguard (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d170317ae4c7d997a989c7d6567c2840", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d175258b2973b917a05b46df4e1cf15d", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d17a671029b1532b197defca5f3649a7", "Hozer Video Games", "", "Gunfight 2600 - Limit broken again! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d17a8c440d6be79fae393a4b46661164", "", "", "Warring Worms (Beta 3) (2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d1a1841b7f2007a24439ac248374630a", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d1a9478b99d6a55e13a9fd4262da7cd4", "U.S. Games Corporation, Garry Kitchen - Vidtec", "VC1001", "Space Jockey (1982) (U.S. Games) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d1b4075925e8d3031a7616d2f02fdd1f", "", "", "Demo Image Series #7 - Two Marios (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d1c3520b57c348bc21d543699bc88e7e", "Gameworld", "133-002", "Warplock (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "YES", "" }, + { "d1ca47b262f952413c1234117c4e4e21", "Bit Corporation", "R320", "Missile Command (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d1d704a7146e95709b57b6d4cac3f788", "Atari, Warren Robinett", "CX26163P", "Slot Racers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d20e61c86ed729780feca162166912ca", "Supergame", "32", "Pitfall (1984) (Supergame)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d214c7a734e133a5c18e93229435b57a", "Digivision", "", "Mickey (Digivision)", "AKA Sorcerer's Apprentice", "", "", "", "UASW", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d223bc6f13358642f02ddacfaf4a90c9", "Rainbow Vision - Suntek", "SS-003", "Pac-Kong (1983) (Rainbow Vision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d245e2f27c84016041e9496b66b722fe", "", "", "Gunfight 2600 - The Final Kernel (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d25018349c544320bf3fd5092ee072bc", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d28afe0517a046265c418181fa9dd9a1", "", "", "Dodge 'Em (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d2901c34bb6496bb96c7bc78a9e6142a", "Greg Zumwalt", "", "Fish Revenge (2003) (Greg Zumwalt) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d2c4f8a4a98a905a9deef3ba7380ed64", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1001", "Sorcerer (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d2c8e6aa8172b16c8aa9aae739ac9c5e", "Activision, David Crane", "08-08-1980", "Laser Blast (08-08-1980) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d2c957dd7746521b51bb09fde25c5774", "Eckhard Stolberg", "", "Cubis (6K) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d2d8c4f1ea7f347c8bcc7d24f45aa338", "", "", "20 Sprites at Once Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d2deddb77c8b823e4be9c57cb3c69adc", "Canal 3 - Intellivision", "C 3007", "Snoopy and the Red Baron (Canal 3)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d2f713c78a9ebba9da6d10aeefc6f20f", "Digivision", "", "Enduro (Digivision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d3171407c3a8bb401a3a62eb578f48fb", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d326db524d93fa2897ab69c42d6fb698", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d339b95f273f8c3550dc4daa67a4aa94", "", "", "Laser Blast (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d341d39774277cee6a1d378a013f92ac", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d3423d7600879174c038f53e5ebbf9d3", "U.S. Games Corporation - Western Technologies", "VC2005", "Piece o' Cake (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" }, + { "d3456b4cf1bd1a7b8fb907af1a80ee15", "Avalon Hill, Duncan Scott", "5003002", "Wall Ball (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d34b933660e29c0a0a04004f15d7e160", "", "", "Multi-Color Demo 5 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d36308387241e98f813646f346e7f9f7", "King Atari", "", "Ghostbuster 2 (King Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d39e29b03af3c28641084dd1528aae05", "Funvision - Fund. Int'l Co.", "", "Spider Monster (1982) (Funvision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d3bb42228a6cd452c111c1932503cc03", "UA Limited", "", "Funky Fish (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d44d90e7c389165f5034b5844077777f", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d45bf71871b196022829aa3b96bfcfd4", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d45ebf130ed9070ea8ebd56176e48a38", "SEGA, Jeff Lorenz", "001-01", "Tac-Scan (1983) (SEGA)", "Uses the Paddle Controllers (right only)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "YES", "" }, + { "d47387658ed450db77c3f189b969cc00", "PlayAround - J.H.M.", "206", "Westward Ho (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d4806775693fcaaa24cf00fc00edcdf3", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (1987) (Atari) (PAL)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d483f65468d9a265661917bae1a54f3e", "Joe Grand", "", "SCSIcide Pre-release 3 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d4942f4b55313ff269488527d84ce35c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d49aff83f77a1b9041ad7185df3c2277", "", "", "Space Treat (60% complete) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d4aa89e96d2902692f5c45f36903d336", "", "", "Euchre (NTSC) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d4c590ccfb611a73b3331359700c01a3", "", "", "Sprite Movement Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d541b20eae221a8ee321375e5971e766", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d54cd41ecfd59e4b72d2c086152b9a75", "Amiga - Video Soft - Michael K. Glass, Jerry Lawson", "1110", "Power Play Arcade Video Game Album (1983) (Amiga) (Prototype)", "3-D Ghost Attack only (3-D Genesis & 3-D Havoc missing in ROM)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d5618464dbdc2981f6aa8b955828eeb4", "CCE", "C-829", "Megamania (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d563ba38151b8204c9f5c9f58e781455", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d573089534ca596e64efef474be7b6bc", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL) [a]", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" }, + { "d57913088e0c49ac3a716bf9837b284f", "Activision, Garry Kitchen", "EAZ-032", "Pressure Cooker (1983) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d57eb282d7540051bc9b5427cf966f03", "Atari Troll", "", "Custer's Viagra (Atari Troll) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d597d35c6022c590d6e75e865738558a", "", "", "Sprite Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d5aa7472e7f2cc17e893a1a36f8dadf0", "", "", "Overhead Adventure Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d5c6b81212ad86fd9542a1fedaf57cae", "", "", "Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d5d2d44fb73785996ccc24ae3a0f5cef", "Robby", "", "Grand Prix (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d5e17022d1ecc20fd9b53dc464c302f1", "Activision, Carol Shaw", "EAX-020", "River Raid (1982) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d5e27051512c1e7445a9bf91501bda09", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d5e5b3ec074fff8976017ef121d26129", "Star Game", "003", "River Raid (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d5f965c159e26a1fb49a22a47fbd1dd0", "Supergame", "", "River Raid II (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d605ed12f4eaaaec3dcd5aa909a4bad7", "", "", "Chronocolor Frame Demo (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d61629bbbe035f45552e31cef7d591b2", "", "", "Atari Logo Demo (PD) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d62283aed0f4199adb2333de4c263e9c", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner", "CX2615", "Demons to Diamonds (1982) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" }, + { "d62d7d1a974c31c5803f96a8c1552510", "", "", "StarMaster (Unknown) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d632b74fea533d593af82cf16e7c5e4a", "", "", "Fu Kung! (V0.13) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d65028524761ef52fbbdebab46f79d0f", "CCE", "", "Galaxian (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d65900fefa7dc18ac3ad99c213e2fa4e", "", "", "Guntest (2000) (Eckhard Stolberg)", "Light Gun Test (based on Sentinel code)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d69559f9c9dc6ef528d841bf9d91b275", "Activision, Alan Miller", "AX-016", "StarMaster (1982) (Activision)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d6a44277c3eb4f9d039185e0ecf7bfa6", "", "", "Trick (1997) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d6acff6aed0f04690fe4024d58ff4ce3", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL) [different spaceship]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d6b8beeb05e5b730084d4b8f381bbf8d", "", "", "208 in 1 Game Select ROM (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d6d1ddd21e9d17ea5f325fa09305069c", "Funvision - Fund. International Co.", "", "Time Warp (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d6d5dd8fd322d3cf874e651e7b6c1657", "", "", "How to Draw a Playfield (1997) (Nick Bensema) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d6dc9b4508da407e2437bfa4de53d1b2", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb) (PAL)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d726621c676552afa503b7942af5afa2", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d73ad614f1c2357997c88f37e75b18fe", "Goliath", "7", "Space Tunnel (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d74a81fcd89c5cf0bd4c88eb207ebd62", "", "", "Poker Squares (V0.00a) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d763e3a9cdcdd56c715ec826106fab6a", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d7759fa91902edd93f1568a37dc70cdb", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d782543818b6320e4f60d77da2b596de", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d787ec6785b0ccfbd844c7866db9667d", "Retroactive", "", "Qb (V0.04) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d7891b0faa4c7f764482762d0ed427a5", "", "", "Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d7b2259f6bb57bf37eac82365c1f8ad6", "Parker Brothers, Mike Brodie", "PB5320", "Super Cobra (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d7b58303ec8d8c4dbcbf54d3b9734c7e", "", "", "Paddle Demo (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d7dd56677e4ec1e6627419478a4a9668", "", "", "Shadow Keep (Fixed) (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d7f5bf138cfc7feab7b8ef1534c8b477", "", "", "Eric Bergstrom's KC-135 (Radar Map) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d816fea559b47f9a672604df06f9d2e3", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d81bb6965e6c99b3be99ffd8978740e4", "", "", "Gunfight 2600 - The Final Kernel Part 3 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d82675ce67caf16afe5ed6b6fac8aa37", "Thomas Jentzsch", "", "Robot City (V0.23) (13-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d8295eff5dcc43360afa87221ea6021f", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d82c8a58098a6b46c5b81c16180354d1", "Dennis Debro", "", "Climber 5 (30-10-2002) (Dennis Debro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d85f1e35c5445ac898746719a3d93f09", "Suntek", "SS-034", "Farmyard Fun (1983) (Suntek) (PAL)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d86deb100c6abed1588aa84b2f7b3a98", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d88691c995008b9ab61a44bb686b32e4", "", "", "Warring Worms (07-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d89262907e70c13dff23356c4a9055d0", "Bit Corporation", "R320", "Video Pinball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d89fedded0436fdeda7c3c37e2fb7cf1", "", "", "Surround (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d8acaa980cda94b65066568dd04d9eb0", "CCE", "", "Sea Hunt (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d8b2c81cea5af04f795eb3dc6573d72b", "", "", "Tunnel Demo 2 (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d8df256c0d89e494a9fb3e9abb8e44ac", "Imagic, Michael Greene", "IA3312P", "No Escape! (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d8e4c8e2d210270cd1e0f6d1b4582b91", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d90205e29bb73a4cdf28ea7662ba0c3c", "Thomas Jentzsch", "", "Boulderdash Demo (Brighter Version) (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d912312349d90e9d41a9db0d5cd3db70", "CCE", "C-818", "Star Voyager (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d9548ad44e67edec202d1b8b325e5adf", "Apollo - Games by Apollo, Dan Oliver - RCA Video Jeux", "AP-2002", "Space Cavern (1982) (Apollo) (PAL)", "AKA Les guerriers de l'espace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d968de2b4ff18bfe4a95066cde310578", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d97e3d0b4575ce0b9a6132e19cfeac6e", "Fabrizio Zavagli", "", "Space Treat (061002) (PD)", "Won't work with Stella < V1.2", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d97fd5e6e1daacd909559a71f189f14b", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (04-20-1983) (M Network) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d9ab6b67a17da51e5ad13717e93fa2e2", "Thomas Jentzsch", "", "Turbo (Coleco) Prototype Fake v0.1 (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d9b49f0678776e04916fa5478685a819", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d9bd343533b61389b270c0787210943b", "Atari, Douglas 'Solaris' Neubauer", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Genesis controller (C switches to map mode)", "Hack of Last Starfighter (Solaris prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "d9c9cece2e769c7985494b1403a25721", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "d9da2ae7c7894a29b43b3c6b79f3b7a2", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, + { "d9fbf1113114fb3a3c97550a0689f10f", "ZiMAG - Emag - Vidco", "713-111 - GN-050", "Pizza Chef (1983) (ZiMAG) (Prototype)", "AKA Pizza Time", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "da0fb2a484d0d2d8f79d6e063c94063d", "", "", "Air Raiders (1982) (Unknown) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "da4e3396aa2db3bd667f83a1cb9e4a36", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "da5096000db5fdaa8d02db57d9367998", "Digitel", "", "River Raid (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "da6465a34d2e44d26aa9a2a0cd1bce4d", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "da66d75e4b47fab99733529743f86f4f", "Digitel", "", "Chopper Command (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "da732c57697ad7d7af414998fa527e75", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari) (PAL)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "da79aad11572c80a96e261e4ac6392d0", "Salu - Ubi Soft, Dennis M. Kiss", "460673", "Pick 'n' Pile (1990) (Salu) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "da7a17dcdaa62d6971393c0a6faf202a", "", "", "Flag Capture (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dab844deed4c752632b5e786b0f47999", "", "", "Super Challenge Baseball (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dac38b4dd3da73bb7b2e9d70c61d2b7c", "", "", "Hangman Monkey Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dac5c0fe74531f077c105b396874a9f1", "Atari - GCC", "CX2680", "RealSports Tennis (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dac762e4d01d445bdef20b7771f6570e", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K) [a]", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" }, + { "dad2ab5f66f98674f12c92abcfbf3a20", "", "", "Blue and White Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "daeb54957875c50198a7e616f9cc8144", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11005", "Mega Force (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "daef7d8e5a09981c4aa81573d4dbb380", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack)", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "dafc3945677ccc322ce323d1e9930beb", "Atari", "", "A-Team (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "db1753cc702c18d3917ec7f3b0e8659f", "", "", "Frame Counter 2 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "db339aea2b65b84c7cfe0eeab11e110a", "", "", "Chronocolor Frame Demo 2 (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "db4eb44bc5d652d9192451383d3249fc", "CBS Electronics - E.F. Dreyer - VSS, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "db5073bd75eb05f7d62a7268396d1e77", "Atari", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "db76f7a0819659d9e585f2cdde9175c7", "Xonox", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "db80d8ef9087af4764236f7b5649fa12", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "db971b6afc9d243f614ebf380af0ac60", "Gammation, Robert L. Esken Jr.", "", "Gamma-Attack (1983) (Gammation)", "Uses right joystick controller", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dba270850ae997969a18ee0001675821", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (4K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "dbabb80e92ff18d8eecf615c0539151e", "", "", "Sprite Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dbb10b904242fcfb8428f372e00c01af", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dbba14a0f69f0e13fdccb3fde3baedca", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dbc7485ad5814d466de780a3e7ed3b46", "Kyle Pittman", "", "Pink Floyd (Kyle Pittman) (PD)", "Hack of Adventures of Tron (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dbc8829ef6f12db8f463e30f60af209f", "Data Age", "DA1001", "Encounter at L-5 (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, + { "dbdaf82f4f0c415a94d1030271a9ef44", "CCE", "", "Kaboom! (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "dbdd21e1ee3d72119e8cd14d943c585b", "", "", "Slot Machine (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dc13df8420ec69841a7c51e41b9fbba5", "Atari, Mimi Nyden, Steve Woita", "CX26132", "Garfield (06-21-1984) (Atari) (Prototype)", "AKA Garfield on the Run", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dc33479d66615a3b09670775de4c2a38", "Suntek", "SS-033", "I.Q. Memory Teaser (1983) (Suntek) (PAL)", "AKA IQ 180", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dc81c4805bf23959fcf2c649700b82bf", "Imagic, Michael Greene", "720055-2A, IA3312P", "No Escape! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dc905b22de0f191a029df13eddfcabc4", "Atari, Warren Robinett", "", "Elf Adventure (05-02-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dc97cbcf091a5ef4ca7fe95dc0848036", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dca90ea1084a2fdbe300d7178ca1a138", "Imagic, Dennis Koble", "IA3000P", "Trick Shot (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "dca941dab5c6f859b71883b13ade9744", "", "", "Hangman Pac-Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dcba0e33aa4aed67630a4b292386f405", "Retroactive", "", "Qb (V2.08) (Half Speed Version) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "dcc2956c7a39fdbf1e861fc5c595da0d", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5664", "Frogs and Flies (1982) (M Network)", "AKA Frogs 'n' Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dcec46a98f45b193f07239611eb878c2", "", "", "Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd08e18cfee87a0e7fc19a684b36e124", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd0cbe5351551a538414fb9e37fc56e8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd0de0f61af2a2a4878e377b880a3933", "SOLID Corp. (D. Scott Williamson)", "CX2655-013", "Star Castle 2600 (SolidCorp) [013]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "dd10b5ee37fdbf909423f2998a1f3179", "", "", "Space Instigators (V1.9) (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd13a16d14100819f79b1ce3a5bf499c", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd1422ffd538e2e33b339ebeef4f259d", "Atari, Michael Sierchio", "", "Football Demo (1982) (Atari)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd17711a30ad60109c8beace0d4a76e8", "", "", "Karate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd1842ba0f3f9d94dccb21eaa0f069b7", "Bit Corporation", "R320", "Defender (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd45e370aceff765f1e72c619efd4399", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd4f4e0fbd81762533e39e6f5b55bb3a", "Thomas Jentzsch", "", "Turbo WIP (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd7598b8bcb81590428900f71b720efb", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd7884b4f93cab423ac471aa1935e3df", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "dd8a2124d4eda200df715c698a6ea887", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dd92d6ad50976f881d86b52d38616118", "SpkSoft", "", "River Raid (SpkSoft) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dda23757407c4e217f64962c87ad0c82", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack) [a]", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ddd1efc1862cd3eb3baf4cba81ff5050", "", "", "Max3 (2001) (Maxime Beauvais) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de0173ed6be9de6fd049803811e5f1a8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99008, 6240", "Motocross Racer (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de07e9cb43ad8d06a35f6506e22c62e9", "", "", "Oh No! (Version 4) (22-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de1a636d098349be11bbc2d090f4e9cf", "", "", "Pressure Gauge (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de1e9fb700baf8d2e5ae242bffe2dbda", "Activision - Imagineering, Mike Reidel", "EAK-043-04I", "Commando (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de24f700fd28d5b8381de13abd091db9", "CCE", "", "Plaque Attack (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de29e46dbea003c3c09c892d668b9413", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "4L1717, 4L1718, 4L1719, 4L2277", "Carnival (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de3d0e37729d85afcb25a8d052a6e236", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "de4436eaa41e5d7b7609512632b90078", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de5aab22e5aba5edcb29a3e7491ff319", "Star Game", "001", "Donkey Kong (Star Game)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de61a0b171e909a5a4cfcf81d146dbcb", "Rainbow Vision - Suntek", "SS-005", "Tom Boy (1983) (Rainbow Vision) (PAL)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de62f8a30298e2325249fe112ecb5c10", "CCE", "C-810", "Enduro (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de78b3a064d374390ac0710f95edde92", "Bomb - Onbase", "CA281", "Assault (1983) (Bomb)", "AKA Sky Alien", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de7a64108074098ba333cc0c70eef18a", "", "", "Nuts (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de7bca4e569ad9d3fd08ff1395e53d2d", "Thomas Jentzsch", "", "Thrust (V1.22) (2000) (TJ)", "Supports BoosterGrip", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "de8443ff47283e7b274a7838cb071fb6", "Atari, Lou Harp", "CX26122", "Sinistar (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dea0ade296f7093e71185e802b500db8", "CCE", "", "Fishing Derby (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "deb39482e77f984d4ce73be9fd8adabd", "Activision, David Lubar", "AK-048-04", "River Raid II (1988) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ded26e1cb17f875a9c17515c900f9933", "", "", "Space Treat (29-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df12953b919844dad2070ed2e70c9fa2", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype) (PAL)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df2745d585238780101df812d00b49f4", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df3e6a9b6927cf59b7afb626f6fd7eea", "", "", "Tuby Bird (208 in 1) (Unknown) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df40af244a8d68b492bfba9e97dea4d6", "Franklin Cruz", "", "Asteroids 2 (Franlin Cruz) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "df5cc5cccdc140eb7107f5b8adfacda1", "Cracker Jack Productions", "", "Lumberman (Cracker Jack) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df62a658496ac98a3aa4a6ee5719c251", "Atari, Tom Reuterdahl - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari)", "AKA Arcade Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df6a28a89600affe36d94394ef597214", "Apollo - Games by Apollo, Dan Oliver", "AP-2002", "Space Cavern (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df6a46714960a3e39b57b3c3983801b5", "Puzzy - Bit Corporation", "PG201", "Sea Monster (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df753cb87d3af4d03f694ab848638108", "CBS Electronics, Bob Curtiss", "4L1845, 4L1852, 4L1853, 4L1854", "Solar Fox (1983) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df91277a3569344b89e6e8bd5bebc8d1", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "df95e4af466c809619299f49ece92365", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (06-03-1983) (Atari) (Prototype) (PAL)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dfad86dd85a11c80259f3ddb6151f48f", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dfafa3fa58f5cc3f0342cca475df6095", "", "", "Space Treat (V1.1 Beta) (24-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dfc03ef371cf5163f54c50d8ee73c8cf", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dfc3dbbb39f05d7dd8ee3ac987478970", "", "", "Imagic Selector ROM (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dfcdd6f593bb7b05dbc2e8e1fc6ee0de", "", "", "Gunfight 2600 - Scenarios complete (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dfe034297200dff672df9533ed1449a9", "", "", "Sprite Movement Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dfe6aa7443bb813cefa35a4cf4887422", "", "", "This Planet Sucks (Greg Troutman) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "dff33523ccd2fdc8912e84cab8e0d982", "", "", "Fu Kung! (V0.03) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e01e00504e6d4b88fa743c0bbe8a96e5", "", "", "Qb (Special Edition, some bugfixes) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e020f612255e266a8a6a9795a4df0c0f", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (PAL)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e02156294393818ff872d4314fc2f38e", "Sancho - Tang's Electronic Co.", "TEC005", "Dice Puzzle (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e0221c95aa657f5764eeeb64c8429258", "", "", "Tomb Raider 2600 [REV 02] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e03b0b091bea5bc9d3f14ee0221e714d", "CBS Electronics, Bob Curtiss", "4L1852, 4L1853, 4L1854, 4L1855", "Solar Fox (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e040df95a055b18ebdb094e904cb71b2", "", "", "Score Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e04f1c1e4401d584d3f4343410a5bcc4", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e0b24c3f40a46cda52e29835ab7ad660", "Quelle - Otto Versand", "626.502 9 - 746381", "Top Gun (1983) (Quelle) (PAL)", "AKA Air Raiders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e0cf2dcc4c1348c468f5bb1e421c9164", "", "", "Invader Sprites in a Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e0de3773f5b867795db557be7b8a703e", "", "", "Boulderdash (13 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e0eff071f578ecf19edc2ab276644e46", "", "", "Gas Gauge Demo (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1029676edb3d35b76ca943da7434da8", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (10-30-1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e10bf1af6bf3b4a253c5bef6577fe923", "Rob Kudla", "", "Space Invaders (1978) (Atari) [h1]", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e10d2c785aadb42c06390fae0d92f282", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1143b72a30d4d3fee385eec38b4aa4d", "", "", "Word Zapper (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e12e32dee68201b6765fcd0ed54d6646", "Atari, Larry Kaplan", "CX2612, CX2612P", "Street Racer (1977) (Atari) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 75", "", "", "", "" }, + { "e13818a5c0cb2f84dd84368070e9f099", "CCE", "C-839", "Misterious Thief, A (1983) (CCE)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e13c7627b2e136b9c449d9e8925b4547", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1486c7822c07117b4f94a32e5ed68c1", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-14-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e14dc36b24fe22c04fa076e298f2e15f", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (16K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "e14feddeb82f5160ed5cf9ca4078e58d", "", "", "SpaceMaster X-7 (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e150f0d14f013a104b032305c0ce23ef", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e15b5525cf8f77297b322838df8d999c", "", "", "Sprite Demo 0 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e171558c51bb3bac97bfa79fa2c1a19c", "", "", "Warring Worms (Tim Strauss Edition) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e17699a54c90f3a56ae4820f779f72c4", "Rainbow Vision - Suntek", "SS-020", "Tuby Bird (1983) (Rainbow Vision) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e18abe87035379c56b435bfe8175077b", "Grimlock", "", "Rumble 2600 (Grimlock) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1a51690792838c5c687da80cd764d78", "20th Century Fox, John Russell", "", "Alligator People (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1b90f1e01b1a316d7bbf141525cc00e", "", "", "Sky Jinks (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1d5c8213e82820128fa9c4775f1e166", "Jess Ragan", "", "Jungle King (2003) (Jess Ragan) (Hack)", "Hack of Jungle Hunt", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1d79e4e7c150f3861256c541ec715a1", "", "", "Space Jockey (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1e09e2f280e8e142121a377d0dc1b46", "Thomas Jentzsch", "", "Thrust (V1.21) (2000) (TJ)", "Bugfixed", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1efe2ef7664bb6758b1a22ff8ea16a1", "Dynacom", "", "Enduro (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e1f88da6da8a7d521ca1dcbf2bc6978b", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e21ee3541ebd2c23e817ffb449939c37", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001", "King Kong (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e227be19f572f6900e314213ae9a4deb", "Atari, Dan Hitchens, Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (Prototype)", "AKA Adventure I, SwordQuest I - EarthWorld", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e237ee91514d5ed535c95a14fc608c11", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e2389c0be5b5b84e0d3ca36ec7e67514", "Retroactive", "", "Qb (V2.09) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e24d7d879281ffec0641e9c3f52e505a", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype)", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e25e173740f7ecc0e23025445c4591f3", "Greg Zumwalt", "", "Comitoid (Greg Zumwalt)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e275cbe7d4e11e62c3bfcfb38fca3d49", "M Network - INTV - APh Technological Consulting, Ken Smith", "MT5658", "Super Challenge Football (1982) (M Network)", "AKA Pro Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e27d518993b0a010f16e92b971ecdcdd", "Manuel Polik", "", "Star Fire (2003) (XYPE) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e28113d10c0c14cc3b5f430b0d142fcb", "CCE", "C-816", "Keystone Kappers (1983) (CCE) [a]", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e2846af3e4d172b251ab77cbdd01761e", "Steve Engelhardt", "", "Adventure Plus (2003) (Steve Engelhardt) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e2904748da63dfefc8816652b924b642", "Jone Yuan Telephonic Enterprise Co", "", "Catch Time (Jone Yuan)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e2b682f6e6d76b35c180c7d847e93b4f", "", "", "Dodge Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e2c1b60eaa8eda131632d73e4e0c146b", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e2c89f270f72cd256ed667507fa038a2", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e2ca84a2bb63d1a210ebb659929747a9", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys) (PAL)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e2eccbbe963f80f291cb1f18803bf557", "Atari, Joe Decuir, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e30f3a37032da52d7815b5a409f6d4b4", "SEGA, Fred Mack", "", "Bear Game Demo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e314b42761cd13c03def744b4afc7b1b", "Activision, David Crane, Dan Kitchen", "AZ-108-04", "Ghostbusters (1985) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e34c236630c945089fcdef088c4b6e06", "Activision, Steve Cartwright, David Crane - Ariola", "EAB-035-04 - 711 035-721", "Pitfall II (1984) (Activision) (PAL)", "Lost Caverns", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e3533684a7ef930a7fbd0c4dd8ec4847", "CCE", "C-856", "Pimball (1983) (CCE)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e3600be9eb98146adafdc12d91323d0f", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e363e467f605537f3777ad33e74e113a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e377c3af4f54a51b85efe37d4b7029e6", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e37c8055d70979af354251ebe9f1b7dd", "HES", "", "Mega Funpak - Gorf, P. Patrol, Pacman, Skeet Shoot (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e38dc1f81a02e325562cd285123f579b", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e39843c56b7a4a08b18fa7949ec3ee6b", "", "", "Joshua Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e39a13b13dc82c5fdbfbbfd55ba1230e", "", "", "Analog Clock (Additional Frame Info) (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e3c0451d29dad724231bc5818ec4bae0", "", "", "Single-Scanline Positioning Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e3c35eac234537396a865d23bafb1c84", "TechnoVision - Video Technology", "TVS1001", "Nuts (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e3ed4ba3361756970f076e46e9cad1d2", "", "", "Tennis (Unknown) (PAL) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e40a818dac4dd851f3b4aafbe2f1e0c1", "Atari, Bill Aspromonte, Dr. Lee Salk", "CX26135", "Peek-A-Boo (1984) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e42b937c30c617241ca9e01e4510c3f6", "", "", "Pitfall! (No Walls Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e434c0e161dd3c3fb435eb6bad2e182c", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e48d3a4056ede9393586421996db1ae8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e49ac0ec879a0d7820bc2598fc2cfcd4", "CCE", "", "Kaboom! (CCE) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "e4a0b28befaaa2915df1fa01238b1e29", "", "", "Gunfight 2600 - Red River (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4afe157c09962cf39cdb25845d83d47", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4b12deaafd1dbf5ac31afe4b8e9c233", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack) [a]", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e4bff1d5df70163c0428a1ead309c22d", "Atari, Robert C. Polaro, Alan J. Murphy", "CX2609, CX2609P", "Defender (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4c00beb17fdc5881757855f2838c816", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4c2077a18e3c27f4819aa7757903aa0", "", "", "Many Blue Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4c666ca0c36928b95b13d33474dbb44", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e4d41f2d59a56a9d917038682b8e0b8c", "Cody Pittman", "", "Kiss Meets Pacman (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4e9125a8741977583776729359614e1", "SnailSoft", "", "Comitoid beta 4 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e4fa739c81b003c92bea7da5e84c7feb", "Akor", "", "TV Boy (1992) (Akor) (NTSC) [bad dump]", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "e505bd8e59e31aaed20718d47b15c61b", "Funvision - Fund. Int'l Co.", "", "Space War (1982) (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e51030251e440cffaab1ac63438b44ae", "Parker Brothers - On-Time Software, Joe Gaucher, Louis Marbel", "PB5110", "James Bond 007 (1984) (Parker Bros)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e51c23389e43ab328ccfb05be7d451da", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e5359cbbbff9c6d7fe8aeff5fb471b46", "CCE", "C-849", "Boom Bang (1983) (CCE)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e549f1178e038fa88dc6d657dc441146", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e556e07cc06c803f2955986f53ef63ed", "Coleco - Individeo, Ed Temple", "2665", "Front Line (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e558be88eef569f33716e8e330d2f5bc", "Shock Vision", "", "Keystone Kapers (Shock Vision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e56da674188ba2f02c7a0a343a01236f", "", "", "This Planet Sucks Demo 4 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e59d022d524d05acc19515598c831e4d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118 (PAL)", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e5a6e0bb7d56e2f08b237e15076e5699", "", "", "Color Table Display Helper (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e5bacf526036d3c8c99db5b030cf00e7", "", "", "Starmaster (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Starmaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e5d5085123a98c1e61818caa2971e999", "", "", "Euchre (PAL) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e5d72ff8bab4450be57785cc9e83f3c0", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames) (PAL)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e5ecd78edd24326a968809decbc7b916", "Imagic, Bob Smith", "720020-1A, IA3611", "Cheese (Dragonfire Beta) (05-21-1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e5f17b3e62a21d0df1ca9aee1aa8c7c5", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid)", "AKA Termite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e5f360226dc552aba3e7e9b202330f48", "Supercat", "", "Mega Bitmap Demo (2007) (Supercat)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e5f84930aa468db33c0d0f7b26dd8293", "CCE", "C-826", "Grand Prix (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e5fcc62e1d73706be7b895e887e90f84", "", "", "Air-Sea Battle (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e600f5e98a20fafa47676198efe6834d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e609e8a007127b8fcff79ffc380da6b1", "", "", "Multi-Sprite Game V2.3 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e61210293b14c9c4ecc91705072c6a7e", "Gameworld", "133-005", "Bugs (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" }, + { "e62e60a3e6cb5563f72982fcd83de25a", "Jone Yuan Telephonic Enterprise Co", "", "End of the World (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e63a87c231ee9a506f9599aa4ef7dfb9", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e63efdfda9a4003dcd77a854a781a06a", "Paul Slocum", "", "Combat Rock (PD) (Hack) [a]", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e643aaec9a9e1c8ab7fe1eae90bc77d7", "Roger Williams", "", "Asymmetric Playfield (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e64a8008812327853877a37befeb6465", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1002", "Gauntlet (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e6508b878145187b87b9cded097293e7", "", "", "Oystron (V2.8) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e66e5af5dea661d58420088368e4ef0d", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e67b0ed32fd9d28d12ab3775d52e8c3a", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" }, + { "e6d5948f451a24994dfaaca51dfdb4e1", "Jone Yuan Telephonic Enterprise Co", "", "Football (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e6de4ef9ab62e2196962aa6b0dedac59", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-2A, 13206", "Solar Storm (1983) (Imagic) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, + { "e6e5bb0e4f4350da573023256268313d", "Thomas Jentzsch", "", "Missile Control (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e6f49a1053c79211f82be4d90dc9fe3d", "", "", "Gunfight 2600 - Little progress... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e723ad8f406cb258b89681ef4cef0eff", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "e72eb8d4410152bdcb69e7fba327b420", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e72ee2d6e501f07ec5e8a0efbe520bee", "Imagic, Dave Johnson", "720119-2A, 13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e73838c43040bcbc83e4204a3e72eef4", "CCE", "", "Apples and Dolls (CCE)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e74022cfe31ec8908844718dfbdedf7a", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e77ec259e1387bc308b0534647a89198", "Parker Brothers, David Lamkins, Laura Nikolich", "931503", "Spider-Man (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e77f332b71f13884c84771e7a121182d", "Jone Yuan Telephonic Enterprise Co", "", "Hey! Stop! (Jone Yuan)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e784a9d26707cfcd170a4c1c60422a72", "Quelle", "147.443 6", "Gefecht im All (1983) (Quelle) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e7864caaf9ec49ed67b1904ce8602690", "", "", "Donkey Kong 2K3 Pic (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e7a758bb0b43d0f7004e92b9abf4bc83", "", "", "Troll's Adventure (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e7dd8c2e6c100044002c1086d02b366e", "Activision, Steve Cartwright - Ariola", "EAX-013, PAX-013, 711 013-720", "Barnstorming (1982) (Activision) (PAL)", "AKA Die tollkeuhnen Flieger", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e7f005ddb6902c648de098511f6ae2e5", "Spectravideo - Universum", "SV-010", "CompuMate (1983) (Spectravideo) (PAL)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "", "", "COMPUMATE", "", "", "", "", "", "", "", "", "YES", "80" }, + { "e800e4aec7c6c54c9cf3db0d1d030058", "", "", "Qb (2.06) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e80a4026d29777c3c7993fbfaee8920f", "", "", "Frisco (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e823b13751e4388f1f2a375d3560a8d7", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (Preview) (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e879b7093ac4cfad74c88d636ca97d00", "", "", "Poker Squares (V0.0f) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e88340f5bd2f03e2e9ce5ecfa9c644f5", "", "", "Lock 'n' Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e8a3473bf786cf796d1336d2d03a0008", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-05-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e8aa36e3d49e9bfa654c25dcc19c74e6", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX2601, CX2601P", "Combat (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e8e7b9bdf4bf04930c2bcaa0278ee637", "", "", "Boring Taz (Hack)", "Hack of Taz", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e8f7679359c4f532f5d5e93af7d8a985", "", "", "Hangman Invader Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e9034b41741dcee64ab6605aba9de455", "Digivision", "", "Phanton Tank (Digivision)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e908611d99890733be31733a979c62d8", "Atari, Dan Hitchens, Mimi Nyden", "CX2697", "Mario Bros. (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e91d2ecf8803ae52b55bbf105af04d4b", "Atari, Howard Scott Warshaw", "CX2655, CX2655P", "Yars' Revenge (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e923001015bedd7901569f035d9c592c", "", "", "Adventure II (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e927ecf80f3784d745abd8368d78f2f3", "", "", "Space Instigators (V1.8) (19-10-2002) (CT) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e932f44fad2a66b6d5faec9addec208e", "", "", "Atari Logo Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e94632b0d863dd76459d689a9865bb33", "Jone Yuan Telephonic Enterprise Co", "", "Combat (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e957eb4612d6bd5940d3492dfa749668", "", "", "Tunnel Demo (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e959b5a2c882ccaacb43c32790957c2d", "", "", "Phantom II & Pirate (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e97eafd0635651d3999cece953c06bd5", "", "", "M.A.S.H (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e9be3e8e4a7e73dd63ed4235a3a1a25f", "", "", "MMetall (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e9c5d04643855949a23ff29349af74ea", "", "", "SCSIcide (Score Hack 2) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e9c71f8cdba6037521c9a3c70819d171", "Action Hi Tech - Hi-Score", "", "Bank Heist (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e9cb18770a41a16de63b124c1e8bd493", "Parker Brothers - Roklan, Joe Gaucher", "931519", "Popeye (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "e9db2f91efe6ff7ea3546e2c2578fb09", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" }, + { "e9e646f730b8400cd5da08c849ef3e3b", "Tron", "", "Enduro (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e9e6ad30549a6e2cd89fe93b7691d447", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (05-27-1987) (Atari) (Prototype) (PAL)", "AKA Nile Flyer, Sphinx", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "e9f25c7af4f27c9e1b5b8f6fe6141e8c", "Champ Games", "CG-03-N", "Scramble (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ea38fcfc06ad87a0aed1a3d1588744e4", "Atari, Lou Harp", "CX26122", "Sinistar (01-XX-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ea6d40db5498d6386571a76df448aa4c", "", "", "Vertical Playfield Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ea7e25ade3fe68f5b786ee0aa82b1fe5", "", "", "Galatic (208 in 1) (Unknown) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ea832e2cb6aae6f525f07452c381fa48", "", "", "Polar to Cartesian and VV (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ea86176b27ab0da8cce8f0179884bfaa", "", "", "Demo Image Series #10 - It's Art (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eaacfcdc1d4ee1258429b7ae7f084125", "Telegames", "6057 A227", "Quest for Quintana Roo (1989) (Telegames)", "Genesis controller (B is action button, C chooses tool or weapon)", "Hack of Quest for Quintana Roo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ead60451c28635b55ca8fea198444e16", "Sancho - Tang's Electronic Co.", "TEC004", "Nightmare (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eada0dd61ce13f8317de774dc1e68604", "", "", "2600 Digital Clock (Demo 1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eae0c06ee61c63b81cd016096fc901b0", "Joe Grand", "", "SCSIcide (v1.0) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eae6a5510055341d3abeb45667bb3e9b", "HES", "", "Wall Defender (HES) (PAL)", "AKA Wall Break (Planet Patrol if right difficulty = 'A')", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eaf744185d5e8def899950ba7c6e7bb5", "Atari", "CX26172", "Xenophobe (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eafe8b40313a65792e88ff9f2fe2655c", "Eric Ball", "ELB004", "Skeleton+ (NTSC)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eb3d680699f8762f71f38e28e321234d", "", "", "Fu Kung! (V0.01) (08-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eb4252faff7a4f2ba5284a98b8f78d1a", "", "", "John K Harvey's Equalizer (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "eb46e99ec15858f8cd8c91cef384ce09", "Goliath - Hot Shot", "83-113", "Ground Zero (1983) (Goliath) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eb503cc64c3560cd78b7051188b7ba56", "Star Game", "043", "Moto Laser (Star Game)", "AKA Mega Force", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eb634650c3912132092b7aee540bbce3", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "eb6d6e22a16f30687ade526d7a6f05c5", "Atari", "CX26150P", "Q-bert (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eb71743c6c7ccce5b108fad70a326ad9", "", "", "Euchre (25-11-2001) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eb7934360658a29c50aeaff20bfda23b", "Activision, John Van Ryzin", "EAZ-036-04", "H.E.R.O. (1984) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eb92193f06b645df0b2a15d077ce435f", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "eb9712e423b57f0b07ccd315bb9abf61", "Retroactive", "", "Qb (V2.04) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "eb9f8b84c193d9d93a58fca112aa39ed", "", "", "Register Twiddler Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ebcb084a91d41865b2c1915779001ca7", "JVP", "", "Bob Is Going Home (JVP)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ebcbc8a181a738e13df6216e5c329230", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ebd2488dcace40474c1a78fa53ebfadf", "Skill Screen Games, Herman Quast", "SSG001", "Extra Terrestrials (1984) (SSG)", "The only Canadian-designed and manufactured Atari 2600 game from the 1980's", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ebdc5716b85c4ff44fa357cb697d6cef", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ebf2dff78a08733251bf3838f02f7938", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ebf9038e927e6a0db3e0d170c59911e6", "", "", "Pac-2600 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ec3beb6d8b5689e867bafb5d5f507491", "U.S. Games Corporation - Vidtec - JWDA, Todd Marshall, Henry Will IV", "VC1003", "Word Zapper (1982) (U.S. Games)", "AKA Word Grabber", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ec407a206b718a0a9f69b03e920a0185", "Quelle", "876.482 1", "Landung in der Normandie (1983) (Quelle) (PAL)", "AKA Commando Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ec5c861b487a5075876ab01155e74c6c", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ece463abde92e8b89bcd867ec71751b8", "Puzzy - Bit Corporation", "PG205", "Dancing Plate (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ece908d77ab944f7bac84322b9973549", "", "", "Tom Boy (Unknown) (PAL60)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ecf51385384b468834611d44a8429c03", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ecfa04523dde82fe42cdc7315a8f61b6", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL) (4K)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed014beeeb77dbb2bbcf9b5f6850b2f4", "", "", "Green Bar Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed0451010d022b96a464febcba70b9c4", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ed0ab909cf7b30aff6fc28c3a4660b8e", "Panda", "105", "Stunt Man (1983) (Panda)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed1306436ce237afc5a7ed3f77134202", "HES", "771-341", "2 Pak Special - Dolphin, Pigs n' Wolf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed1492d4cafd7ebf064f0c933249f5b0", "CCE", "", "Video Cube (CCE)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed1a784875538c7871d035b7a98c2433", "Bit Corporation", "R320", "Save Our Ship (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed2218b3075d15eaa34e3356025ccca3", "Atari, Richard Maurer", "CX2635, CX2635P", "Maze Craze (1980) (Atari) (PAL)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed5ccfc93ad4561075436ee42a15438a", "Atari, Tom Reuterdahl", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ed8f319e82d355832195eb7715644795", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (8K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "eddef10fdc0029301064115ae0cd41d4", "CCE", "", "Freeway (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ede4ab11ca346bd023b2c21d941e0c50", "Activision, David Crane", "EAZ-030", "Decathlon (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ede7e8bf865b0afb4744f86d13624f9a", "", "", "Demo Image Series #2 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "edf69b123e06eaf8663cc78d8aeba06e", "SpkSoft 98", "", "River Raid (SpkSoft 98) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee28424af389a7f3672182009472500c", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee456542b93fa8d7e6a8c689b5a0413c", "", "", "Chronocolor Donkey Kong Clean (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee4c186123d31a279ed7a84d3578df23", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner", "CX2608", "Super Breakout (1982 - 1981) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" }, + { "ee659ae50e9df886ac4f8d7ad10d046a", "Exus Corporation", "", "Video Reflex (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee6665683ebdb539e89ba620981cb0f6", "Coleco", "2658", "Berenstain Bears (1983) (Coleco)", "Uses the KidVid Controller", "Unbelievably Rare", "", "", "", "A", "", "", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "", "", "" }, + { "ee67dc0b01746372d2b983d88f48e24f", "", "", "Scroller Demo (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee681f566aad6c07c61bbbfc66d74a27", "Activision", "", "Unknown Activision Game (10-29-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee6cbedf6c0aac90faa0a8dbc093ffbe", "CCE", "", "My Golf (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee8027d554d14c8d0b86f94737d2fdcc", "Canal 3 - Intellivision", "", "Yars' Revenge (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "ee84bdc5dae268e227e407c7b5e6b6b7", "", "", "Marilyn Monroe Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ee9caee4eb958284fb10c277b14537f1", "Carrere Video, Garry Kitchen - Teldec", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eea0da9b987d661264cce69a7c13c3bd", "Coleco", "2454", "Zaxxon (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eeb92f3f46df841487d1504f2896d61a", "Cody Pittman", "", "Corys Adventure (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eec61cc4250df70939d48fe02d7122ac", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eed9eaf1a0b6a2b9bc4c8032cb43e3fb", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "eee7695ae3eea7818321df0b790b31f3", "", "", "Sound Paddle V2 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "ef263d40a23483ab339cac44d9515a56", "Thomas Jentzsch", "", "Fatal Run (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ef3a4f64b6494ba770862768caf04b86", "Activision, Bob Whitehead", "AG-034-04", "Private Eye (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ef60b06fddb675b0d783afbfa5fc5232", "", "", "Many Blue Bars and Text Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ef66af190840871409fe1702d2483554", "Andrew Davie, Paul Slocum, Christopher Tumber", "", "DiscoTech (12-02-2003) (Andrew Davie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ef71e9fb0d8d477226d8d42261fbf0a7", "Piero Cavina", "", "Multi-Sprite Demo V2.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ef76ea05655a0b62cb1018c92b9b4b7d", "Gakken", "010", "Strategy X (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "efa1098c7d091b940c2543abe372f036", "Scott Stilphen", "", "E.T. The Extra-Terrestrial (Scott Stilphen) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "efb47d70b2965ce689e2c5757616b286", "", "", "Time Test Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "efd387430a35a659ff569a9a0ec22209", "Atari - GCC", "CX26118", "Millipede (1984) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "efefc02bbc5258815457f7a5b8d8750a", "CBS Electronics, Richard K. Balaska Jr.", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "effa3a7ce078c6d83bf43174a7bfdb1f", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "efffafc17b7cb01b9ca35324aa767364", "", "", "Circus Atari (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f02ba8b5292bf3017d10553c9b7b2861", "Atari", "CX26172", "Xenophobe (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f032b2f2d8323404a6b4541f92dd1825", "", "", "Many Blue Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f047df70d3d08e331122cd2de61d6af8", "Dave Neuman", "", "Space Battle (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f04ee80011d95798006378643650aaa7", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0510abbfbe24ead552e92e3841f63f3", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0536303f49006806bac3aec15738336", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0541d2f7cda5ec7bab6d62b6128b823", "Atari, Paul Donaldson", "", "Bionic Breakthrough (1984) (Atari) (Prototype)", "Uses Mindlink Controller (left only)", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f060826626aac9e0d8cda0282f4b7fc3", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0631c6675033428238408885d7e4fde", "Paul Slocum", "", "Test Cart (2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f066bea7ab0a37b83c83c924a87c5b67", "", "", "Air Raiders (1982) (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0a6e99f5875891246c3dbecbf2d2cea", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0b7db930ca0e548c41a97160b9f6275", "Atari, Larry Wagner, Bob Whitehead - Sears", "CX2645 - 49-75181", "Video Chess (1979) (Atari)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0cacae1d1b79ee92f0dc035f42e0560", "", "", "Boring Donkey Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0d393dbf4164a688b2346770c9bbd12", "", "", "Racquetball (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f0daaa966199ef2b49403e9a29d12c50", "", "", "Mr. Postman (Unknown)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0de4f49e95d529569e8788d5a7b4d30", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0e0addc07971561ab80d9abe1b8d333", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f0ef9a1e5d4027a157636d7f19952bb5", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a5]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f10e3f45fb01416c87e5835ab270b53a", "Suntek", "SS-024", "Ski Run (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1127ade54037236e75a133b1dfc389d", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f11cfab087fcbd930ab8b0becc5b2e5a", "Canal 3 - Intellivision", "", "River Raid (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f12afbffa080dd3b2801dd14d4837cf6", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f137211537438b1fce3d811baef25457", "", "", "Incoming (02-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1489e27a4539a0c6c8529262f9f7e18", "Champ Games", "CG-01-P", "Lady Bug (PAL60)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f14d5e96ec3380aef57a4b70132c6677", "Goliath - Hot Shot", "83-414", "Pac Kong (1983) (Goliath) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1554569321dc933c87981cf5c239c43", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f16c709df0a6c52f47ff52b9d95b7d8d", "Atari, Alan Miller - Sears", "CX2662 - 6-99811", "Hangman (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f16ef574d2042ed8fe877d6541f4dba4", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1929bb9b5db22d98dd992aa3fe72920", "", "", "Cube Conquest (Improved Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f19aba18f86e415812480ad2be221425", "Chris Larkin", "", "Solaris Trainer (2002) (Chris Larkin) (Hack)", "Hack of Solaris", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1a0a23e6464d954e3a9579c4ccd01c8", "20th Century Fox, Douglas 'Dallas North' Neubauer", "11006", "Alien (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f1ae6305fa33a948e36deb0ef12af852", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f1b2ea568b3e156e3f2849dac83591f6", "", "", "Sprite Demo (1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1b7edff81ceef5af7ae1fa76c8590fc", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1beca5a198cf08190487e5c27b8e540", "", "", "Fu Kung! (V0.16) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1e375d921858467166e53bcec05803f", "Jeffry Johnston", "", "Radial Pong - Version 3 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f1eeeccc4bba6999345a2575ae96508e", "Video Gems", "VG-03", "Steeplechase (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f1fe06ebe2900eac4cdd17799389a102", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f20675c8b98518367b9f5b8ee6f7c8ea", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f20bd756f3990e06c492f53cd0168e68", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f21813aa050437f0dbc8479864acec6d", "", "", "Sneak 'n Peek (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f23d19b73dac50cc6149316912b8ee53", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f240ba9f8092d2e8a4c7d82c554bf509", "Quelle", "463.860 7", "Strahlen der Teufelsvoegel (1983) (Quelle) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f280976d69d6e27a48506bd6bad11dcd", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "f283cc294ece520c2badf9da20cfc025", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "f28c07767b3e90a2689ade5b5e305874", "Canal 3 - Intellivision", "C 3014", "Keystone Kapers (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f2d40c70cf3e1d03bc112796315888d9", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f2d4d6187903cac2d5ea8ed90dad120d", "Digimax", "", "River Raid II (Digimax)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f2e4fb2d3600c0f76d05864e658cc57b", "", "", "Marble Craze (Kernel) (17-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f2f2cb35fdef063c966c1f5481050ea2", "", "", "Ram It (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f2f59629d7341c97644405daeac08845", "Jone Yuan Telephonic Enterprise Co", "", "Bobby Is Going Home (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f303630a2d7316787aecd67fff6b2e33", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f3213a8a702b0646d2eaf9ee0722b51c", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari) (4K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f33f1d0f7819c74148dacb48cbf1c597", "Retroactive", "", "Qb (2.00) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f344ac1279152157d63e64aa39479599", "Tigervision", "7-012", "Espial (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f34dd3b8156aaf113cb621b2e51d90b8", "Joe Grand", "", "SCSIcide Pre-release 5 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f34f08e5eb96e500e851a80be3277a56", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" }, + { "f367e58667a30e7482175809e3cec4d4", "ZiMAG - Emag - Vidco", "708-111 - GN-040", "Cosmic Corridor (1983) (ZiMAG)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f38358cd8f5ecfedffd5aca1aa939f18", "Universal Gamex Corporation, Alan Roberts", "1005", "X-Man (1983) (Universal) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f39e4bc99845edd8621b0f3c7b8c4fd9", "AtariAge", "", "Toyshop Trouble (AtariAge)", "F8 Emulator Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f3c431930e035a457fe370ed4d230659", "", "", "Crackpots (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f3cd0f886201d1376f3abab2df53b1b9", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f3dfae774f3bd005a026e29894db40d3", "Otto Versand", "649635", "See Saw (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "f3f5f72bfdd67f3d0e45d097e11b8091", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Submarine Commander (1982) (Sears)", "AKA Seawolf 3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f3f92aad3a335f0a1ead24a0214ff446", "", "", "Spectrum Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f40e437a9ebf0bdfe26204152f74f868", "Bit Corporation", "R320", "Jawbreaker (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f4204fc92d17ed4cb567c40361ad58f1", "Inky", "", "Beanie Baby Bash (Inky) (Hack)", "Hack of Beany Bopper", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f4469178cd8998cb437fa110a228eaca", "Digitel", "", "Frostbite (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f45644ff82b533a781a1ee50f2e95f3c", "", "", "Overhead Adventure Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f457674cef449cfd85f21db2b4f631a7", "U.S. Games Corporation - JWDA, Todd Marshall, Wes Trager, Henry Will IV", "VC1004", "Commando Raid (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f473f99e47d4026a7a571184922ebf04", "Philip R. Frey", "", "Donkey Claus (Philip R. Frey) (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f48022230bb774a7f22184b48a3385af", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, + { "f48735115ec302ba8bb2d2f3a442e814", "", "", "Dancing Plate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f49a34f1fdd7dc147cbf96ce2ce71b76", "", "", "Qb (Special Edition) (PAL) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f4a09f906cc37be31224433f576d77d3", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f4ab6bd5f80d8988141edde4c84b23b5", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f4b8a47a95b61895e671c3ec86ffd461", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (01-03-1984) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f4c2e50b01dff99bddbe037b3489511c", "", "", "Hypnotic (V0.04) (2001) (Inkling) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f4c6621f1a0b4d27081123c08d7d1497", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f4cf6881b65c424095dc25dc987f151f", "", "", "128 in 1 Game Select ROM (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f4dabd5bcc603e8464a478208037d423", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (08-21-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f526d0c519f5001adb1fc7948bfbb3ce", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1003", "Star Fox (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f52f40299fd238c6ffd9e6107050dc76", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f539e32bf6ce39c8ca47cb0cdd2c5cb8", "Control Video Corporation", "", "GameLine Master Module ROM (1983) (Control Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f542b5d0193a3959b54f3c4c803ba242", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f5445b52999e229e3789c39e7ee99947", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f5a2f6efa33a3e5541bc680e9dc31d5b", "Suntek", "SS-022", "Motocross (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f5a3e051730d45fea518f2e8b926565b", "Robby", "", "Keystone Kapers (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f5aa6bd10f662199c42e43863a30106c", "", "", "Music Kit (V1.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f5d103a9ae36d1d4ee7eef657b75d2b3", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (Preview) (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f613aad84d2163d6b197b220bfec1b7e", "", "", "X-Doom V.27 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f661f129644f338b13d9f4510d816c03", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f6676e3fe901eb8515fc7ae310302c3c", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f67181b3a01b9c9159840b15449b87b0", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (08-27-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f687ec4b69611a7f78bd69b8a567937a", "Activision, Alan Miller - Ariola", "EAZ-028 - 711 028-725", "Robot Tank (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f69a39b215852a0c2764d2a923c1e463", "", "", "Move a Blue Blob Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f69bb58b815a6bdca548fa4d5e0d5a75", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f69d4fcf76942fcd9bdf3fd8fde790fb", "CCE", "", "Aquaventure (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f6a282374441012b01714e19699fc62a", "ZiMAG - Emag - Vidco", "710-111 - GN-010", "I Want My Mommy (1983) (ZiMAG)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f6a9ea814d15b85bffe980c927df606b", "", "", "Missile Command (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f6b5ebb65cbb2981af4d546c470629d7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype) [a]", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f6c13e816e58c8c62f82b2c8b91a2d67", "", "", "Scrolling Playfield 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f6d512bef1bf253dc935d0e13c3d1462", "", "", "Slot Racers (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f6daebc0424fa0f8d9aaf26c86df50f4", "Brian Watson", "", "Color Tweaker (V1.0) (2001) (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f6efa00ae99aaf33e427b674bcfd834d", "", "", "2600 Digital Clock (Demo 3) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f6f1b27efc247a0e8d473ddb4269ff9e", "Rainbow Vision - Suntek", "SS-015", "Catch Time (1983) (Rainbow Vision) (PAL)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f70e3f3bb2d19ec2aaec8f78dc43744f", "Jone Yuan Telephonic Enterprise Co", "", "Pooyan (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f714a223954c28eccf459295517dcae6", "", "", "Big - Move This Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7154add27b95cd90464dbed8cfd7557", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f724d3dd2471ed4cf5f191dbb724b69f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f736864442164b29235e8872013180cd", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f73d2d0eff548e8fc66996f27acf2b4b", "CCE", "C-813", "Pitfall (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7424985bac41067502b4a05b64cb75a", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "Genesis controller (B is fire up, C is fire down)", "Hack of Plaque Attack", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f74ad642552385c3daa203a2a6fc2291", "Eckhard Stolberg", "", "Cubis (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f750b5d613796963acecab1690f554ae", "Manuel Polik", "", "Gunfight 2600 (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f75872946e82ad74d48eae5bc28f5f0e", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (04-15-1980) (Sears) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f777444fc21a5925e066b68b1d350575", "", "", "Marble Craze (Kernel Works) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f77f5fc3893da5d00198e4cd96544aad", "Canal 3 - Intellivision", "", "Stampede (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7856e324bc56f45b9c8e6ff062ec033", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) [no opening tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f78c125b5da483c41e51522947d6c4ce", "", "", "Sound Paddle V1 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" }, + { "f7a138eed69665b5cd1bfa796a550b01", "Tigervision - Teldec", "7-012 - 3.60016 VC", "Espial (1984) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7a651972d78f9ba485b14690452d4be", "Paul Slocum", "", "Homestar Runner Demo #2 (2004-03-29)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f7af41a87533524d9a478575b0d873d0", "Quelle", "495.663 7", "Spiderman (1983) (Quelle) (PAL)", "AKA Spider-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7d6592dcb773c81c278140ed4d01669", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7e07080ed8396b68f2e5788a5c245e2", "Video Game Cartridge - Ariola", "TP-617", "Farmyard Fun (Ariola)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7ec2f2bdbe8fbea048c0d5fa6503b0b", "Akor", "", "TV Boy (1992) (Akor) (PAL)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" }, + { "f7f50d9c9d28bcc9f7d3075668b7ac89", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f7fac15cf54b55c5597718b6742dbec2", "Spiceware", "SW-01", "Medieval Mayhem (NTSC)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" }, + { "f802fa61011dd9eb6f80b271bac479d0", "Suntek", "SS-023", "Mole Hunter (1983) (Suntek) (PAL)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f80cf77164079d774b9b0fae33dffca9", "", "", "Fu Kung! (V0.15) (Negative Version) (05-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8240e62d8c0a64a61e19388414e3104", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f825c538481f9a7a46d1e9bc06200aaf", "Atari, Richard Maurer - Sears", "CX2635 - 49-75157", "Maze Craze (1980) (Atari)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" }, + { "f844f4c6f3baaaf5322657442d6f29eb", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f847fb8dba6c6d66d13724dbe5d95c4d", "Absolute Entertainment, David Crane", "AG-042-02, AG-042-04", "Skate Boardin' (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8582bc6ca7046adb8e18164e8cecdbc", "", "", "Panda Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8648d0c6ad1266434f6c485ff69ec40", "CCE", "", "Oink! (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8811d45a9935cca90c62f924712f8e6", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8b2a6a4d73ebff10d805a9b59041986", "Activision, Larry Kaplan - Ariola", "EAX-006, PAX-006 - 771 006-720", "Bridge (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8bfd99163d2c4ec688357786e6fba28", "", "", "Eckhard Stolberg's Scrolling Text Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8c1c4a41303bd40b0d6c81bfaf8573b", "HES", "773-891", "2 Pak Special - Dungeon Master, Creature Strike (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8fbe2b07345086fc867bceeaf38dc48", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f8ff34b53d86f55bd52d7a520af6d1dc", "", "", "Big Dig (04-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f90b5da189f24d7e1a2117d8c8abc952", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f91fb8da3223b79f1c9a07b77ebfa0b2", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner - Sears", "CX2615 - 49-75140", "Demons to Diamonds (1982) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" }, + { "f93d7fee92717e161e6763a88a293ffa", "20th Century Fox Video Games - Lazer Micro Systems - Dunhill Electronics, B. Winston Hendrickson, Randall Hyde, Mark V. Rhoads, John Simonds", "11013", "Porky's (1983) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9420173efcb4b9f2b01c2a7b595cca7", "CCE", "", "Laser Blast (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f954381f9e0f2009d1ac40dedd777b1a", "Thomas Jentzsch", "", "Robot City (V0.18) (01-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9655ed51462ecfc690c7b97cec649f9", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f965cc981cbb0822f955641f8d84e774", "Answer Software Corporation - TY Associates, Kim Ellis", "ASC2001", "Confrontation (1983) (Answer) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "f9660ebed66fee8bdfdf07b4faa22941", "VGS", "", "Vanguard (VGS)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9677b2ec8728a703eb710274474613d", "Atari, Ian Shepard", "CX2604, CX2604P", "Space War (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f97dee1aa2629911f30f225ca31789d4", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, Jim Jacob", "5005002", "Out of Control (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f98d2276d4a25b286135566255aea9d0", "Digitel", "", "Name This Game (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f98d869f287d2ce4f8fb36e0686929d9", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f991e0670b5f67faa6b6211e9bd81b91", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f992a39b46aa48188fab12ad3809ae4a", "", "", "Sky Jinks (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9967369943209b4788d4e92cefc0795", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9cef637ea8e905a10e324e582dd39c2", "CCE", "", "Private Eye (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9d51a4e5f8b48f68770c89ffd495ed1", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9da42f91a1c5cfa344d2ff440c6f8d4", "ZUT", "", "Pac Invaders (ZUT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9de91d868d6ebfb0076af9063d7195e", "", "", "Maze Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "f9e99596345a84358bc5d1fbe877134b", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" }, + { "fa0570561aa80896f0ead05c46351389", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fa1b060fd8e0bca0c2a097dcffce93d3", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" }, + { "fa2be8125c3c60ab83e1c0fe56922fcb", "Camelot - DSD, Michael Doherty, Clyde Hager - Johnson & Johnson", "", "Tooth Protectors (1983) (Camelot)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fa3de71841c0841db6a741884a6b6b2f", "", "", "Warring Worms (17-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fa4404fabc094e3a31fcd7b559cdd029", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fa529ec88eca679f6d5fd0ccb2120e46", "", "", "20 Sprites at Once Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fa6fe97a10efb9e74c0b5a816e6e1958", "ZiMAG - Emag - Vidco", "707-111 - GN-030", "Tanks But No Tanks (1983) (ZiMAG)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fa7ce62e7fd77e02b3e2198d70742f80", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-18-1983) (Atari) (Prototype) (PAL)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fa7e11a3dbea4365975cd2f094e61d25", "Tim Snider", "", "Mystery Science Theater 2600 (1999) (Tim Snider) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fa98d48cd609c9babc819e0a1bd8d598", "AtariAge (Chris Walton)", "", "Juno First (2009) (PAL60)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "YES", "" }, + { "fab7b04b9f42df761eb6f2bc445eaa99", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (11-04-1982) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fabca526d57de46768b392f758f1a008", "", "", "Laseresal 2600 (16-12-2001) (Andrew Wallace) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fac28963307b6e85082ccd77c88325e7", "CCE", "", "Berzerk (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fadb89f9b23beb4d43a7895c532757e2", "Galaga Games", "", "River Raid (1984) (Galaga Games) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fae0b86934a7c5a362281dffebdb43a0", "Retroactive", "", "Qb (2.07) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "faebcb2ef1f3831b2fc1dbd39d36517c", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari) (PAL)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "faed2ef6b44894f8c83f2b50891c35c6", "CCE", "", "Super Baseball (CCE)", "AKA RealSports Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "faffd84f3a8eceee2fa5ea5b0a3e6678", "Suntek", "SS-025", "Spectracube Invasion (1983) (Suntek) (PAL)", "AKA Immies & Aggies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb09ee4ccd47ae74a3c314f0d8a40344", "", "", "Titans (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb0c32ef7af5b45486db663510094be8", "", "", "Demo Image Series #15 - Three Marios (NTSC) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb0e84cee4c108d24253bcb7e382cffd", "", "", "Interleaved ChronoColour Demo (SECAM) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb27afe896e7c928089307b32e5642ee", "M Network - INTV - APh Technological Consulting, Jeff Ronne, Brett Stutz", "MT5662", "TRON - Deadly Discs (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb4ca865abc02d66e39651bd9ade140a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb531febf8e155328ec0cd39ef77a122", "", "", "Worm War I (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fb5c8af97bd8ffe88323656f462645a7", "", "", "Interlace Demo (Glenn Saunders)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fb833ed50c865a9a505a125fc9d79a7e", "ITT Family Games", "", "Pumuckl I (1983) (ITT Family Games) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb884ffd89013331a6f01ae3f6abd214", "Activision, David Crane", "", "Venetian Blinds Demo (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb88baa01afd34e0e4b601e1d29bc806", "Manuel Polik", "", "Star Fire (2003) (XYPE)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb88c400d602fe759ae74ef1716ee84e", "20th Century Fox Video Games, Bill Aspromonte", "11031", "Crash Dive (1983) (20th Century Fox)", "AKA Voyage to the Bottom of the Sea", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb91da78455d9b1606913fbf8c859772", "", "", "Split Screen (Ballblazer) Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fb91dfc36cddaa54b09924ae8fd96199", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fb978f1c053e8061cc37a726639f43f7", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fbac6476e7b2b20d246202af81662c88", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fbb0151ea2108e33b2dbaae14a1831dd", "Thomas Jentzsch", "", "Robot Tank TV (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Robot Tank", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fbb4f3debf48dc961b559384467f2057", "Digitel", "", "River Raid III (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fbe554aa8f759226d251ba6b64a9cce4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fbfebee9c14694719e3eda4854dc42ee", "Jake Patterson", "", "Baubles 3 (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fc2104dd2dadf9a6176c1c1c8f87ced9", "Coleco - Woodside Design Associates, Harley H. Puthuff Jr.", "2663", "Time Pilot (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fc2233fc116faef0d3c31541717ca2db", "Atari, Tod Frye", "CX2646", "Pac-Man (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fc24a94d4371c69bc58f5245ada43c44", "Atari - Axlon, Steve DeFrisco", "CX26170", "Secret Quest (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fc6052438f339aea373bbc999433388a", "Atari, David Crane", "CX2653P", "Slot Machine (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fc668a2251dd79cbd903d4fa0e558f96", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fc92d74f073a44bc6e46a3b3fa8256a2", "", "", "Megademo (19xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fc9c1652fe3a2cade6188f4d3692481f", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fca4a5be1251927027f2c24774a02160", "Activision, John Van Ryzin", "AZ-036-04", "H.E.R.O. (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fcbbd0a407d3ff7bf857b8a399280ea1", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fcbdf405f0fc2027b0ea45bb5af94c1a", "Amiga - Video Soft, Michael K. Glass, Jerry Lawson", "", "3-D Ghost Attack (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fcea12625c071ddc49f4e409f4038c60", "Fabrizio Zavagli", "", "Balls! (16-09-2002) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, + { "fcf8e306f6615f74feba5cb25550038c", "", "", "Blue Dot Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd0e5148162e8ec6719445d559f018a9", "Activision, Steve Cartwright - Ariola", "EAX-022, EAX-022-04I - 711 022-720", "Seaquest (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd10915633aea4f9cd8b518a25d62b55", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd16949913aaab5beaefed73bf2ca67c", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-03-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd4f5536fd80f35c64d365df85873418", "Atari - Bobco, Robert C. Polaro", "CX26140", "Desert Falcon (1987) (Atari)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd6e507b5df68beeeddeaf696b6828fa", "", "", "Boxing (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd7464edaa8cc264b97ba0d13e7f0678", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd78f186bdff83fbad7f97cb583812fe", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a2]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd8b4ee0d57605b35e236e814f706ff1", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fd9b321cee5fbb32c39ba3ca5d9ec7cf", "Jeffry Johnston", "", "Radial Pong - Version 5 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fdd4995a50395db14f518f63c2d63438", "", "", "Oh No! (Version 3) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fde42e39710e75e9e4d4d75440f8e4e5", "Thomas Jentzsch", "", "Coke Zero (v1.0) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fdf0de38517e0cf7f0885f98ccc95836", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fdf6680b2b1e8054293a39700a765692", "", "", "Alpha Demo - The Beta Demo 2 (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fe0b7f27e3ad50bbf9ff468ee56d553d", "", "", "Lines Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fe0bc4bb92c1c4de7d5706aaa8d8c10d", "", "", "Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fe3b461d4c8b179fe68bc77760294c25", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "", "", "", "", "" }, + { "fe641247a4ab9bee970e19ab55f23b25", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (02-07-1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fe67087f9c22655ce519616fc6c6ef4d", "Atari - Zip Technology, Randy Bowker, Bruce Williams", "CX26142", "Crack'ed (11-28-1988) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fe6abc0f63e31e2646c9c600926b5b7f", "Atari", "CX26137", "4 in 1 (02-19-1987) (Atari) (Prototype)", "Home Run, Canyon Bomber, Sky Diver, Night Driver", "Prototype", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fe870018332a0221eb59fb18b0c6bccc", "", "", "Incoming (08-11-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fe9ae625d924b54c9f8a14ac9a0f6c6d", "BG Dodson", "", "High Bid! (BG Dodson) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "feba8686fd0376015258d1152923958a", "", "", "Super Circus (Unknown) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fec0c2e2ab0588ed20c750b58cf3baa3", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "EAZ-037-04, EAZ-037-04I", "Beamrider (1984) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "fece458a8023a809a5006867feca40e8", "", "", "SCSIcide (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "feec54aac911887940b47fe8c9f80b11", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" }, + { "feedcc20bc3ca34851cd5d9e38aa2ca6", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "10", "", "", "", "" }, + { "ff1523783e0e76a3b0d1f7f0d1cb3050", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ff3bd0c684f7144aeaa18758d8281a78", "Atari, Bob Whitehead", "CX2651", "Blackjack (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ff5a9e340d96df6f5a5b6eb038e923bd", "", "", "Space Shuttle (1983) (Activision) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ff7627207e8aa03730c35c735a82c26c", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ff86fc8ffa717bb095e8471638c1c31c", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" }, + { "ff87d58125ae517eb7b09a0475a1ccdc", "", "", "SCSIcide (Score Hack 1) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ffb1cd548563158ce33f9d10268187e7", "Erik Eid", "", "Euchre (Beta) (NTSC) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ffc0ff4305dd46b4b459885bd1818e2e", "Barry Laws Jr.", "", "Star Wars - The Battle of Alderaan (Star Strike Hack)", "Hack of Star Strike (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ffdc0eb3543404eb4c353fbdddfa33b6", "CCE", "C-827", "Chopper Command (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ffe51989ba6da2c6ae5a12d277862e16", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari) (4K)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "ffebb0070689b9d322687edd9c0a2bae", "", "", "Spitfire Attack (1983) (Milton Bradley) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" } }}; #endif diff --git a/src/emucore/Driving.cxx b/src/emucore/Driving.cxx index bd08a03e0..490759e63 100644 --- a/src/emucore/Driving.cxx +++ b/src/emucore/Driving.cxx @@ -21,22 +21,40 @@ #include "Driving.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Driving::Driving(Jack jack, const Event& event, const System& system) +Driving::Driving(Jack jack, const Event& event, const System& system, bool altmap) : Controller(jack, event, system, Controller::Type::Driving) { if(myJack == Jack::Left) { - myCCWEvent = Event::JoystickZeroLeft; - myCWEvent = Event::JoystickZeroRight; - myFireEvent = Event::JoystickZeroFire; + if(!altmap) + { + myCCWEvent = Event::JoystickZeroLeft; + myCWEvent = Event::JoystickZeroRight; + myFireEvent = Event::JoystickZeroFire; + } + else + { + myCCWEvent = Event::JoystickTwoLeft; + myCWEvent = Event::JoystickTwoRight; + myFireEvent = Event::JoystickTwoFire; + } myXAxisValue = Event::PaddleZeroAnalog; myYAxisValue = Event::PaddleOneAnalog; } else { - myCCWEvent = Event::JoystickOneLeft; - myCWEvent = Event::JoystickOneRight; - myFireEvent = Event::JoystickOneFire; + if(!altmap) + { + myCCWEvent = Event::JoystickOneLeft; + myCWEvent = Event::JoystickOneRight; + myFireEvent = Event::JoystickOneFire; + } + else + { + myCCWEvent = Event::JoystickThreeLeft; + myCWEvent = Event::JoystickThreeRight; + myFireEvent = Event::JoystickThreeFire; + } myXAxisValue = Event::PaddleTwoAnalog; myYAxisValue = Event::PaddleThreeAnalog; } diff --git a/src/emucore/Driving.hxx b/src/emucore/Driving.hxx index 35a02b2c1..863132890 100644 --- a/src/emucore/Driving.hxx +++ b/src/emucore/Driving.hxx @@ -33,11 +33,12 @@ class Driving : public Controller Create a new Indy 500 driving controller plugged into the specified jack - @param jack The jack the controller is plugged into - @param event The event object to use for events - @param system The system using this controller + @param jack The jack the controller is plugged into + @param event The event object to use for events + @param system The system using this controller + @param altmap If true, use alternative mapping */ - Driving(Jack jack, const Event& event, const System& system); + Driving(Jack jack, const Event& event, const System& system, bool altmap = false); ~Driving() override = default; public: diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 88d546ba2..d0e04e1fd 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -618,11 +618,23 @@ unique_ptr OSystem::openConsole(const FilesystemNode& romfile, string& CMDLINE_PROPS_UPDATE("sp", PropType::Console_SwapPorts); CMDLINE_PROPS_UPDATE("lc", PropType::Controller_Left); + CMDLINE_PROPS_UPDATE("lq1", PropType::Controller_Left1); + CMDLINE_PROPS_UPDATE("lq2", PropType::Controller_Left2); CMDLINE_PROPS_UPDATE("rc", PropType::Controller_Right); - const string& s = mySettings->getString("bc"); - if(s != "") { - props.set(PropType::Controller_Left, s); - props.set(PropType::Controller_Right, s); + CMDLINE_PROPS_UPDATE("rq1", PropType::Controller_Right1); + CMDLINE_PROPS_UPDATE("rq2", PropType::Controller_Right2); + const string& bc = mySettings->getString("bc"); + if(bc != "") { + props.set(PropType::Controller_Left, bc); + props.set(PropType::Controller_Right, bc); + } + const string& aq = mySettings->getString("aq"); + if(aq != "") + { + props.set(PropType::Controller_Left1, aq); + props.set(PropType::Controller_Left2, aq); + props.set(PropType::Controller_Right1, aq); + props.set(PropType::Controller_Right2, aq); } CMDLINE_PROPS_UPDATE("cp", PropType::Controller_SwapPaddles); CMDLINE_PROPS_UPDATE("ma", PropType::Controller_MouseAxis); diff --git a/src/emucore/Props.cxx b/src/emucore/Props.cxx index 144955c9c..dfef72a97 100644 --- a/src/emucore/Props.cxx +++ b/src/emucore/Props.cxx @@ -51,7 +51,11 @@ void Properties::set(PropType key, const string& value) case PropType::Console_TVType: case PropType::Console_SwapPorts: case PropType::Controller_Left: + case PropType::Controller_Left1: + case PropType::Controller_Left2: case PropType::Controller_Right: + case PropType::Controller_Right1: + case PropType::Controller_Right2: case PropType::Controller_SwapPaddles: case PropType::Controller_MouseAxis: case PropType::Display_Format: @@ -249,7 +253,11 @@ void Properties::print() const << get(PropType::Console_TVType) << "|" << get(PropType::Console_SwapPorts) << "|" << get(PropType::Controller_Left) << "|" + << get(PropType::Controller_Left1) << "|" + << get(PropType::Controller_Left2) << "|" << get(PropType::Controller_Right) << "|" + << get(PropType::Controller_Right1) << "|" + << get(PropType::Controller_Right2) << "|" << get(PropType::Controller_SwapPaddles) << "|" << get(PropType::Controller_PaddlesXCenter) << "|" << get(PropType::Controller_PaddlesYCenter) << "|" @@ -296,7 +304,11 @@ void Properties::printHeader() << "Console_TVType|" << "Console_SwapPorts|" << "Controller_Left|" + << "Controller_Left1|" + << "Controller_Left2|" << "Controller_Right|" + << "Controller_Right1|" + << "Controller_Right2|" << "Controller_SwapPaddles|" << "Controller_PaddlesXCenter|" << "Controller_PaddlesYCenter|" @@ -325,7 +337,11 @@ std::array Properties::ourDefaultProperties = "COLOR", // Console.TVType "NO", // Console.SwapPorts "AUTO", // Controller.Left + "", // Controller.Left1 + "", // Controller.Left2 "AUTO", // Controller.Right + "", // Controller.Right1 + "", // Controller.Right2 "NO", // Controller.SwapPaddles "0", // Controller.PaddlesXCenter "0", // Controller.PaddlesYCenter @@ -353,7 +369,11 @@ std::array Properties::ourPropertyNames = "Console.TVType", "Console.SwapPorts", "Controller.Left", + "Controller.Left1", + "Controller.Left2", "Controller.Right", + "Controller.Right1", + "Controller.Right2", "Controller.SwapPaddles", "Controller.PaddlesXCenter", "Controller.PaddlesYCenter", diff --git a/src/emucore/Props.hxx b/src/emucore/Props.hxx index 70e9fa727..8f280312c 100644 --- a/src/emucore/Props.hxx +++ b/src/emucore/Props.hxx @@ -35,7 +35,11 @@ enum class PropType : uInt8 { Console_TVType, Console_SwapPorts, Controller_Left, + Controller_Left1, + Controller_Left2, Controller_Right, + Controller_Right1, + Controller_Right2, Controller_SwapPaddles, Controller_PaddlesXCenter, Controller_PaddlesYCenter, diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index 598b37fb8..afac9294a 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -15,45 +15,92 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +#include "OSystem.hxx" +#include "EventHandler.hxx" #include "Event.hxx" +#include "Console.hxx" #include "System.hxx" #include "TIA.hxx" #include "FrameBuffer.hxx" +#include "AtariVox.hxx" +#include "Driving.hxx" #include "Joystick.hxx" +#include "SaveKey.hxx" #include "QuadTari.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -QuadTari::QuadTari(Jack jack, const Event& event, const System& system, - const Controller::Type firstType, const Controller::Type secondType) - : Controller(jack, event, system, Controller::Type::QuadTari) +QuadTari::QuadTari(Jack jack, OSystem& osystem, const System& system, const Properties& properties) + : Controller(jack, osystem.eventHandler().event(), system, + Controller::Type::QuadTari), + myOSystem(osystem) { - // TODO: support multiple controller types - switch(firstType) - { - case Controller::Type::Joystick: - myFirstController = make_unique(myJack, event, system); - break; + string first, second; + Controller::Type firstType = Controller::Type::Joystick, + secondType = Controller::Type::Joystick; - default: - // TODO - break; - } - switch(secondType) + if(jack == Controller::Jack::Left) { - case Controller::Type::Joystick: - mySecondController = make_unique(myJack, event, system, true); // use alternative mapping - break; - - default: - // TODO - break; + first = properties.get(PropType::Controller_Left1); + second = properties.get(PropType::Controller_Left2); } + else + { + first = properties.get(PropType::Controller_Right1); + second = properties.get(PropType::Controller_Right2); + } + + if(!first.empty()) + firstType = Controller::getType(first); + if(!second.empty()) + secondType = Controller::getType(second); + + myFirstController = addController(firstType, false); + mySecondController = addController(secondType, true); // QuadTari auto detection setting setPin(AnalogPin::Five, MIN_RESISTANCE); setPin(AnalogPin::Nine, MAX_RESISTANCE); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +unique_ptr QuadTari::addController(const Controller::Type type, bool second) +{ + switch(type) + { + case Controller::Type::AtariVox: + { + FilesystemNode nvramfile = myOSystem.nvramDir(); + nvramfile /= "atarivox_eeprom.dat"; + Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { + bool devSettings = os.settings().getBool("dev.settings"); + if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + os.frameBuffer().showMessage(msg); + }; + return make_unique(myJack, myEvent, mySystem, + myOSystem.settings().getString("avoxport"), + nvramfile, callback); // no alternative mapping here + } + case Controller::Type::Driving: + return make_unique(myJack, myEvent, mySystem, second); + + case Controller::Type::SaveKey: + { + FilesystemNode nvramfile = myOSystem.nvramDir(); + nvramfile /= "savekey_eeprom.dat"; + Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { + bool devSettings = os.settings().getBool("dev.settings"); + if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + os.frameBuffer().showMessage(msg); + }; + return make_unique(myJack, myEvent, mySystem, + nvramfile, callback); // no alternative mapping here + } + default: + // fall back to good old Joystick + return make_unique(myJack, myEvent, mySystem, second); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool QuadTari::read(DigitalPin pin) { diff --git a/src/emucore/QuadTari.hxx b/src/emucore/QuadTari.hxx index 3d5d0bfb6..bfaf1b5d8 100644 --- a/src/emucore/QuadTari.hxx +++ b/src/emucore/QuadTari.hxx @@ -39,9 +39,7 @@ class QuadTari: public Controller @param firstType The type of the first, plugged-in controller @param secondType The type of the second, plugged-in controller */ - QuadTari(Jack jack, const Event& event, const System& system, - const Controller::Type firstType = Controller::Type::Joystick, - const Controller::Type secondType = Controller::Type::Joystick); + QuadTari(Jack jack, OSystem& osystem, const System& system, const Properties& properties); ~QuadTari() override = default; public: @@ -90,6 +88,9 @@ class QuadTari: public Controller Controller::Type xtype, int xid, Controller::Type ytype, int yid) override; private: + unique_ptr addController(const Controller::Type type, bool second); + + OSystem& myOSystem; unique_ptr myFirstController; unique_ptr mySecondController; diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index e960ab419..69e485f93 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -236,6 +236,10 @@ GameInfoDialog::GameInfoDialog( myLeftPortLabel->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kLeftCChanged); wid.push_back(myLeftPort); + + myLeftQuadTari = new ButtonWidget(myTab, font, myLeftPort->getRight() + fontWidth * 2, myLeftPort->getTop() - 2, + "QuadTari" + ELLIPSIS, kLeftQTPressed); + wid.push_back(myLeftQuadTari); ypos += lineHeight + VGAP; myLeftPortDetected = new StaticTextWidget(myTab, ifont, myLeftPort->getLeft(), ypos, @@ -247,17 +251,19 @@ GameInfoDialog::GameInfoDialog( myRightPortLabel->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kRightCChanged); wid.push_back(myRightPort); + + myRightQuadTari = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 2, myRightPort->getTop() - 2, + "QuadTari" + ELLIPSIS, kRightQTPressed); + wid.push_back(myRightQuadTari); + ypos += lineHeight + VGAP; myRightPortDetected = new StaticTextWidget(myTab, ifont, myRightPort->getLeft(), ypos, "Sega Genesis detected"); ypos += ifont.getLineHeight() + VGAP + 4; - mySwapPorts = new CheckboxWidget(myTab, font, myLeftPort->getRight() + fontWidth*4, - myLeftPort->getTop()+1, "Swap ports"); + mySwapPorts = new CheckboxWidget(myTab, font, xpos + fontWidth * 2, + myLeftPortDetected->getTop()-1, "Swap ports"); wid.push_back(mySwapPorts); - mySwapPaddles = new CheckboxWidget(myTab, font, myRightPort->getRight() + fontWidth*4, - myRightPort->getTop()+1, "Swap paddles"); - wid.push_back(mySwapPaddles); // EEPROM erase button for left/right controller //ypos += lineHeight + VGAP + 4; @@ -271,6 +277,10 @@ GameInfoDialog::GameInfoDialog( "(for this game only)"); ypos += lineHeight + VGAP * 4; + mySwapPaddles = new CheckboxWidget(myTab, font, xpos, ypos, "Swap paddles"); + wid.push_back(mySwapPaddles); + ypos += lineHeight + VGAP; + // Paddles myPaddlesCenter = new StaticTextWidget(myTab, font, xpos, ypos, "Paddles center:"); ypos += lineHeight + VGAP; @@ -293,7 +303,7 @@ GameInfoDialog::GameInfoDialog( // Mouse xpos = HBORDER + fontWidth * 24 - INDENT; - ypos = myPaddlesCenter->getTop(); + ypos = mySwapPaddles->getTop() - 1; myMouseControl = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Specific mouse axes", kMCtrlChanged); wid.push_back(myMouseControl); @@ -760,6 +770,8 @@ void GameInfoDialog::updateControllerStates() myRightPortLabel->setEnabled(enableSelectControl); myLeftPort->setEnabled(enableSelectControl); myRightPort->setEnabled(enableSelectControl); + myLeftQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI")); + myRightQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrRight, "QUADTARI")); mySwapPorts->setEnabled(enableSelectControl); mySwapPaddles->setEnabled(enablePaddles); @@ -859,6 +871,12 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, updateControllerStates(); break; + case kLeftQTPressed: + break; + + case kRightQTPressed: + break; + case kEEButtonPressed: eraseEEPROM(); break; diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index c1302e753..b1b155f7a 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -87,6 +87,8 @@ class GameInfoDialog : public Dialog, public CommandSender StaticTextWidget* myLeftPortDetected{nullptr}; PopUpWidget* myRightPort{nullptr}; StaticTextWidget* myRightPortDetected{nullptr}; + ButtonWidget* myLeftQuadTari{nullptr}; + ButtonWidget* myRightQuadTari{nullptr}; CheckboxWidget* mySwapPorts{nullptr}; CheckboxWidget* mySwapPaddles{nullptr}; StaticTextWidget* myEraseEEPROMLabel{nullptr}; @@ -114,6 +116,8 @@ class GameInfoDialog : public Dialog, public CommandSender kPPBlendChanged = 'PBch', kLeftCChanged = 'LCch', kRightCChanged = 'RCch', + kLeftQTPressed = 'LQTp', + kRightQTPressed = 'RQTp', kMCtrlChanged = 'MCch', kEEButtonPressed = 'EEgb', kPXCenterChanged = 'Pxch', diff --git a/src/tools/PropSet.pm b/src/tools/PropSet.pm index 0c40d7452..346f01e89 100755 --- a/src/tools/PropSet.pm +++ b/src/tools/PropSet.pm @@ -17,15 +17,19 @@ my %prop_type = ( "Console.TVType" => 11, "Console.SwapPorts" => 12, "Controller.Left" => 13, - "Controller.Right" => 14, - "Controller.SwapPaddles" => 15, - "Controller.PaddlesXCenter" => 16, - "Controller.PaddlesYCenter" => 17, - "Controller.MouseAxis" => 18, - "Display.Format" => 19, - "Display.VCenter" => 20, - "Display.Phosphor" => 21, - "Display.PPBlend" => 22 + "Controller.Left1" => 14, + "Controller.Left2" => 15, + "Controller.Right" => 16, + "Controller.Right1" => 17, + "Controller.Right2" => 18, + "Controller.SwapPaddles" => 19, + "Controller.PaddlesXCenter" => 20, + "Controller.PaddlesYCenter" => 21, + "Controller.MouseAxis" => 22, + "Display.Format" => 23, + "Display.VCenter" => 24, + "Display.Phosphor" => 25, + "Display.PPBlend" => 26 ); my @prop_type_as_string = ( "Cart.MD5", @@ -42,7 +46,11 @@ my @prop_type_as_string = ( "Console.TVType", "Console.SwapPorts", "Controller.Left", + "Controller.Left1", + "Controller.Left2", "Controller.Right", + "Controller.Right1", + "Controller.Right2", "Controller.SwapPaddles", "Controller.PaddlesXCenter", "Controller.PaddlesYCenter", @@ -69,7 +77,13 @@ my @prop_defaults = ( "NO", "", "", + "", + "", + "", + "", "NO", + "0", + "0", "AUTO", "AUTO", "0", From 2c0bd6ecee14b6cba4c97cebc60fc40d2dc4ebf7 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 2 Sep 2020 19:29:35 -0230 Subject: [PATCH 028/263] libretro: Updated VS2017 project. This has been broken for months, so I wonder whether we should keep it. --- src/libretro/Stella.vcxproj | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libretro/Stella.vcxproj b/src/libretro/Stella.vcxproj index f92e5ea11..2d0a777db 100644 --- a/src/libretro/Stella.vcxproj +++ b/src/libretro/Stella.vcxproj @@ -140,8 +140,14 @@ + + + + + + @@ -174,8 +180,6 @@ - - @@ -248,7 +252,6 @@ - @@ -276,6 +279,7 @@ + @@ -296,23 +300,25 @@ + + - - + + @@ -325,6 +331,7 @@ + From 21bc244d97a87c49a3b2182a92b0e6665c3480a3 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Thu, 3 Sep 2020 15:14:55 +0200 Subject: [PATCH 029/263] added multiple controller support (joystick, driving, SaveKey, AtariVox) --- Changes.txt | 2 +- docs/index.html | 17 +-- src/emucore/ControllerDetector.cxx | 10 +- src/emucore/QuadTari.cxx | 19 +-- src/gui/GameInfoDialog.cxx | 69 +++++++--- src/gui/GameInfoDialog.hxx | 10 +- src/gui/QuadTariDialog.cxx | 200 +++++++++++++++++++++++++++++ src/gui/QuadTariDialog.hxx | 69 ++++++++++ src/windows/Stella.vcxproj | 2 + src/windows/Stella.vcxproj.filters | 6 + 10 files changed, 351 insertions(+), 53 deletions(-) create mode 100644 src/gui/QuadTariDialog.cxx create mode 100644 src/gui/QuadTariDialog.hxx diff --git a/Changes.txt b/Changes.txt index eb495b099..ac82c7713 100644 --- a/Changes.txt +++ b/Changes.txt @@ -37,7 +37,7 @@ are no longer corrupted/cut off. This includes properly supporting the 2600-daptor II, which is flashable to an AVox-USB converter. - * Added QuadTari controller support for josticks (TODO: doc, settings etc.) + * Added QuadTari controller support for several controllers (TODO: docs) * Added option to select the audio device. diff --git a/docs/index.html b/docs/index.html index 699422419..f466e7413 100644 --- a/docs/index.html +++ b/docs/index.html @@ -268,24 +268,15 @@ Atari 2600 FPGA project, including cycle-exact audio, analog interference from mixing of audio channels, as well as stereo sound support; dynamic sound resampling is also included -
  • Emulates the Atari 2600 Joystick Controllers using your computer's keyboard, +
  • Emulates the Atari 2600 Joystick, Paddle, Driving, CBS BoosterGrip, Sega Genesis, QuadTari controllers using your computer's keyboard, joysticks or mouse
  • -
  • Emulates the Atari 2600 Keyboard Controllers using your computer's keyboard
  • -
  • Emulates the Atari 2600 Paddle Controllers using your computer's mouse, keyboard - or joysticks
  • -
  • Emulates the Atari 2600 Driving Controllers using your computer's keyboard, - joysticks or mouse
  • -
  • Emulates the CBS BoosterGrip Controller using your computer's keyboard, - joysticks or mouse
  • -
  • Emulates the Sega Genesis Controller using your computer's keyboard, - joysticks or mouse
  • -
  • Emulates CX22/CX80 style trackballs and Amiga/Atari Mouse using your +
  • Emulates CX22/CX80 style Trackballs, Amiga/Atari Mouse, Mindlink controller and the Light Gun using your computer's mouse
  • +
  • Emulates the Atari 2600 Keyboard controllers using your computer's keyboard
  • Emulates Spectravideo CompuMate system using your computer's keyboard, including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to to the actual keys on your keyboard
  • -
  • Emulates the Mindlink Controller and the Light Gun using your computer's mouse
  • -
  • Supports autodetection for most common controller types
  • +
  • Supports autodetection for most common controller types
  • Support for real Atari 2600 controllers using the Stelladaptor and 2600-daptor/2600-daptor II
  • diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index 86835f54d..644d4e23b 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -699,6 +699,11 @@ bool ControllerDetector::isProbablyLightGun(const ByteBuffer& image, size_t size bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size, Controller::Jack port) { + uInt8 signatureBoth[] = { 0x1B, 0x1F, 0x0B, 0x0E, 0x1E, 0x0B, 0x1C, 0x13 }; // "QUADTARI" + + if(searchForBytes(image, size, signatureBoth, 8)) + return true; + if(port == Controller::Jack::Left) { uInt8 signature[] = { 'Q', 'U', 'A', 'D', 'L' }; @@ -711,8 +716,5 @@ bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size return searchForBytes(image, size, signature, 5); } - - uInt8 signature[] = { 0x1B, 0x1F, 0x0B, 0x0E, 0x1E, 0x0B, 0x1C, 0x13 }; - - return searchForBytes(image, size, signature, 8); + return false; } diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index afac9294a..9b7b98190 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -65,17 +65,18 @@ QuadTari::QuadTari(Jack jack, OSystem& osystem, const System& system, const Prop // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unique_ptr QuadTari::addController(const Controller::Type type, bool second) { + FilesystemNode nvramfile = myOSystem.nvramDir(); + Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { + bool devSettings = os.settings().getBool("dev.settings"); + if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + os.frameBuffer().showMessage(msg); + }; + switch(type) { case Controller::Type::AtariVox: { - FilesystemNode nvramfile = myOSystem.nvramDir(); nvramfile /= "atarivox_eeprom.dat"; - Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { - bool devSettings = os.settings().getBool("dev.settings"); - if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); - }; return make_unique(myJack, myEvent, mySystem, myOSystem.settings().getString("avoxport"), nvramfile, callback); // no alternative mapping here @@ -85,13 +86,7 @@ unique_ptr QuadTari::addController(const Controller::Type type, bool case Controller::Type::SaveKey: { - FilesystemNode nvramfile = myOSystem.nvramDir(); nvramfile /= "savekey_eeprom.dat"; - Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { - bool devSettings = os.settings().getBool("dev.settings"); - if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); - }; return make_unique(myJack, myEvent, mySystem, nvramfile, callback); // no alternative mapping here } diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 69e485f93..a603a5a2d 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -31,6 +31,7 @@ #include "PopUpWidget.hxx" #include "Props.hxx" #include "PropsSet.hxx" +#include "QuadTariDialog.hxx" #include "TabWidget.hxx" #include "TIAConstants.hxx" #include "Widget.hxx" @@ -236,10 +237,6 @@ GameInfoDialog::GameInfoDialog( myLeftPortLabel->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kLeftCChanged); wid.push_back(myLeftPort); - - myLeftQuadTari = new ButtonWidget(myTab, font, myLeftPort->getRight() + fontWidth * 2, myLeftPort->getTop() - 2, - "QuadTari" + ELLIPSIS, kLeftQTPressed); - wid.push_back(myLeftQuadTari); ypos += lineHeight + VGAP; myLeftPortDetected = new StaticTextWidget(myTab, ifont, myLeftPort->getLeft(), ypos, @@ -252,17 +249,17 @@ GameInfoDialog::GameInfoDialog( pwidth, lineHeight, ctrls, "", 0, kRightCChanged); wid.push_back(myRightPort); - myRightQuadTari = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 2, myRightPort->getTop() - 2, - "QuadTari" + ELLIPSIS, kRightQTPressed); - wid.push_back(myRightQuadTari); + myQuadTariButton = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 4, myRightPort->getTop() - 2, + "QuadTari" + ELLIPSIS, kQuadTariPressed); + wid.push_back(myQuadTariButton); ypos += lineHeight + VGAP; myRightPortDetected = new StaticTextWidget(myTab, ifont, myRightPort->getLeft(), ypos, "Sega Genesis detected"); ypos += ifont.getLineHeight() + VGAP + 4; - mySwapPorts = new CheckboxWidget(myTab, font, xpos + fontWidth * 2, - myLeftPortDetected->getTop()-1, "Swap ports"); + mySwapPorts = new CheckboxWidget(myTab, font, myLeftPort->getRight() + fontWidth * 4, + myLeftPort->getTop() + 1, "Swap ports"); wid.push_back(mySwapPorts); // EEPROM erase button for left/right controller @@ -601,8 +598,22 @@ void GameInfoDialog::saveProperties() myGameProperties.set(PropType::Console_RightDiff, myRightDiffGroup->getSelected() ? "B" : "A"); // Controller properties - myGameProperties.set(PropType::Controller_Left, myLeftPort->getSelectedTag().toString()); - myGameProperties.set(PropType::Controller_Right, myRightPort->getSelectedTag().toString()); + string controller = myLeftPort->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Left, controller); + if(controller != "AUTO" && controller != "QUADTARI") + { + myGameProperties.set(PropType::Controller_Left1, ""); + myGameProperties.set(PropType::Controller_Left2, ""); + } + + controller = myRightPort->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Right, controller); + if(controller != "AUTO" && controller != "QUADTARI") + { + myGameProperties.set(PropType::Controller_Right1, ""); + myGameProperties.set(PropType::Controller_Right2, ""); + } + myGameProperties.set(PropType::Console_SwapPorts, (mySwapPorts->isEnabled() && mySwapPorts->getState()) ? "YES" : "NO"); myGameProperties.set(PropType::Controller_SwapPaddles, mySwapPaddles->getState() ? "YES" : "NO"); @@ -715,8 +726,12 @@ void GameInfoDialog::updateControllerStates() if(type == Controller::Type::Unknown) { if(instance().hasConsole()) + { label = (!swapPorts ? instance().console().leftController().name() - : instance().console().rightController().name()) + " detected"; + : instance().console().rightController().name() + " detected"); + if(BSPF::startsWithIgnoreCase(label, "QUADTARI")) + label = "QuadTari detected"; // remove plugged-in controller names + } else if(autoDetect) label = ControllerDetector::detectName(image, size, type, !swapPorts ? Controller::Jack::Left : Controller::Jack::Right, @@ -730,8 +745,12 @@ void GameInfoDialog::updateControllerStates() if(type == Controller::Type::Unknown) { if(instance().hasConsole()) + { label = (!swapPorts ? instance().console().rightController().name() : instance().console().leftController().name()) + " detected"; + if(BSPF::startsWithIgnoreCase(label, "QUADTARI")) + label = "QuadTari detected"; // remove plugged-in controller names + } else if(autoDetect) label = ControllerDetector::detectName(image, size, type, !swapPorts ? Controller::Jack::Right : Controller::Jack::Left, @@ -770,8 +789,10 @@ void GameInfoDialog::updateControllerStates() myRightPortLabel->setEnabled(enableSelectControl); myLeftPort->setEnabled(enableSelectControl); myRightPort->setEnabled(enableSelectControl); - myLeftQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI")); - myRightQuadTari->setEnabled(BSPF::startsWithIgnoreCase(contrRight, "QUADTARI")); + myQuadTariButton->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI") || + BSPF::startsWithIgnoreCase(contrRight, "QUADTARI") || + BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "QUADTARI") || + BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "QUADTARI")); mySwapPorts->setEnabled(enableSelectControl); mySwapPaddles->setEnabled(enablePaddles); @@ -843,7 +864,7 @@ void GameInfoDialog::saveCurrentPropertiesToDisk() void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) { - switch (cmd) + switch(cmd) { case GuiObject::kOKCmd: saveConfig(); @@ -871,12 +892,22 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, updateControllerStates(); break; - case kLeftQTPressed: - break; + case kQuadTariPressed: + { + bool enableLeft = + BSPF::startsWithIgnoreCase(myLeftPort->getSelectedTag().toString(), "QUADTARI") || + BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "QUADTARI"); + bool enableRight = + BSPF::startsWithIgnoreCase(myRightPort->getSelectedTag().toString(), "QUADTARI") || + BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "QUADTARI"); - case kRightQTPressed: + if(!myQuadTariDialog) + myQuadTariDialog = make_unique + (this, _font, _font.getMaxCharWidth() * 37, _font.getFontHeight() * 8, + myGameProperties); + myQuadTariDialog->show(enableLeft, enableRight); break; - + } case kEEButtonPressed: eraseEEPROM(); break; diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index b1b155f7a..19d1c29e3 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -26,6 +26,7 @@ class StaticTextWidget; class RadioButtonGroup; class TabWidget; class SliderWidget; +class QuadTariDialog; #include "Dialog.hxx" #include "Command.hxx" @@ -87,8 +88,7 @@ class GameInfoDialog : public Dialog, public CommandSender StaticTextWidget* myLeftPortDetected{nullptr}; PopUpWidget* myRightPort{nullptr}; StaticTextWidget* myRightPortDetected{nullptr}; - ButtonWidget* myLeftQuadTari{nullptr}; - ButtonWidget* myRightQuadTari{nullptr}; + ButtonWidget* myQuadTariButton{nullptr}; CheckboxWidget* mySwapPorts{nullptr}; CheckboxWidget* mySwapPaddles{nullptr}; StaticTextWidget* myEraseEEPROMLabel{nullptr}; @@ -102,6 +102,9 @@ class GameInfoDialog : public Dialog, public CommandSender PopUpWidget* myMouseY{nullptr}; SliderWidget* myMouseRange{nullptr}; + // Allow assigning the four QuadTari controllers + unique_ptr myQuadTariDialog; + // Cartridge properties EditTextWidget* myName{nullptr}; EditTextWidget* myMD5{nullptr}; @@ -116,8 +119,7 @@ class GameInfoDialog : public Dialog, public CommandSender kPPBlendChanged = 'PBch', kLeftCChanged = 'LCch', kRightCChanged = 'RCch', - kLeftQTPressed = 'LQTp', - kRightQTPressed = 'RQTp', + kQuadTariPressed = 'QTpr', kMCtrlChanged = 'MCch', kEEButtonPressed = 'EEgb', kPXCenterChanged = 'Pxch', diff --git a/src/gui/QuadTariDialog.cxx b/src/gui/QuadTariDialog.cxx new file mode 100644 index 000000000..dda63853b --- /dev/null +++ b/src/gui/QuadTariDialog.cxx @@ -0,0 +1,200 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "OSystem.hxx" +#include "EventHandler.hxx" +#include "Widget.hxx" +#include "PopUpWidget.hxx" +#include "Font.hxx" +#include "Variant.hxx" +#include "Props.hxx" +#include "PropsSet.hxx" +#include "QuadTariDialog.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +QuadTariDialog::QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h, + Properties& properties) + : Dialog(boss->instance(), boss->parent(), font, "QuadTari controllers", 0, 0, max_w, max_h), + myGameProperties(properties) +{ + const int lineHeight = font.getLineHeight(), + fontHeight = font.getFontHeight(), + fontWidth = font.getMaxCharWidth(), + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int VGAP = fontHeight / 4; + + int xpos, ypos; + WidgetArray wid; + VariantList ctrls; + + xpos = HBORDER; ypos = VBORDER + _th; + + ctrls.clear(); + //VarList::push_back(ctrls, "Auto-detect", "AUTO"); + VarList::push_back(ctrls, "Joystick", "JOYSTICK"); + //VarList::push_back(ctrls, "Paddles", "PADDLES"); + //VarList::push_back(ctrls, "Paddles_IAxis", "PADDLES_IAXIS"); + //VarList::push_back(ctrls, "Paddles_IAxDr", "PADDLES_IAXDR"); + //VarList::push_back(ctrls, "BoosterGrip", "BOOSTERGRIP"); + VarList::push_back(ctrls, "Driving", "DRIVING"); + //VarList::push_back(ctrls, "Keyboard", "KEYBOARD"); + //VarList::push_back(ctrls, "AmigaMouse", "AMIGAMOUSE"); + //VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE"); + //VarList::push_back(ctrls, "Trakball", "TRAKBALL"); + VarList::push_back(ctrls, "AtariVox", "ATARIVOX"); + VarList::push_back(ctrls, "SaveKey", "SAVEKEY"); + //VarList::push_back(ctrls, "Sega Genesis", "GENESIS"); + //VarList::push_back(ctrls, "KidVid", "KIDVID"); + //VarList::push_back(ctrls, "Lightgun", "LIGHTGUN"); + //VarList::push_back(ctrls, "MindLink", "MINDLINK"); + //VarList::push_back(ctrls, "QuadTari", "QUADTARI"); + + int pwidth = font.getStringWidth("Joystick12"); // looks better overall + + myLeftPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Left port"); + + ypos += lineHeight + VGAP * 2; + myLeft1Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P1 "); + wid.push_back(myLeft1Port); + + ypos += lineHeight + VGAP * 2; + myLeft2Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P2 "); + wid.push_back(myLeft2Port); + + xpos = _w - HBORDER - myLeft1Port->getWidth(); // aligned right + ypos = myLeftPortLabel->getTop() - 1; + myRightPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Right port"); + + ypos += lineHeight + VGAP * 2; + myRight1Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P3 "); + wid.push_back(myRight1Port); + + ypos += lineHeight + VGAP * 2; + myRight2Port = new PopUpWidget(this, font, xpos, ypos, + pwidth, lineHeight, ctrls, "P4 "); + wid.push_back(myRight2Port); + + addDefaultsOKCancelBGroup(wid, _font); + addBGroupToFocusList(wid); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::show(bool enableLeft, bool enableRight) +{ + myLeftPortLabel->setEnabled(enableLeft); + myLeft1Port->setEnabled(enableLeft); + myLeft2Port->setEnabled(enableLeft); + myRightPortLabel->setEnabled(enableRight); + myRight1Port->setEnabled(enableRight); + myRight2Port->setEnabled(enableRight); + + open(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::loadControllerProperties(const Properties& props) +{ + string controller; + + if(myLeftPortLabel->isEnabled()) + { + controller = props.get(PropType::Controller_Left1); + myLeft1Port->setSelected(controller, "Joystick"); + controller = props.get(PropType::Controller_Left2); + myLeft2Port->setSelected(controller, "Joystick"); + } + + if(myRightPortLabel->isEnabled()) + { + controller = props.get(PropType::Controller_Right1); + myRight1Port->setSelected(controller, "Joystick"); + controller = props.get(PropType::Controller_Right2); + myRight2Port->setSelected(controller, "Joystick"); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::loadConfig() +{ + loadControllerProperties(myGameProperties); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::saveConfig() +{ + if(myLeftPortLabel->isEnabled()) + { + string controller = myLeft1Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Left1, controller); + controller = myLeft2Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Left2, controller); + } + else + { + myGameProperties.set(PropType::Controller_Left1, ""); + myGameProperties.set(PropType::Controller_Left2, ""); + } + + if(myRightPortLabel->isEnabled()) + { + string controller = myRight1Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Right1, controller); + controller = myRight2Port->getSelectedTag().toString(); + myGameProperties.set(PropType::Controller_Right2, controller); + } + else + { + myGameProperties.set(PropType::Controller_Right1, ""); + myGameProperties.set(PropType::Controller_Right2, ""); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::setDefaults() +{ + // Load the default properties + const string& md5 = myGameProperties.get(PropType::Cart_MD5); + Properties defaultProperties; + + instance().propSet().getMD5(md5, defaultProperties, true); + loadControllerProperties(defaultProperties); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) +{ + switch(cmd) + { + case GuiObject::kOKCmd: + saveConfig(); + close(); + break; + + case GuiObject::kDefaultsCmd: + setDefaults(); + break; + + default: + Dialog::handleCommand(sender, cmd, data, id); + break; + } +} diff --git a/src/gui/QuadTariDialog.hxx b/src/gui/QuadTariDialog.hxx new file mode 100644 index 000000000..070a0bd71 --- /dev/null +++ b/src/gui/QuadTariDialog.hxx @@ -0,0 +1,69 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef JOYSTICK_DIALOG_HXX +#define JOYSTICK_DIALOG_HXX + +class CommandSender; +class PopUpWidget; + +#include "Dialog.hxx" + +/** + * Allow assigning controllers to the four QuadTari ports. + */ +class QuadTariDialog: public Dialog +{ + public: + QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h, + Properties& properties); + ~QuadTariDialog() override = default; + + /** Place the dialog onscreen */ + void show(bool enableLeft, bool enableRight); + + private: + void loadConfig() override; + void saveConfig() override; + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + + void setDefaults() override; + + void loadControllerProperties(const Properties& props); + + private: + StaticTextWidget* myLeftPortLabel{nullptr}; + PopUpWidget* myLeft1Port{nullptr}; + PopUpWidget* myLeft2Port{nullptr}; + + StaticTextWidget* myRightPortLabel{nullptr}; + PopUpWidget* myRight1Port{nullptr}; + PopUpWidget* myRight2Port{nullptr}; + + // Game properties for currently loaded ROM + Properties& myGameProperties; + + private: + // Following constructors and assignment operators not supported + QuadTariDialog() = delete; + QuadTariDialog(const QuadTariDialog&) = delete; + QuadTariDialog(QuadTariDialog&&) = delete; + QuadTariDialog& operator=(const QuadTariDialog&) = delete; + QuadTariDialog& operator=(QuadTariDialog&&) = delete; +}; + +#endif diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 261ac76b9..f37614cda 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -773,6 +773,7 @@ + @@ -1815,6 +1816,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 6be678998..217dfaecf 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1023,6 +1023,9 @@ Source Files\debugger + + Source Files\gui + @@ -2102,6 +2105,9 @@ Header Files\debugger + + Header Files\gui + From d68c8ba65a9aef34365bdac63be18f774dbfae17 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Thu, 3 Sep 2020 19:35:38 +0200 Subject: [PATCH 030/263] QuadTari documentation --- Changes.txt | 2 +- docs/graphics/options_gameinfo_controller.png | Bin 4139 -> 4276 bytes docs/graphics/options_gameinfo_quadtari.png | Bin 0 -> 1669 bytes docs/index.html | 33 ++++++++++++++---- src/gui/GameInfoDialog.cxx | 13 ++++--- 5 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 docs/graphics/options_gameinfo_quadtari.png diff --git a/Changes.txt b/Changes.txt index ac82c7713..9fca8766a 100644 --- a/Changes.txt +++ b/Changes.txt @@ -37,7 +37,7 @@ are no longer corrupted/cut off. This includes properly supporting the 2600-daptor II, which is flashable to an AVox-USB converter. - * Added QuadTari controller support for several controllers (TODO: docs) + * Added QuadTari controller support. * Added option to select the audio device. diff --git a/docs/graphics/options_gameinfo_controller.png b/docs/graphics/options_gameinfo_controller.png index fe5adb275112aed7de598609cee65dedf983480f..5200f72119ebe0e163777436f8e3d069788c8450 100644 GIT binary patch literal 4276 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 literal 4139 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 bankswitching document or the documentation in each cartridge's source code file) types. Types marked as (¹) do currently have no reliable auto-detection, those marked as (²) - are not fully supported in the debugger: + are not fully supported in the debugger.
    Cart.Name:Cart.Name Indicates the actual name of the game. When you save snapshots, load/save state files, or use the ROM Audit Mode functionality, this is the name that will be used for the respective file(s).
    Cart.MD5:Cart.MD5 Indicates the MD5 checksum of the ROM image as a string of hexadecimal digits. Stella uses this property while attempting to match a game with its block of properties. If the @@ -4309,22 +4348,22 @@ Ms Pac-Man (Stella extended codes):
    Cart.Manufacturer:Cart.Manufacturer Indicates the game's manufacturer.
    Cart.ModelNo:Cart.ModelNo Indicates the manufacturer's model number for the game.
    Cart.Rarity:Cart.Rarity Indicates how rare a cartridge is, based on the scale described on AtariAge.
    Cart.Note:Cart.Note Contains any special notes about playing the game.
    @@ -4226,11 +4226,6 @@ Ms Pac-Man (Stella extended codes): - +
     Type DescriptionFile Extension
    (to force type)
    0840 8K ECONObanking .084, .0840
    Controller.Left
    Controller.Right
    -
    For QuadTari:
    - Controller.Left1
    - Controller.Left2
    - Controller.Right1
    - Controller.Right2
    Indicates what type of controller the left and right player uses. The value must be either Auto or one of the following types. Types marked @@ -4254,7 +4249,7 @@ Ms Pac-Man (Stella extended codes):
    LightgunAtari XG-1 compatible Light Gun
    Mindlink ¹Mindlink controller.
    KidVid ¹KidVid controller, limited support (8, 9 and 0 start the games).
    QuadTariQuadTari controller, limited support (Joystick, Driving controller, SaveKey and AtariVox only).
    QuadTariQuadTari controller, limited support (see below).
    @@ -4316,6 +4311,30 @@ Ms Pac-Man (Stella extended codes):
    +

    + +

    + + + + + +
    + Controller.Left1
    + Controller.Left2
    + Controller.Right1
    + Controller.Right2
    +
    Indicates which controllers are plugged into one of the four QuadTari ports. + The value must be one of the following types. + + + + + + +
     Type Description
    JoystickAtari's famous black joystick that was originally included with the system.
    DrivingLooks like a paddle, but allows 360° movement. Only one unit per connector, unlike paddles which were sold in pairs.
    AtariVoxA SpeakJet based unlimited-vocabulary speech/sound synthesizer with 32K EEPROM.
    SaveKeyA 32K EEPROM for saving high scores, etc. (the EEPROM portion of an AtariVox).
    +
    +

    diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index a603a5a2d..e5eb1162c 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -249,21 +249,20 @@ GameInfoDialog::GameInfoDialog( pwidth, lineHeight, ctrls, "", 0, kRightCChanged); wid.push_back(myRightPort); - myQuadTariButton = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 4, myRightPort->getTop() - 2, - "QuadTari" + ELLIPSIS, kQuadTariPressed); - wid.push_back(myQuadTariButton); - ypos += lineHeight + VGAP; myRightPortDetected = new StaticTextWidget(myTab, ifont, myRightPort->getLeft(), ypos, "Sega Genesis detected"); - ypos += ifont.getLineHeight() + VGAP + 4; mySwapPorts = new CheckboxWidget(myTab, font, myLeftPort->getRight() + fontWidth * 4, myLeftPort->getTop() + 1, "Swap ports"); wid.push_back(mySwapPorts); + myQuadTariButton = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 4, myRightPort->getTop() - 2, + " QuadTari" + ELLIPSIS + " ", kQuadTariPressed); + wid.push_back(myQuadTariButton); + // EEPROM erase button for left/right controller - //ypos += lineHeight + VGAP + 4; + ypos += ifont.getLineHeight() + VGAP + 4; pwidth = myRightPort->getWidth(); //font.getStringWidth("Erase EEPROM ") + 23; myEraseEEPROMLabel = new StaticTextWidget(myTab, font, HBORDER, ypos, "AtariVox/SaveKey "); myEraseEEPROMButton = new ButtonWidget(myTab, font, myEraseEEPROMLabel->getRight(), ypos - 4, @@ -728,7 +727,7 @@ void GameInfoDialog::updateControllerStates() if(instance().hasConsole()) { label = (!swapPorts ? instance().console().leftController().name() - : instance().console().rightController().name() + " detected"); + : instance().console().rightController().name()) + " detected"; if(BSPF::startsWithIgnoreCase(label, "QUADTARI")) label = "QuadTari detected"; // remove plugged-in controller names } From 635094b75ff633ef4dee9a80ab17301c147a37d5 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 3 Sep 2020 20:44:41 -0230 Subject: [PATCH 031/263] Fix a few compiler warning and errors from the latest g++ and clang compilers. --- src/emucore/QuadTari.hxx | 13 +++++++------ src/gui/GameInfoDialog.cxx | 5 +++++ src/gui/GameInfoDialog.hxx | 2 +- src/gui/QuadTariDialog.cxx | 3 +-- src/gui/module.mk | 1 + 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/emucore/QuadTari.hxx b/src/emucore/QuadTari.hxx index bfaf1b5d8..449a43dff 100644 --- a/src/emucore/QuadTari.hxx +++ b/src/emucore/QuadTari.hxx @@ -26,23 +26,24 @@ class Event; @author Thomas Jentzsch */ -class QuadTari: public Controller +class QuadTari : public Controller { friend class QuadTariWidget; public: /** Create a QuadTari controller plugged into the specified jack - @param jack The jack the controller is plugged into - @param event The event object to use for events - @param system The system using this controller - @param firstType The type of the first, plugged-in controller - @param secondType The type of the second, plugged-in controller + @param jack The jack the controller is plugged into + @param osystem The OSystem object to use + @param system The system using this controller + @param properties The properties to use for the current ROM */ QuadTari(Jack jack, OSystem& osystem, const System& system, const Properties& properties); ~QuadTari() override = default; public: + using Controller::read; + /** Read the value of the specified digital pin for this controller. diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index e5eb1162c..7e6e247f2 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -394,6 +394,11 @@ GameInfoDialog::GameInfoDialog( addBGroupToFocusList(wid); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +GameInfoDialog::~GameInfoDialog() +{ +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GameInfoDialog::loadConfig() { diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index 19d1c29e3..72e3df1a7 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -37,7 +37,7 @@ class GameInfoDialog : public Dialog, public CommandSender public: GameInfoDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, GuiObject* boss, int max_w, int max_h); - ~GameInfoDialog() override = default; + ~GameInfoDialog() override; private: void loadConfig() override; diff --git a/src/gui/QuadTariDialog.cxx b/src/gui/QuadTariDialog.cxx index dda63853b..3db0a6a65 100644 --- a/src/gui/QuadTariDialog.cxx +++ b/src/gui/QuadTariDialog.cxx @@ -33,8 +33,7 @@ QuadTariDialog::QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w { const int lineHeight = font.getLineHeight(), fontHeight = font.getFontHeight(), - fontWidth = font.getMaxCharWidth(), - buttonHeight = font.getLineHeight() * 1.25; + fontWidth = font.getMaxCharWidth(); const int VBORDER = fontHeight / 2; const int HBORDER = fontWidth * 1.25; const int VGAP = fontHeight / 4; diff --git a/src/gui/module.mk b/src/gui/module.mk index 4b52d3996..d7412d2a2 100644 --- a/src/gui/module.mk +++ b/src/gui/module.mk @@ -36,6 +36,7 @@ MODULE_OBJS := \ src/gui/OptionsDialog.o \ src/gui/PopUpWidget.o \ src/gui/ProgressDialog.o \ + src/gui/QuadTariDialog.o \ src/gui/R77HelpDialog.o \ src/gui/RadioButtonWidget.o \ src/gui/RomAuditDialog.o \ From ce7e01e98925c1c592bb007960fd4d8d5d0c3203 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Fri, 4 Sep 2020 07:50:58 +0200 Subject: [PATCH 032/263] reduced QuadTari timer to 1 scanline --- src/emucore/QuadTari.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index 9b7b98190..390fcac01 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -103,7 +103,7 @@ bool QuadTari::read(DigitalPin pin) // can switch the controller multiple times per frame // (we can't just read 60 times per second in the ::update() method) - constexpr int MIN_CYCLES = 20 * 76; // minimal cycles required for stable input switch (TODO: define cycles) + constexpr int MIN_CYCLES = 76; // minimal cycles required for stable input switch (just to be safe) bool readFirst; if(mySystem.tia().dumpPortsCycles() < MIN_CYCLES) From fc5f3bb8d7bb561868311529b4a8795ec6adc22f Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Sat, 5 Sep 2020 16:16:12 +0200 Subject: [PATCH 033/263] made changes in controller widgets and switches highlighted in SWCHA(R)/SWCHB(R) made SWCHB(R) editable in debugger --- src/debugger/RiotDebug.cxx | 10 ++++++---- src/debugger/gui/RiotWidget.cxx | 13 ++++++++++++- src/debugger/gui/RiotWidget.hxx | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx index 0a71c6d92..4484944aa 100644 --- a/src/debugger/RiotDebug.cxx +++ b/src/debugger/RiotDebug.cxx @@ -75,10 +75,11 @@ const DebuggerState& RiotDebug::getState() void RiotDebug::saveOldState() { // Port A & B registers - myOldState.SWCHA_R = swcha(); + // read from myState where other widgets can update pins directly + myOldState.SWCHA_R = myState.SWCHA_R; // swcha(); myOldState.SWCHA_W = mySystem.m6532().myOutA; myOldState.SWACNT = swacnt(); - myOldState.SWCHB_R = swchb(); + myOldState.SWCHB_R = myState.SWCHB_R; // swchb(); myOldState.SWCHB_W = mySystem.m6532().myOutB; myOldState.SWBCNT = swbcnt(); Debugger::set_bits(myOldState.SWCHA_R, myOldState.swchaReadBits); @@ -93,8 +94,9 @@ void RiotDebug::saveOldState() myOldState.INPT1 = inpt(1); myOldState.INPT2 = inpt(2); myOldState.INPT3 = inpt(3); - myOldState.INPT4 = inpt(4); - myOldState.INPT5 = inpt(5); + // read from myState where other widgets can update pins directly + myOldState.INPT4 = myState.INPT4; // inpt(4); + myOldState.INPT5 = myState.INPT5; // inpt(5); myOldState.INPTLatch = vblank(6); myOldState.INPTDump = vblank(7); diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index e1b5bf415..171da0cd6 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -99,7 +99,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, // SWCHB bits in 'peek' mode xpos = 10; ypos += lineHeight + 5; - CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, 0, false) + CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, kSWCHBRBitsID, true) // Timer registers (R/W) static constexpr std::array writeNames = { @@ -418,6 +418,17 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) rport.setPin(Controller::DigitalPin::Four, value & 0b00001000); break; } + case kSWCHBRBitsID: + { + value = Debugger::get_bits(mySWCHBReadBits->getState()); + + riot.reset( value & 0b00000001); + riot.select(value & 0b00000010); + riot.tvType(value & 0b00001000); + riot.diffP0(value & 0b01000000); + riot.diffP1(value & 0b10000000); + break; + } default: break; } diff --git a/src/debugger/gui/RiotWidget.hxx b/src/debugger/gui/RiotWidget.hxx index fdfd699ef..dfbe16ce2 100644 --- a/src/debugger/gui/RiotWidget.hxx +++ b/src/debugger/gui/RiotWidget.hxx @@ -76,7 +76,7 @@ class RiotWidget : public Widget, public CommandSender kTim1TID, kTim8TID, kTim64TID, kTim1024TID, kTimWriteID, kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kSWBCNTBitsID, kP0DiffChanged, kP1DiffChanged, kTVTypeChanged, kSelectID, kResetID, - kSWCHARBitsID, kPauseID + kSWCHARBitsID, kSWCHBRBitsID, kPauseID }; private: From 48cea696d89fbfd72fc334842af5d05f2eb2577d Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Sat, 5 Sep 2020 22:24:13 +0200 Subject: [PATCH 034/263] Updated StellaSettingsDialog and WhatsNewDialog --- src/gui/StellaSettingsDialog.cxx | 1 + src/gui/WhatsNewDialog.cxx | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/StellaSettingsDialog.cxx b/src/gui/StellaSettingsDialog.cxx index 74e8ca35f..fc3d3e4d9 100644 --- a/src/gui/StellaSettingsDialog.cxx +++ b/src/gui/StellaSettingsDialog.cxx @@ -195,6 +195,7 @@ void StellaSettingsDialog::addGameOptions(WidgetArray& wid, int& xpos, int& ypos VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE"); VarList::push_back(ctrls, "Trakball", "TRAKBALL"); VarList::push_back(ctrls, "Sega Genesis", "GENESIS"); + VarList::push_back(ctrls, "QuadTari", "QUADTARI"); int pwidth = _font.getStringWidth("Sega Genesis"); myLeftPortLabel = new StaticTextWidget(this, _font, xpos, ypos + 1, "Left port "); diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index 7f6c15084..4787d8fd7 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -38,7 +38,6 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const const int HBORDER = fontWidth * 1.25; int ypos = _th + VBORDER; - // Set preliminary dimensions setSize(MAX_CHARS * fontWidth + HBORDER * 2, max_h, max_w, max_h); @@ -53,8 +52,11 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const add(ypos, "added option to playback a game using the Time Machine"); //add(ypos, "allow taking snapshots from within the Time Machine dialog"); add(ypos, "added the ability to access most files that Stella uses from within a ZIP file"); + add(ypos, "extended AtariVox support to handle flow control, so that long phrases are no longer corrupted / cut off"); + add(ypos, "added QuadTari controller support"); add(ypos, "added option to select the audio device"); //add(ypos, "added option to display detected settings info when a ROM is loaded"); + //add(ypos, "added another oddball TIA glitch option for delayed background color"); //add(ypos, "replaced 'Re-disassemble' with 'Disassemble @ current line' in debugger"); //add(ypos, "fixed bug when taking fullscreen snapshots; the dimensions were sometimes cut"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); From cb7888b1b6bd046ef1fad6f22e9670ccfb0948b5 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Sat, 5 Sep 2020 16:16:12 +0200 Subject: [PATCH 035/263] made changes in controller widgets and switches highlighted in SWCHA(R)/SWCHB(R) made SWCHB(R) editable in debugger --- src/debugger/RiotDebug.cxx | 10 ++++++---- src/debugger/gui/RiotWidget.cxx | 13 ++++++++++++- src/debugger/gui/RiotWidget.hxx | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx index 0a71c6d92..4484944aa 100644 --- a/src/debugger/RiotDebug.cxx +++ b/src/debugger/RiotDebug.cxx @@ -75,10 +75,11 @@ const DebuggerState& RiotDebug::getState() void RiotDebug::saveOldState() { // Port A & B registers - myOldState.SWCHA_R = swcha(); + // read from myState where other widgets can update pins directly + myOldState.SWCHA_R = myState.SWCHA_R; // swcha(); myOldState.SWCHA_W = mySystem.m6532().myOutA; myOldState.SWACNT = swacnt(); - myOldState.SWCHB_R = swchb(); + myOldState.SWCHB_R = myState.SWCHB_R; // swchb(); myOldState.SWCHB_W = mySystem.m6532().myOutB; myOldState.SWBCNT = swbcnt(); Debugger::set_bits(myOldState.SWCHA_R, myOldState.swchaReadBits); @@ -93,8 +94,9 @@ void RiotDebug::saveOldState() myOldState.INPT1 = inpt(1); myOldState.INPT2 = inpt(2); myOldState.INPT3 = inpt(3); - myOldState.INPT4 = inpt(4); - myOldState.INPT5 = inpt(5); + // read from myState where other widgets can update pins directly + myOldState.INPT4 = myState.INPT4; // inpt(4); + myOldState.INPT5 = myState.INPT5; // inpt(5); myOldState.INPTLatch = vblank(6); myOldState.INPTDump = vblank(7); diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index 43514e072..d589026c2 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -98,7 +98,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, // SWCHB bits in 'peek' mode xpos = 10; ypos += lineHeight + 5; - CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, 0, false) + CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, kSWCHBRBitsID, true) // Timer registers (R/W) static constexpr std::array writeNames = { @@ -417,6 +417,17 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) rport.setPin(Controller::DigitalPin::Four, value & 0b00001000); break; } + case kSWCHBRBitsID: + { + value = Debugger::get_bits(mySWCHBReadBits->getState()); + + riot.reset( value & 0b00000001); + riot.select(value & 0b00000010); + riot.tvType(value & 0b00001000); + riot.diffP0(value & 0b01000000); + riot.diffP1(value & 0b10000000); + break; + } default: break; } diff --git a/src/debugger/gui/RiotWidget.hxx b/src/debugger/gui/RiotWidget.hxx index fdfd699ef..dfbe16ce2 100644 --- a/src/debugger/gui/RiotWidget.hxx +++ b/src/debugger/gui/RiotWidget.hxx @@ -76,7 +76,7 @@ class RiotWidget : public Widget, public CommandSender kTim1TID, kTim8TID, kTim64TID, kTim1024TID, kTimWriteID, kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kSWBCNTBitsID, kP0DiffChanged, kP1DiffChanged, kTVTypeChanged, kSelectID, kResetID, - kSWCHARBitsID, kPauseID + kSWCHARBitsID, kSWCHBRBitsID, kPauseID }; private: From d5909381567b05727b2b86fa007cbabd1afc1c23 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Sun, 6 Sep 2020 15:30:40 +0200 Subject: [PATCH 036/263] working on more controllers and debugger widgets --- src/debugger/gui/DrivingWidget.cxx | 41 +++++++++++++++++-------- src/debugger/gui/DrivingWidget.hxx | 2 +- src/debugger/gui/JoystickWidget.cxx | 2 +- src/debugger/gui/NullControlWidget.hxx | 42 ++++++++++++++++++-------- src/debugger/gui/QuadTariWidget.cxx | 31 ++++++++++++++----- src/emucore/QuadTari.cxx | 21 +++++++++---- src/emucore/QuadTari.hxx | 5 +-- src/gui/QuadTariDialog.cxx | 4 +-- 8 files changed, 102 insertions(+), 46 deletions(-) diff --git a/src/debugger/gui/DrivingWidget.cxx b/src/debugger/gui/DrivingWidget.cxx index 29419268c..3dadc24b4 100644 --- a/src/debugger/gui/DrivingWidget.cxx +++ b/src/debugger/gui/DrivingWidget.cxx @@ -20,37 +20,52 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DrivingWidget::DrivingWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, Controller& controller) + int x, int y, Controller& controller, bool embedded) : ControllerWidget(boss, font, x, y, controller) { const string& label = getHeader(); const int fontHeight = font.getFontHeight(), - bwidth = font.getStringWidth("Gray code +") + 10, + fontWidth = font.getMaxCharWidth(), bheight = font.getLineHeight() + 4; int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Driving)"); StaticTextWidget* t; - t = new StaticTextWidget(boss, font, xpos, ypos+2, lwidth, - fontHeight, label, TextAlign::Left); + if(embedded) + { + const int bwidth = font.getStringWidth("GC+ "); - ypos += t->getHeight() + 20; - myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, - "Gray code +", kGrayUpCmd); + myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + "GC+", kGrayUpCmd); + + ypos += myGrayUp->getHeight() + 5; + myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + "GC-", kGrayDownCmd); + } + else + { + const int bwidth = font.getStringWidth("Gray code +") + 10; + t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth, + fontHeight, label, TextAlign::Left); + + ypos += t->getHeight() + 20; + myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + "Gray code +", kGrayUpCmd); + + ypos += myGrayUp->getHeight() + 5; + myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + "Gray code -", kGrayDownCmd); + } myGrayUp->setTarget(this); - - ypos += myGrayUp->getHeight() + 5; - myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, - "Gray code -", kGrayDownCmd); myGrayDown->setTarget(this); - xpos += myGrayDown->getWidth() + 10; ypos -= 10; + xpos += myGrayDown->getWidth() + fontWidth; ypos -= 10; myGrayValue = new DataGridWidget(boss, font, xpos, ypos, 1, 1, 2, 8, Common::Base::Fmt::_16); myGrayValue->setTarget(this); myGrayValue->setEditable(false); - xpos = x + 30; ypos += myGrayDown->getHeight() + 20; + xpos = x + fontWidth*3; ypos += myGrayDown->getHeight() + 20; myFire = new CheckboxWidget(boss, font, xpos, ypos, "Fire", kFireCmd); myFire->setTarget(this); } diff --git a/src/debugger/gui/DrivingWidget.hxx b/src/debugger/gui/DrivingWidget.hxx index 0ab6c1d15..e8d648f8f 100644 --- a/src/debugger/gui/DrivingWidget.hxx +++ b/src/debugger/gui/DrivingWidget.hxx @@ -29,7 +29,7 @@ class DrivingWidget : public ControllerWidget { public: DrivingWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - Controller& controller); + Controller& controller, bool embedded = false); ~DrivingWidget() override = default; private: diff --git a/src/debugger/gui/JoystickWidget.cxx b/src/debugger/gui/JoystickWidget.cxx index 6e9ad18dc..80455dea0 100644 --- a/src/debugger/gui/JoystickWidget.cxx +++ b/src/debugger/gui/JoystickWidget.cxx @@ -34,7 +34,7 @@ JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font, t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth, fontHeight, label, TextAlign::Left); - xpos += t->getWidth() / 2 - 5; ypos += t->getHeight() + 20; + xpos += t->getWidth() / 2 - 5; ypos = t->getBottom() + fontHeight; } myPins[kJUp] = new CheckboxWidget(boss, font, xpos, ypos, "", CheckboxWidget::kCheckActionCmd); diff --git a/src/debugger/gui/NullControlWidget.hxx b/src/debugger/gui/NullControlWidget.hxx index 79364ca6e..d5cef42c9 100644 --- a/src/debugger/gui/NullControlWidget.hxx +++ b/src/debugger/gui/NullControlWidget.hxx @@ -26,22 +26,38 @@ class NullControlWidget : public ControllerWidget { public: NullControlWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - Controller& controller) + Controller& controller, bool embedded = false) : ControllerWidget(boss, font, x, y, controller) { - ostringstream buf; - buf << getHeader(); const int fontHeight = font.getFontHeight(), - lineHeight = font.getLineHeight(), - lwidth = std::max(font.getStringWidth(buf.str()), - font.getStringWidth("Controller input")); - new StaticTextWidget(boss, font, x, y+2, lwidth, - fontHeight, buf.str(), TextAlign::Left); - new StaticTextWidget(boss, font, x, y+2+2*lineHeight, lwidth, - fontHeight, "Controller input", TextAlign::Center); - new StaticTextWidget(boss, font, x, y+2+3*lineHeight, lwidth, - fontHeight, "not available", - TextAlign::Center); + lineHeight = font.getLineHeight(); + + if(embedded) + { + const int lwidth = font.getStringWidth("avail."); + + y += fontHeight; + new StaticTextWidget(boss, font, x, y, lwidth, fontHeight, + "not", TextAlign::Center); + y += lineHeight; + new StaticTextWidget(boss, font, x, y, lwidth, fontHeight, + "avail.", TextAlign::Center); + } + else + { + ostringstream buf; + buf << getHeader(); + const int lwidth = std::max(font.getStringWidth(buf.str()), + font.getStringWidth("Controller input")); + + new StaticTextWidget(boss, font, x, y + 2, lwidth, fontHeight, buf.str()); + y += 2 + lineHeight * 2; + new StaticTextWidget(boss, font, x, y, lwidth, + fontHeight, "Controller input", TextAlign::Center); + new StaticTextWidget(boss, font, x, y+lineHeight, lwidth, + fontHeight, "not available", + TextAlign::Center); + } } ~NullControlWidget() override = default; diff --git a/src/debugger/gui/QuadTariWidget.cxx b/src/debugger/gui/QuadTariWidget.cxx index 2c605da37..23db86995 100644 --- a/src/debugger/gui/QuadTariWidget.cxx +++ b/src/debugger/gui/QuadTariWidget.cxx @@ -19,6 +19,7 @@ #include "Console.hxx" #include "TIA.hxx" #include "QuadTari.hxx" +#include "DrivingWidget.hxx" #include "JoystickWidget.hxx" #include "NullControlWidget.hxx" #include "QuadTariWidget.hxx" @@ -28,40 +29,54 @@ QuadTariWidget::QuadTariWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller) : ControllerWidget(boss, font, x, y, controller) { + const int fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(); string label = (isLeftPort() ? "Left" : "Right") + string(" (QuadTari)"); StaticTextWidget* t = new StaticTextWidget(boss, font, x, y + 2, label); QuadTari& qt = static_cast(controller); - x += font.getMaxCharWidth() * 2; - y = t->getBottom() + font.getFontHeight() * 1.25; - // TODO: support multiple controller types switch(qt.myFirstController->type()) { case Controller::Type::Joystick: + x += fontWidth * 2; + y = t->getBottom() + fontHeight; myFirstControl = new JoystickWidget(boss, font, x, y, *qt.myFirstController, true); - x = myFirstControl->getRight() - font.getMaxCharWidth() * 8; + break; + + case Controller::Type::Driving: + y = t->getBottom() + font.getFontHeight() * 1; + myFirstControl = new DrivingWidget(boss, font, x, y, *qt.myFirstController, true); break; default: - myFirstControl = new NullControlWidget(boss, font, x, y, *qt.myFirstController); - x += font.getMaxCharWidth() * 8; + y = t->getBottom() + font.getFontHeight() * 1.25; + myFirstControl = new NullControlWidget(boss, font, x, y, *qt.myFirstController, true); break; } + x = t->getLeft() + fontWidth * 10; switch(qt.mySecondController->type()) { case Controller::Type::Joystick: + x += fontWidth * 2; + y = t->getBottom() + fontHeight; mySecondControl = new JoystickWidget(boss, font, x, y, *qt.mySecondController, true); break; + case Controller::Type::Driving: + y = t->getBottom() + font.getFontHeight(); + myFirstControl = new DrivingWidget(boss, font, x, y, *qt.mySecondController, true); + break; + default: - mySecondControl = new NullControlWidget(boss, font, x, y, *qt.mySecondController); + y = t->getBottom() + font.getFontHeight() * 1.25; + mySecondControl = new NullControlWidget(boss, font, x, y, *qt.mySecondController, true); break; } myPointer = new StaticTextWidget(boss, font, - x - font.getMaxCharWidth() * 5, y, " "); + t->getLeft() + font.getMaxCharWidth() * 7, y, " "); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index 390fcac01..64c0cf027 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -25,18 +25,20 @@ #include "AtariVox.hxx" #include "Driving.hxx" #include "Joystick.hxx" +#include "Paddles.hxx" #include "SaveKey.hxx" #include "QuadTari.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -QuadTari::QuadTari(Jack jack, OSystem& osystem, const System& system, const Properties& properties) +QuadTari::QuadTari(Jack jack, const OSystem& osystem, const System& system, const Properties& properties) : Controller(jack, osystem.eventHandler().event(), system, Controller::Type::QuadTari), - myOSystem(osystem) + myOSystem(osystem), + myProperties(properties) { - string first, second; Controller::Type firstType = Controller::Type::Joystick, secondType = Controller::Type::Joystick; + string first, second; if(jack == Controller::Jack::Left) { @@ -74,6 +76,16 @@ unique_ptr QuadTari::addController(const Controller::Type type, bool switch(type) { + case Controller::Type::Paddles: + { + // Check if we should swap the paddles plugged into a jack + bool swapPaddles = myProperties.get(PropType::Controller_SwapPaddles) == "YES"; + + return make_unique(myJack, myEvent, mySystem, swapPaddles, false, false); + } + case Controller::Type::Driving: + return make_unique(myJack, myEvent, mySystem, second); + case Controller::Type::AtariVox: { nvramfile /= "atarivox_eeprom.dat"; @@ -81,9 +93,6 @@ unique_ptr QuadTari::addController(const Controller::Type type, bool myOSystem.settings().getString("avoxport"), nvramfile, callback); // no alternative mapping here } - case Controller::Type::Driving: - return make_unique(myJack, myEvent, mySystem, second); - case Controller::Type::SaveKey: { nvramfile /= "savekey_eeprom.dat"; diff --git a/src/emucore/QuadTari.hxx b/src/emucore/QuadTari.hxx index 449a43dff..2ce42e319 100644 --- a/src/emucore/QuadTari.hxx +++ b/src/emucore/QuadTari.hxx @@ -38,7 +38,7 @@ class QuadTari : public Controller @param system The system using this controller @param properties The properties to use for the current ROM */ - QuadTari(Jack jack, OSystem& osystem, const System& system, const Properties& properties); + QuadTari(Jack jack, const OSystem& osystem, const System& system, const Properties& properties); ~QuadTari() override = default; public: @@ -91,7 +91,8 @@ class QuadTari : public Controller private: unique_ptr addController(const Controller::Type type, bool second); - OSystem& myOSystem; + const OSystem& myOSystem; + const Properties& myProperties; unique_ptr myFirstController; unique_ptr mySecondController; diff --git a/src/gui/QuadTariDialog.cxx b/src/gui/QuadTariDialog.cxx index 3db0a6a65..b4d1891ef 100644 --- a/src/gui/QuadTariDialog.cxx +++ b/src/gui/QuadTariDialog.cxx @@ -47,7 +47,7 @@ QuadTariDialog::QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w ctrls.clear(); //VarList::push_back(ctrls, "Auto-detect", "AUTO"); VarList::push_back(ctrls, "Joystick", "JOYSTICK"); - //VarList::push_back(ctrls, "Paddles", "PADDLES"); + VarList::push_back(ctrls, "Paddles", "PADDLES"); //VarList::push_back(ctrls, "Paddles_IAxis", "PADDLES_IAXIS"); //VarList::push_back(ctrls, "Paddles_IAxDr", "PADDLES_IAXDR"); //VarList::push_back(ctrls, "BoosterGrip", "BOOSTERGRIP"); @@ -64,7 +64,7 @@ QuadTariDialog::QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w //VarList::push_back(ctrls, "MindLink", "MINDLINK"); //VarList::push_back(ctrls, "QuadTari", "QUADTARI"); - int pwidth = font.getStringWidth("Joystick12"); // looks better overall + int pwidth = font.getStringWidth("Joystick12"); // a bit wider looks better overall myLeftPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Left port"); From 1eae318c530e1938dea5e92261061f4f2c1bef54 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Sun, 6 Sep 2020 19:10:08 +0200 Subject: [PATCH 037/263] enhanced UA bank switching to support more Brazilian carts (fixes #698) --- Changes.txt | 2 ++ src/debugger/gui/CartUAWidget.cxx | 2 +- src/emucore/CartDetector.cxx | 9 ++++++--- src/emucore/CartUA.cxx | 18 ++++++++++++++---- src/emucore/CartUA.hxx | 4 +++- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Changes.txt b/Changes.txt index 31e2254ef..b3929fb3c 100644 --- a/Changes.txt +++ b/Changes.txt @@ -39,6 +39,8 @@ * Added option to select the audio device. + * Further enhanced UA bankswitching to support more Brazilian carts. + * Added option to display detected settings info when a ROM is loaded. * Added another oddball TIA glitch option for delayed background color. diff --git a/src/debugger/gui/CartUAWidget.cxx b/src/debugger/gui/CartUAWidget.cxx index f6ae16bc7..02728b52d 100644 --- a/src/debugger/gui/CartUAWidget.cxx +++ b/src/debugger/gui/CartUAWidget.cxx @@ -47,7 +47,7 @@ string CartridgeUAWidget::hotspotStr(int bank, int, bool prefix) uInt16 hotspot = myCart.hotspot() + (bank ^ (mySwappedHotspots ? 1 : 0)) * myHotspotDelta; info << "(" << (prefix ? "hotspot " : ""); - info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80); + info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80) << ", $" << (hotspot | 0xf80); info << ")"; return info.str(); diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 0ecc6e82e..dba8bb3e4 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -708,15 +708,18 @@ bool CartDetector::isProbablyUA(const ByteBuffer& image, size_t size) // using 'STA $240' or 'LDA $240' // Similar Brazilian (Digivison) cart bankswitching switches to bank 1 by accessing address 0x2C0 // using 'BIT $2C0', 'STA $2C0' or 'LDA $2C0' - uInt8 signature[6][3] = { + // Other Brazilian (Atari Mania) ROM's bankswitching switches to bank 1 by accessing address 0xFC0 + // using 'BIT $FA0', 'BIT $FC0' or 'STA $FA0' + uInt8 signature[7][3] = { { 0x8D, 0x40, 0x02 }, // STA $240 (Funky Fish, Pleiades) { 0xAD, 0x40, 0x02 }, // LDA $240 (???) { 0xBD, 0x1F, 0x02 }, // LDA $21F,X (Gingerbread Man) { 0x2C, 0xC0, 0x02 }, // BIT $2C0 (Time Pilot) { 0x8D, 0xC0, 0x02 }, // STA $2C0 (Fathom, Vanguard) - { 0xAD, 0xC0, 0x02 } // LDA $2C0 (Mickey) + { 0xAD, 0xC0, 0x02 }, // LDA $2C0 (Mickey) + { 0x2C, 0xC0, 0x0F } // BIT $FC0 (H.E.R.O., Kung-Fu Master) }; - for(uInt32 i = 0; i < 6; ++i) + for(uInt32 i = 0; i < 7; ++i) if(searchForBytes(image, size, signature[i], 3)) return true; diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index e73f166db..83afca20e 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -39,11 +39,21 @@ void CartridgeUA::install(System& system) // Set the page accessing methods for the hot spots System::PageAccess access(this, System::PageAccessType::READ); - mySystem->setPageAccess(0x0220, access); - mySystem->setPageAccess(0x0240, access); - mySystem->setPageAccess(0x0220 | 0x80, access); - mySystem->setPageAccess(0x0240 | 0x80, access); + // Map all potential addresses + // - A11, A10 and A8 are not connected to RIOT + // - A9 is the fixed part of the hotspot address + // - A7 is used by Brazilian carts + // - A5 and A4 determine bank + for(uInt16 a11 = 0; a11 <= 1; ++a11) + for(uInt16 a10 = 0; a10 <= 1; ++a10) + for(uInt16 a8 = 0; a8 <= 1; ++a8) + for(uInt16 a7 = 0; a7 <= 1; ++a7) + { + uInt16 addr = (a11 << 11) + (a10 << 10) + (a8 << 8) + (a7 << 7); + mySystem->setPageAccess(0x0220 | addr, access); + mySystem->setPageAccess(0x0240 | addr, access); + } // Install pages for the startup bank bank(startBank()); } diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx index 95d4d022d..f5b25803f 100644 --- a/src/emucore/CartUA.hxx +++ b/src/emucore/CartUA.hxx @@ -28,7 +28,9 @@ /** Cartridge class used for UA Limited's 8K bankswitched games. There are two 4K banks, which are switched by accessing $0220 (bank 0) and - $0240 (bank 1). + $0240 (bank 1). Similar addresses are used by Brazilian carts, e.g. + $02A0, $02C0 and $0FA0, $0FC0. The code accepts further potential + hotspot addresses. @author Bradford W. Mott, Thomas Jentzsch */ From 6c06d05c959e5971b15a5dddadda69395e4cf6f3 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Mon, 7 Sep 2020 15:37:45 +0200 Subject: [PATCH 038/263] added more controller widget support for QuadTari added tabbing through controller widgets --- src/debugger/gui/AtariVoxWidget.cxx | 5 +- src/debugger/gui/AtariVoxWidget.hxx | 2 +- src/debugger/gui/BoosterWidget.cxx | 8 ++ src/debugger/gui/DrivingWidget.cxx | 53 ++++++++------ src/debugger/gui/FlashWidget.cxx | 48 +++++++----- src/debugger/gui/FlashWidget.hxx | 6 +- src/debugger/gui/GenesisWidget.cxx | 7 ++ src/debugger/gui/JoystickWidget.cxx | 14 +++- src/debugger/gui/KeyboardWidget.cxx | 1 + src/debugger/gui/PaddleWidget.cxx | 87 ++++++++++++++++------ src/debugger/gui/PaddleWidget.hxx | 3 +- src/debugger/gui/PointingDeviceWidget.cxx | 6 ++ src/debugger/gui/QuadTariWidget.cxx | 89 ++++++++++++----------- src/debugger/gui/QuadTariWidget.hxx | 5 +- src/debugger/gui/RiotWidget.cxx | 2 + src/debugger/gui/RomListWidget.cxx | 28 +++---- src/debugger/gui/SaveKeyWidget.cxx | 4 +- src/debugger/gui/SaveKeyWidget.hxx | 2 +- src/gui/CheckListWidget.cxx | 20 ++--- src/gui/ListWidget.cxx | 4 +- src/gui/StringListWidget.cxx | 10 +-- src/gui/TabWidget.cxx | 2 +- src/gui/Widget.cxx | 4 +- src/gui/Widget.hxx | 2 +- 24 files changed, 257 insertions(+), 155 deletions(-) diff --git a/src/debugger/gui/AtariVoxWidget.cxx b/src/debugger/gui/AtariVoxWidget.cxx index 0a38d2ec5..3d3dfe762 100644 --- a/src/debugger/gui/AtariVoxWidget.cxx +++ b/src/debugger/gui/AtariVoxWidget.cxx @@ -20,10 +20,11 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AtariVoxWidget::AtariVoxWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, Controller& controller) + int x, int y, Controller& controller, + bool embedded) : FlashWidget(boss, font, x, y, controller) { - init(boss, font, x, y); + init(boss, font, x, y, embedded); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/AtariVoxWidget.hxx b/src/debugger/gui/AtariVoxWidget.hxx index cf168173d..ea0345762 100644 --- a/src/debugger/gui/AtariVoxWidget.hxx +++ b/src/debugger/gui/AtariVoxWidget.hxx @@ -26,7 +26,7 @@ class AtariVoxWidget : public FlashWidget { public: AtariVoxWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - Controller& controller); + Controller& controller, bool embedded = false); ~AtariVoxWidget() override = default; private: diff --git a/src/debugger/gui/BoosterWidget.cxx b/src/debugger/gui/BoosterWidget.cxx index 1820919bb..b1056c069 100644 --- a/src/debugger/gui/BoosterWidget.cxx +++ b/src/debugger/gui/BoosterWidget.cxx @@ -73,6 +73,14 @@ BoosterWidget::BoosterWidget(GuiObject* boss, const GUI::Font& font, CheckboxWidget::kCheckActionCmd); myPins[kJTrigger]->setID(kJTrigger); myPins[kJTrigger]->setTarget(this); + + addFocusWidget(myPins[kJUp]); + addFocusWidget(myPins[kJLeft]); + addFocusWidget(myPins[kJRight]); + addFocusWidget(myPins[kJDown]); + addFocusWidget(myPins[kJFire]); + addFocusWidget(myPins[kJBooster]); + addFocusWidget(myPins[kJTrigger]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/DrivingWidget.cxx b/src/debugger/gui/DrivingWidget.cxx index 3dadc24b4..5f0b74d95 100644 --- a/src/debugger/gui/DrivingWidget.cxx +++ b/src/debugger/gui/DrivingWidget.cxx @@ -25,49 +25,56 @@ DrivingWidget::DrivingWidget(GuiObject* boss, const GUI::Font& font, { const string& label = getHeader(); - const int fontHeight = font.getFontHeight(), - fontWidth = font.getMaxCharWidth(), - bheight = font.getLineHeight() + 4; - int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Driving)"); - StaticTextWidget* t; + const int lineHeight = font.getLineHeight(), + bHeight = font.getLineHeight() * 1.25; + int xpos = x, ypos = y; if(embedded) { - const int bwidth = font.getStringWidth("GC+ "); + const int bWidth = font.getStringWidth("GC+ "); - myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + ypos += _lineHeight * 0.334; + myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight, "GC+", kGrayUpCmd); - ypos += myGrayUp->getHeight() + 5; - myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + ypos += myGrayUp->getHeight() + bHeight * 0.3; + myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight, "GC-", kGrayDownCmd); + xpos += myGrayDown->getWidth() + _fontWidth * 0.75; } else { - const int bwidth = font.getStringWidth("Gray code +") + 10; - t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth, - fontHeight, label, TextAlign::Left); + const int lwidth = font.getStringWidth("Right (Driving)"), + bWidth = font.getStringWidth("Gray code +") + _fontWidth * 1.25; - ypos += t->getHeight() + 20; - myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + StaticTextWidget* t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth, + lineHeight, label, TextAlign::Left); + + ypos = t->getBottom() + _lineHeight * 1.334; + myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight, "Gray code +", kGrayUpCmd); - ypos += myGrayUp->getHeight() + 5; - myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, + ypos += myGrayUp->getHeight() + bHeight * 0.3; + myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight, "Gray code -", kGrayDownCmd); + xpos += myGrayDown->getWidth() + _fontWidth; } - myGrayUp->setTarget(this); - myGrayDown->setTarget(this); - - xpos += myGrayDown->getWidth() + fontWidth; ypos -= 10; + ypos -= bHeight * 0.6; myGrayValue = new DataGridWidget(boss, font, xpos, ypos, 1, 1, 2, 8, Common::Base::Fmt::_16); + + xpos = x + myGrayDown->getWidth() * 0.25; ypos = myGrayDown->getBottom() + _lineHeight; + myFire = new CheckboxWidget(boss, font, xpos, ypos, "Fire", kFireCmd); + + myGrayUp->setTarget(this); + myGrayDown->setTarget(this); myGrayValue->setTarget(this); myGrayValue->setEditable(false); - - xpos = x + fontWidth*3; ypos += myGrayDown->getHeight() + 20; - myFire = new CheckboxWidget(boss, font, xpos, ypos, "Fire", kFireCmd); myFire->setTarget(this); + + addFocusWidget(myGrayUp); + addFocusWidget(myGrayDown); + addFocusWidget(myFire); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/FlashWidget.cxx b/src/debugger/gui/FlashWidget.cxx index 3c2614659..c432b16ca 100644 --- a/src/debugger/gui/FlashWidget.cxx +++ b/src/debugger/gui/FlashWidget.cxx @@ -28,31 +28,43 @@ FlashWidget::FlashWidget(GuiObject* boss, const GUI::Font& font, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FlashWidget::init(GuiObject* boss, const GUI::Font& font, int x, int y) +void FlashWidget::init(GuiObject* boss, const GUI::Font& font, + int x, int y, bool embedded) { - const int lineHeight = font.getLineHeight(); + const int fontHeight = font.getFontHeight(); int xpos = x, ypos = y; - new StaticTextWidget(boss, font, xpos, ypos + 2, getHeader()); + myEmbedded = embedded; + if(!embedded) + { + new StaticTextWidget(boss, font, xpos, ypos + 2, getHeader()); - ypos += lineHeight + 6; + ypos += _lineHeight * 1.4; + new StaticTextWidget(boss, font, xpos, ypos, "Pages/Ranges used:"); + } + else + { + ypos += _lineHeight * 0.4 - (2 + _lineHeight); + new StaticTextWidget(boss, font, xpos, ypos, "Pages:"); + } - new StaticTextWidget(boss, font, xpos, ypos, "Pages/Ranges used:"); - - ypos += lineHeight + 2; + ypos += _lineHeight + 2; xpos += 8; - for(uInt32 page = 0; page < MAX_PAGES; ++page) { myPage[page] = new StaticTextWidget(boss, font, xpos, ypos, - page ? " " : "none "); - ypos += lineHeight; + embedded ? page ? " " : "none" + : page ? " " : "none "); + ypos += _lineHeight; } xpos -= 8; ypos += 2; myEEPROMEraseCurrent = new ButtonWidget(boss, font, xpos, ypos, - "Erase used pages", kEEPROMEraseCurrent); + embedded ? "Erase" : "Erase used pages", + kEEPROMEraseCurrent); myEEPROMEraseCurrent->setTarget(this); + + addFocusWidget(myEEPROMEraseCurrent); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -86,12 +98,14 @@ void FlashWidget::loadConfig() label.str(""); label << Common::Base::HEX3 << startPage; - if(int(page) - 1 != startPage) - label << "-" << Common::Base::HEX3 << page - 1; - else - label << " "; - label << ": " << Common::Base::HEX4 << from << "-" << Common::Base::HEX4 << to; - + if(!myEmbedded) + { + if(int(page) - 1 != startPage) + label << "-" << Common::Base::HEX3 << page - 1; + else + label << " "; + label << ": " << Common::Base::HEX4 << from << "-" << Common::Base::HEX4 << to; + } myPage[useCount]->setLabel(label.str()); startPage = -1; diff --git a/src/debugger/gui/FlashWidget.hxx b/src/debugger/gui/FlashWidget.hxx index cb085be9d..5db1cae2f 100644 --- a/src/debugger/gui/FlashWidget.hxx +++ b/src/debugger/gui/FlashWidget.hxx @@ -31,12 +31,14 @@ class FlashWidget : public ControllerWidget ~FlashWidget() override = default; protected: - void init(GuiObject* boss, const GUI::Font& font, int x, int y); + void init(GuiObject* boss, const GUI::Font& font, int x, int y, bool embedded); private: - ButtonWidget* myEEPROMEraseCurrent{nullptr}; enum { kEEPROMEraseCurrent = 'eeEC' }; + bool myEmbedded{false}; + ButtonWidget* myEEPROMEraseCurrent{nullptr}; + static constexpr uInt32 MAX_PAGES = 5; std::array myPage{nullptr}; diff --git a/src/debugger/gui/GenesisWidget.cxx b/src/debugger/gui/GenesisWidget.cxx index 70833879a..fcf05ce2f 100644 --- a/src/debugger/gui/GenesisWidget.cxx +++ b/src/debugger/gui/GenesisWidget.cxx @@ -67,6 +67,13 @@ GenesisWidget::GenesisWidget(GuiObject* boss, const GUI::Font& font, CheckboxWidget::kCheckActionCmd); myPins[kJCbtn]->setID(kJCbtn); myPins[kJCbtn]->setTarget(this); + + addFocusWidget(myPins[kJUp]); + addFocusWidget(myPins[kJLeft]); + addFocusWidget(myPins[kJRight]); + addFocusWidget(myPins[kJDown]); + addFocusWidget(myPins[kJBbtn]); + addFocusWidget(myPins[kJCbtn]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/JoystickWidget.cxx b/src/debugger/gui/JoystickWidget.cxx index 80455dea0..2581f41ae 100644 --- a/src/debugger/gui/JoystickWidget.cxx +++ b/src/debugger/gui/JoystickWidget.cxx @@ -23,17 +23,17 @@ JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font, bool embedded) : ControllerWidget(boss, font, x, y, controller) { + const int fontHeight = font.getFontHeight(); int xpos = x, ypos = y; if(!embedded) { const string& label = getHeader(); - const int fontHeight = font.getFontHeight(); - int lwidth = font.getStringWidth("Right (Joystick)"); + const int lwidth = font.getStringWidth("Right (Joystick)"); StaticTextWidget* t; t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth, - fontHeight, label, TextAlign::Left); + _lineHeight, label, TextAlign::Left); xpos += t->getWidth() / 2 - 5; ypos = t->getBottom() + fontHeight; } myPins[kJUp] = new CheckboxWidget(boss, font, xpos, ypos, "", @@ -61,11 +61,17 @@ JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font, myPins[kJRight]->setTarget(this); xpos -= (myPins[kJUp]->getWidth() + 5) * 2; - ypos = myPins[kJDown]->getBottom() + font.getFontHeight() * 0.5 - 1; + ypos = myPins[kJDown]->getBottom() + fontHeight * 0.75; myPins[kJFire] = new CheckboxWidget(boss, font, xpos, ypos, "Fire", CheckboxWidget::kCheckActionCmd); myPins[kJFire]->setID(kJFire); myPins[kJFire]->setTarget(this); + + addFocusWidget(myPins[kJUp]); + addFocusWidget(myPins[kJLeft]); + addFocusWidget(myPins[kJRight]); + addFocusWidget(myPins[kJDown]); + addFocusWidget(myPins[kJFire]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/KeyboardWidget.cxx b/src/debugger/gui/KeyboardWidget.cxx index 296217d1e..1496b172c 100644 --- a/src/debugger/gui/KeyboardWidget.cxx +++ b/src/debugger/gui/KeyboardWidget.cxx @@ -47,6 +47,7 @@ KeyboardWidget::KeyboardWidget(GuiObject* boss, const GUI::Font& font, xpos = x + 30; ypos += myBox[i]->getHeight() + 5; } + addFocusWidget(myBox[i]); } myEvent = leftport ? ourLeftEvents.data() : ourRightEvents.data(); } diff --git a/src/debugger/gui/PaddleWidget.cxx b/src/debugger/gui/PaddleWidget.cxx index 87d9fe6ec..d3e31d656 100644 --- a/src/debugger/gui/PaddleWidget.cxx +++ b/src/debugger/gui/PaddleWidget.cxx @@ -19,49 +19,90 @@ #include "PaddleWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, Controller& controller) +PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font, int x, int y, + Controller& controller, bool embedded, bool second) : ControllerWidget(boss, font, x, y, controller) { bool leftport = isLeftPort(); const string& label = getHeader(); + const int fontHeight = font.getFontHeight(); - const int fontHeight = font.getFontHeight(), - lineHeight = font.getLineHeight(); - int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Paddles)"); + int xpos = x, ypos = y, + lwidth = font.getStringWidth("Right (Paddles)"); - new StaticTextWidget(boss, font, xpos, ypos+2, lwidth, - fontHeight, label); + if(!embedded) + { + new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth, + _lineHeight, label); + ypos += _lineHeight + fontHeight + 2; - ypos += lineHeight + 20; - const string& p0string = leftport ? "P0 pot " : "P2 pot "; - const string& p1string = leftport ? "P1 pot " : "P3 pot "; - myP0Resistance = - new SliderWidget(boss, font, xpos, ypos, - p0string, 0, kP0Changed); + const string& p0string = leftport ? "P1 pot " : "P3 pot "; + const string& p1string = leftport ? "P2 pot " : "P4 pot "; + myP0Resistance = + new SliderWidget(boss, font, xpos, ypos, + p0string, 0, kP0Changed); + + xpos += 20; ypos += myP0Resistance->getHeight() * 1.33; + myP0Fire = new CheckboxWidget(boss, font, xpos, ypos, + "Fire", kP0Fire); + + xpos = x; ypos += _lineHeight * 2.25; + myP1Resistance = + new SliderWidget(boss, font, xpos, ypos, + p1string, 0, kP1Changed); + + xpos += 20; ypos += myP1Resistance->getHeight() * 1.33; + myP1Fire = new CheckboxWidget(boss, font, xpos, ypos, + "Fire", kP1Fire); + } + else + { + const string& p0string = leftport ? second ? "P1b" : "P1a" + : second ? "P3b" : "P3a"; + const string& p1string = leftport ? second ? "P2b" : "P2a" + : second ? "P4b" : "P4a"; + + new StaticTextWidget(boss, font, xpos, ypos + 2, p0string); + + //ypos += lineHeight; + myP0Resistance = new SliderWidget(boss, font, xpos, ypos); + myP0Resistance->setEnabled(false); + myP0Resistance->setFlags(Widget::FLAG_INVISIBLE); + + ypos += _lineHeight * 1.33; + myP0Fire = new CheckboxWidget(boss, font, xpos, ypos, + "Fire", kP0Fire); + + xpos = x; ypos += _lineHeight * 2.25; + new StaticTextWidget(boss, font, xpos, ypos + 2, p1string); + + //ypos += lineHeight; + myP1Resistance = new SliderWidget(boss, font, xpos, ypos); + myP1Resistance->setEnabled(false); + myP1Resistance->setFlags(Widget::FLAG_INVISIBLE); + + ypos += _lineHeight * 1.33; + myP1Fire = new CheckboxWidget(boss, font, xpos, ypos, + "Fire", kP1Fire); + } myP0Resistance->setMinValue(0); myP0Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE)); myP0Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100)); myP0Resistance->setTarget(this); - xpos += 20; ypos += myP0Resistance->getHeight() + 4; - myP0Fire = new CheckboxWidget(boss, font, xpos, ypos, - "Fire", kP0Fire); myP0Fire->setTarget(this); - xpos = x; ypos += 2*lineHeight; - myP1Resistance = - new SliderWidget(boss, font, xpos, ypos, - p1string, 0, kP1Changed); myP1Resistance->setMinValue(0); myP1Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE)); myP1Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100)); myP1Resistance->setTarget(this); - xpos += 20; ypos += myP1Resistance->getHeight() + 4; - myP1Fire = new CheckboxWidget(boss, font, xpos, ypos, - "Fire", kP1Fire); myP1Fire->setTarget(this); + + addFocusWidget(myP0Resistance); + addFocusWidget(myP0Fire); + addFocusWidget(myP1Resistance); + addFocusWidget(myP1Fire); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/PaddleWidget.hxx b/src/debugger/gui/PaddleWidget.hxx index 8773b5a1d..e3034c80c 100644 --- a/src/debugger/gui/PaddleWidget.hxx +++ b/src/debugger/gui/PaddleWidget.hxx @@ -26,7 +26,8 @@ class PaddleWidget : public ControllerWidget { public: PaddleWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - Controller& controller); + Controller& controller, + bool embedded = false, bool second = false); ~PaddleWidget() override = default; private: diff --git a/src/debugger/gui/PointingDeviceWidget.cxx b/src/debugger/gui/PointingDeviceWidget.cxx index 43bbc4ed5..56127c83c 100644 --- a/src/debugger/gui/PointingDeviceWidget.cxx +++ b/src/debugger/gui/PointingDeviceWidget.cxx @@ -68,6 +68,12 @@ PointingDeviceWidget::PointingDeviceWidget(GuiObject* boss, const GUI::Font& fon myFire = new CheckboxWidget(boss, font, xLeft, ypos, "Fire", kTBFire); myFire->setTarget(this); + + addFocusWidget(myGrayUp); + addFocusWidget(myGrayLeft); + addFocusWidget(myGrayRight); + addFocusWidget(myGrayDown); + addFocusWidget(myFire); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/QuadTariWidget.cxx b/src/debugger/gui/QuadTariWidget.cxx index 23db86995..3ab7c0e78 100644 --- a/src/debugger/gui/QuadTariWidget.cxx +++ b/src/debugger/gui/QuadTariWidget.cxx @@ -19,9 +19,13 @@ #include "Console.hxx" #include "TIA.hxx" #include "QuadTari.hxx" +#include "AtariVoxWidget.hxx" #include "DrivingWidget.hxx" #include "JoystickWidget.hxx" #include "NullControlWidget.hxx" +#include "PaddleWidget.hxx" +#include "SaveKeyWidget.hxx" + #include "QuadTariWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -29,54 +33,55 @@ QuadTariWidget::QuadTariWidget(GuiObject* boss, const GUI::Font& font, int x, int y, Controller& controller) : ControllerWidget(boss, font, x, y, controller) { - const int fontWidth = font.getMaxCharWidth(), - fontHeight = font.getFontHeight(); string label = (isLeftPort() ? "Left" : "Right") + string(" (QuadTari)"); StaticTextWidget* t = new StaticTextWidget(boss, font, x, y + 2, label); QuadTari& qt = static_cast(controller); - // TODO: support multiple controller types - switch(qt.myFirstController->type()) - { - case Controller::Type::Joystick: - x += fontWidth * 2; - y = t->getBottom() + fontHeight; - myFirstControl = new JoystickWidget(boss, font, x, y, *qt.myFirstController, true); - break; - - case Controller::Type::Driving: - y = t->getBottom() + font.getFontHeight() * 1; - myFirstControl = new DrivingWidget(boss, font, x, y, *qt.myFirstController, true); - break; - - default: - y = t->getBottom() + font.getFontHeight() * 1.25; - myFirstControl = new NullControlWidget(boss, font, x, y, *qt.myFirstController, true); - break; - } - - x = t->getLeft() + fontWidth * 10; - switch(qt.mySecondController->type()) - { - case Controller::Type::Joystick: - x += fontWidth * 2; - y = t->getBottom() + fontHeight; - mySecondControl = new JoystickWidget(boss, font, x, y, *qt.mySecondController, true); - break; - - case Controller::Type::Driving: - y = t->getBottom() + font.getFontHeight(); - myFirstControl = new DrivingWidget(boss, font, x, y, *qt.mySecondController, true); - break; - - default: - y = t->getBottom() + font.getFontHeight() * 1.25; - mySecondControl = new NullControlWidget(boss, font, x, y, *qt.mySecondController, true); - break; - } + y = t->getBottom() + _lineHeight; + addController(boss, x, y, *qt.myFirstController, false); + addController(boss, x, y, *qt.mySecondController, true); myPointer = new StaticTextWidget(boss, font, - t->getLeft() + font.getMaxCharWidth() * 7, y, " "); + t->getLeft() + _fontWidth * 7, y, " "); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void QuadTariWidget::addController(GuiObject* boss, int x, int y, + Controller& controller, bool second) +{ + ControllerWidget* widget; + + x += second ? _fontWidth * 10 : 0; + switch(controller.type()) + { + case Controller::Type::Joystick: + x += _fontWidth * 2; + widget = new JoystickWidget(boss, _font, x, y, controller, true); + break; + + case Controller::Type::Driving: + widget = new DrivingWidget(boss, _font, x, y, controller, true); + break; + + case Controller::Type::Paddles: + widget = new PaddleWidget(boss, _font, x, y, controller, true, second); + break; + + case Controller::Type::AtariVox: + widget = new AtariVoxWidget(boss, _font, x, y, controller, true); + break; + + case Controller::Type::SaveKey: + widget = new SaveKeyWidget(boss, _font, x, y, controller, true); + break; + + default: + widget = new NullControlWidget(boss, _font, x, y, controller, true); + break; + } + WidgetArray focusList = widget->getFocusList(); + if(!focusList.empty()) + addToFocusList(focusList); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/QuadTariWidget.hxx b/src/debugger/gui/QuadTariWidget.hxx index cccdf1575..2af39743b 100644 --- a/src/debugger/gui/QuadTariWidget.hxx +++ b/src/debugger/gui/QuadTariWidget.hxx @@ -35,12 +35,13 @@ class QuadTariWidget: public ControllerWidget } private: - ControllerWidget* myFirstControl{nullptr}; - ControllerWidget* mySecondControl{nullptr}; StaticTextWidget* myPointer{nullptr}; void loadConfig() override; + void addController(GuiObject* boss, int x, int y, + Controller& controller, bool second); + // Following constructors and assignment operators not supported QuadTariWidget() = delete; QuadTariWidget(const QuadTariWidget&) = delete; diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index 171da0cd6..883772062 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -141,9 +141,11 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, xpos = col; ypos = 10; myLeftControl = addControlWidget(boss, lfont, xpos, ypos, instance().console().leftController()); + addToFocusList(myLeftControl->getFocusList()); xpos += myLeftControl->getWidth() + 15; myRightControl = addControlWidget(boss, lfont, xpos, ypos, instance().console().rightController()); + addToFocusList(myRightControl->getFocusList()); // TIA INPTx registers (R), left port static constexpr std::array contLeftReadNames = { diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 6e450e334..07bbbf668 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -40,7 +40,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, _textcolorhi = kTextColor; _cols = w / _fontWidth; - _rows = h / _fontHeight; + _rows = h / _lineHeight; // Set real dimensions _w = w - ScrollBarWidget::scrollBarWidth(_font); @@ -67,8 +67,8 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, // rowheight is determined by largest item on a line, // possibly meaning that number of rows will change - _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize(_font)); - _rows = h / _fontHeight; + _lineHeight = std::max(_lineHeight, CheckboxWidget::boxSize(_font)); + _rows = h / _lineHeight; // Create a CheckboxWidget for each row in the list for(int i = 0; i < _rows; ++i) @@ -79,7 +79,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, t->setID(i); t->setFill(CheckboxWidget::FillType::Circle); t->setTextColor(kTextColorEm); - ypos += _fontHeight; + ypos += _lineHeight; myCheckList.push_back(t); } @@ -175,7 +175,7 @@ void RomListWidget::setHighlighted(int item) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int RomListWidget::findItem(int x, int y) const { - return (y - 1) / _fontHeight + _currentPos; + return (y - 1) / _lineHeight + _currentPos; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -479,7 +479,7 @@ void RomListWidget::drawWidget(bool hilite) codeDisasmW = actualWidth; xpos = _x + CheckboxWidget::boxSize(_font) + 10; ypos = _y + 2; - for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _fontHeight) + for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _lineHeight) { ColorId bytesColor = textColor; @@ -493,18 +493,18 @@ void RomListWidget::drawWidget(bool hilite) // Draw highlighted item in a frame if (_highlightedItem == pos) - s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _fontHeight, onTop ? kWidColorHi : kBGColorLo); + s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _lineHeight, onTop ? kWidColorHi : kBGColorLo); // Draw the selected item inverted, on a highlighted background. if(_selectedItem == pos && _hasFocus) { if(!_editMode) { - s.fillRect(_x + r.x() - 3, ypos - 1, r.w(), _fontHeight, kTextColorHi); + s.fillRect(_x + r.x() - 3, ypos - 1, r.w(), _lineHeight, kTextColorHi); bytesColor = kTextColorInv; } else - s.frameRect(_x + r.x() - 3, ypos - 1, r.w(), _fontHeight, kWidColorHi); + s.frameRect(_x + r.x() - 3, ypos - 1, r.w(), _lineHeight, kWidColorHi); } // Draw labels @@ -537,7 +537,7 @@ void RomListWidget::drawWidget(bool hilite) } // Draw separator - s.vLine(_x + r.x() - 7, ypos, ypos + _fontHeight - 1, kColor); + s.vLine(_x + r.x() - 7, ypos, ypos + _lineHeight - 1, kColor); // Draw bytes { @@ -567,20 +567,20 @@ void RomListWidget::drawWidget(bool hilite) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common::Rect RomListWidget::getLineRect() const { - const int yoffset = std::max(0, (_selectedItem - _currentPos) * _fontHeight), + const int yoffset = std::max(0, (_selectedItem - _currentPos) * _lineHeight), xoffset = CheckboxWidget::boxSize(_font) + 10; return Common::Rect(2 + xoffset, 1 + yoffset, - _w - (xoffset - 15), _fontHeight + yoffset); + _w - (xoffset - 15), _lineHeight + yoffset); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common::Rect RomListWidget::getEditRect() const { - const int yoffset = std::max(0, (_selectedItem - _currentPos) * _fontHeight); + const int yoffset = std::max(0, (_selectedItem - _currentPos) * _lineHeight); return Common::Rect(2 + _w - _bytesWidth, 1 + yoffset, - _w, _fontHeight + yoffset); + _w, _lineHeight + yoffset); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/SaveKeyWidget.cxx b/src/debugger/gui/SaveKeyWidget.cxx index eb6602ad3..92c58329e 100644 --- a/src/debugger/gui/SaveKeyWidget.cxx +++ b/src/debugger/gui/SaveKeyWidget.cxx @@ -20,10 +20,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SaveKeyWidget::SaveKeyWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, Controller& controller) + int x, int y, Controller& controller, bool embedded) : FlashWidget(boss, font, x, y, controller) { - init(boss, font, x, y); + init(boss, font, x, y, embedded); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/SaveKeyWidget.hxx b/src/debugger/gui/SaveKeyWidget.hxx index 3a646f2d4..e3e6b5213 100644 --- a/src/debugger/gui/SaveKeyWidget.hxx +++ b/src/debugger/gui/SaveKeyWidget.hxx @@ -26,7 +26,7 @@ class SaveKeyWidget : public FlashWidget { public: SaveKeyWidget(GuiObject* boss, const GUI::Font& font, int x, int y, - Controller& controller); + Controller& controller, bool embedded = false); ~SaveKeyWidget() override = default; private: diff --git a/src/gui/CheckListWidget.cxx b/src/gui/CheckListWidget.cxx index 0e5a46d82..1e6db844a 100644 --- a/src/gui/CheckListWidget.cxx +++ b/src/gui/CheckListWidget.cxx @@ -29,8 +29,8 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font, // rowheight is determined by largest item on a line, // possibly meaning that number of rows will change - _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize(_font)); - _rows = h / _fontHeight; + _lineHeight = std::max(_lineHeight, CheckboxWidget::boxSize(_font)); + _rows = h / _lineHeight; // Create a CheckboxWidget for each row in the list for(int i = 0; i < _rows; ++i) @@ -40,7 +40,7 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font, t->setTextColor(kTextColor); t->setTarget(this); t->setID(i); - ypos += _fontHeight; + ypos += _lineHeight; _checkList.push_back(t); } @@ -110,7 +110,7 @@ void CheckListWidget::drawWidget(bool hilite) _checkList[i]->setDirty(); _checkList[i]->draw(); - const int y = _y + 2 + _fontHeight * i + 2; + const int y = _y + 2 + _lineHeight * i + 2; ColorId textColor = kTextColor; Common::Rect r(getEditRect()); @@ -120,13 +120,13 @@ void CheckListWidget::drawWidget(bool hilite) { if(_hasFocus && !_editMode) { - s.fillRect(_x + r.x() - 3, _y + 1 + _fontHeight * i, - _w - r.x(), _fontHeight, kTextColorHi); + s.fillRect(_x + r.x() - 3, _y + 1 + _lineHeight * i, + _w - r.x(), _lineHeight, kTextColorHi); textColor = kTextColorInv; } else - s.frameRect(_x + r.x() - 3, _y + 1 + _fontHeight * i, - _w - r.x(), _fontHeight, onTop ? kTextColorHi : kColor); + s.frameRect(_x + r.x() - 3, _y + 1 + _lineHeight * i, + _w - r.x(), _lineHeight, onTop ? kTextColorHi : kColor); } if (_selectedItem == pos && _editMode) @@ -149,11 +149,11 @@ void CheckListWidget::drawWidget(bool hilite) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common::Rect CheckListWidget::getEditRect() const { - const int yoffset = (_selectedItem - _currentPos) * _fontHeight, + const int yoffset = (_selectedItem - _currentPos) * _lineHeight, xoffset = CheckboxWidget::boxSize(_font) + 10; return Common::Rect(2 + xoffset, 1 + yoffset, - _w - (xoffset - 15), _fontHeight + yoffset); + _w - (xoffset - 15), _lineHeight + yoffset); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ListWidget.cxx b/src/gui/ListWidget.cxx index aa8ed9455..1ac71eb35 100644 --- a/src/gui/ListWidget.cxx +++ b/src/gui/ListWidget.cxx @@ -36,7 +36,7 @@ ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font, _textcolorhi = kTextColor; _cols = w / _fontWidth; - _rows = h / _fontHeight; + _rows = h / _lineHeight; // Set real dimensions _w = w - ScrollBarWidget::scrollBarWidth(_font); @@ -236,7 +236,7 @@ void ListWidget::handleMouseWheel(int x, int y, int direction) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int ListWidget::findItem(int x, int y) const { - return (y - 1) / _fontHeight + _currentPos; + return (y - 1) / _lineHeight + _currentPos; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 46aed13ba..0c0a8ba08 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -79,7 +79,7 @@ void StringListWidget::drawWidget(bool hilite) // Draw the list items for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++) { - const int y = _y + 2 + _fontHeight * i; + const int y = _y + 2 + _lineHeight * i; ColorId textColor = onTop ? kTextColor : kShadowColor; // Draw the selected item inverted, on a highlighted background. @@ -87,11 +87,11 @@ void StringListWidget::drawWidget(bool hilite) { if(_hasFocus && !_editMode) { - s.fillRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kTextColorHi); + s.fillRect(_x + 1, _y + 1 + _lineHeight * i, _w - 1, _lineHeight, kTextColorHi); textColor = kTextColorInv; } else - s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kWidColorHi); + s.frameRect(_x + 1, _y + 1 + _lineHeight * i, _w - 1, _lineHeight, kWidColorHi); } Common::Rect r(getEditRect()); @@ -115,6 +115,6 @@ void StringListWidget::drawWidget(bool hilite) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Common::Rect StringListWidget::getEditRect() const { - const int offset = std::max(0, (_selectedItem - _currentPos) * _fontHeight); - return Common::Rect(_textOfs, 1 + offset, _w - _textOfs, _fontHeight + offset); + const int offset = std::max(0, (_selectedItem - _currentPos) * _lineHeight); + return Common::Rect(_textOfs, 1 + offset, _w - _textOfs, _lineHeight + offset); } diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx index accd65445..f1b92b876 100644 --- a/src/gui/TabWidget.cxx +++ b/src/gui/TabWidget.cxx @@ -292,7 +292,7 @@ void TabWidget::drawWidget(bool hilite) ? onTop ? kDlgColor : kBGColorLo : onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset, - _y + yOffset + (_tabHeight - _fontHeight - 1), + _y + yOffset + (_tabHeight - _lineHeight - 1), tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center); if(i == _activeTab) { diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index ed6ba2f02..a54d9e45c 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -39,7 +39,7 @@ Widget::Widget(GuiObject* boss, const GUI::Font& font, _boss->_firstWidget = this; _fontWidth = _font.getMaxCharWidth(); - _fontHeight = _font.getLineHeight(); + _lineHeight = _font.getLineHeight(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -466,7 +466,7 @@ void ButtonWidget::drawWidget(bool hilite) s.frameRect(_x, _y, _w, _h, !onTop ? kShadowColor : hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor); if (!_useBitmap) - s.drawString(_font, _label, _x, _y + (_h - _fontHeight)/2 + 1, _w, + s.drawString(_font, _label, _x, _y + (_h - _lineHeight)/2 + 1, _w, !(isEnabled() && onTop) ? _textcolorlo : hilite ? _textcolorhi : _textcolor, _align); else diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 3add250ba..91fffff04 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -139,7 +139,7 @@ class Widget : public GuiObject uInt32 _flags{0}; bool _hasFocus{false}; int _fontWidth{0}; - int _fontHeight{0}; + int _lineHeight{0}; ColorId _bgcolor{kWidColor}; ColorId _bgcolorhi{kWidColor}; ColorId _bgcolorlo{kBGColorLo}; From 68fd3670b38bb9b80bb393e8f03a3b4cbd10c674 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Mon, 7 Sep 2020 20:48:36 +0200 Subject: [PATCH 039/263] updated Quadtari docs --- docs/index.html | 70 +++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/docs/index.html b/docs/index.html index 9c7513adc..3df3d2a96 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1784,7 +1784,7 @@ - Switch mouse between controller emulation modes
    (see Game Properties - Controller) + Switch mouse between controller emulation modes
    (see Controller Properties) Control + 0 Control + 0 @@ -1870,16 +1870,16 @@ EndMove cursor to end of line DeleteRemove character to right of cursor BackspaceRemove character to left of cursor - Control-aSame function as 'Home' - Control-eSame function as 'End' - Control-dSame function as 'Delete' - Control-kRemove all characters from cursor to end of line - Control-uRemove all characters from cursor to beginning of line - Control-wRemove entire word to left of cursor - Control-LeftMove cursor to beginning of word to the left - Control-RightMove cursor to beginning of word to the right - Control-cCopy entire line to clipboard (not complete) - Control-vPaste clipboard contents (not complete) + Control + aSame function as 'Home' + Control + eSame function as 'End' + Control + dSame function as 'Delete' + Control + kRemove all characters from cursor to end of line + Control + uRemove all characters from cursor to beginning of line + Control + wRemove entire word to left of cursor + Control + LeftMove cursor to beginning of word to the left + Control + RightMove cursor to beginning of word to the right + Control + cCopy entire line to clipboard (not complete) + Control + vPaste clipboard contents (not complete)
    @@ -2410,12 +2410,12 @@
    -modcombo <1|0>
    - Use modifier(Shift/Alt/Control)-x key combos. This is normally enabled, - since the 'Quit' command is tied to 'Control-q'. However, there are times + Use modifier(Shift/Alt/Control) + x key combos. This is normally enabled, + since the 'Quit' command is tied to 'Control + q'. However, there are times when you want to disable them.
    E.g. a 2-player game is using either the 'f' or 'r' keys for movement, and pressing Control (for Fire) will perform an unwanted action - associated with Control-r or Control-f default keys. + associated with 'Control + r' or 'Control + f' default keys. @@ -2769,7 +2769,7 @@
    -bs <type>
    - Set "Cart.Type" property. See the Game Properties section + Set "Cart.Type" property. See the Emulation Properties section for valid types. @@ -2810,51 +2810,51 @@
    -lc <type>
    - Set "Controller.Left" property. See the Game Properties + Set "Controller.Left" property. See the Controller Properties section for valid types.
    -lq1 <type>
    - Set "Controller.Left1" property for QuadTari. See the Game Properties + Set "Controller.Left1" property for QuadTari. See the QuadTari Properties section for valid types.
    -lq2 <type>
    - Set "Controller.Left2" property for QuadTari. See the Game Properties + Set "Controller.Left2" property for QuadTari. See the QuadTari Properties section for valid types.
    -rc <type>
    - Set "Controller.Right" property. See the Game Properties + Set "Controller.Right" property. See the Controller Properties section for valid types.
    -rq1 <type>
    - Set "Controller.Right1" property for QuadTari. See the Game Properties + Set "Controller.Right1" property for QuadTari. See the QuadTari Properties section for valid types.
    -rq2 <type>
    - Set "Controller.Right2" property for QuadTari. See the Game Properties + Set "Controller.Right2" property for QuadTari. See the QuadTari Properties section for valid types.
    -bc <type>
    Set both "Controller.Left" and "Controller.Right" properties. - See the Game Properties section for valid types. + See the Controller Properties section for valid types.
    -aq <type>
    Set "Controller.Left1", "Controller.Left2", "Controller.Right1" and "Controller.Right2" properties for QuadTari. - See the Game Properties section for valid types. + See the QuadTari Properties section for valid types. @@ -2875,12 +2875,12 @@
    -ma <Auto|XY>
    Set "Controller.MouseAxis" property. - See the Game Properties section for valid types. + See the Controller Properties section for valid types.
    -format <format>
    - Set "Display.Format" property. See the Game Properties section + Set "Display.Format" property. See the Emulation Properties section for valid formats. @@ -3487,7 +3487,7 @@ showing all files (with no restriction on file name).
  • Reload listing: Selecting this performs a reload of the - current listing. It is an alternative to pressing the Control-r + current listing. It is an alternative to pressing the 'Control + r' key combo.

  • @@ -3554,7 +3554,7 @@
  • Any other devices will be ignored.
  • The assignment ordering of Stelladaptor/2600-daptor to port can be redefined with - 'saport' (see description in Using the Command Line) and dynamically with the 'Control-1' key + 'saport' (see description in Using the Command Line) and dynamically with the 'Control + 1' key combo.

  • @@ -4067,8 +4067,9 @@ Ms Pac-Man (Stella extended codes):

    Each block in a property file consists of a set of properties for a single game. Stella supports the properties described below:

    +

    Emulation Properties

    - +

    @@ -4193,8 +4194,9 @@ Ms Pac-Man (Stella extended codes):

    Note: Items marked as '*' are deprecated, and will probably be removed in a future release.

    --> +

    Console Properties

    - +

    @@ -4218,8 +4220,9 @@ Ms Pac-Man (Stella extended codes):

    +

    Controller Properties

    - +

    @@ -4311,8 +4314,9 @@ Ms Pac-Man (Stella extended codes):

    +

    QuadTari Properties

    - +

    @@ -4327,6 +4331,7 @@ Ms Pac-Man (Stella extended codes):
    + @@ -4335,8 +4340,9 @@ Ms Pac-Man (Stella extended codes):
     Type Description
    JoystickAtari's famous black joystick that was originally included with the system.
    Paddles Standard paddle controllers, only (up to 8) fire buttons supported for QuadTari.
    DrivingLooks like a paddle, but allows 360° movement. Only one unit per connector, unlike paddles which were sold in pairs.
    AtariVoxA SpeakJet based unlimited-vocabulary speech/sound synthesizer with 32K EEPROM.
    SaveKeyA 32K EEPROM for saving high scores, etc. (the EEPROM portion of an AtariVox).

    +

    Cartridge Properties

    - +

    From eb0f526b3a426f8b462ad7a7d068c784dcd56237 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Tue, 8 Sep 2020 12:26:05 +0200 Subject: [PATCH 040/263] addressing #694, this seems to fix it (internal RAM bank segment addresses were exceeding 64K) --- src/emucore/CartEnhanced.cxx | 2 +- src/emucore/CartEnhanced.hxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index b401da819..4696fc963 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -295,7 +295,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline uInt16 CartridgeEnhanced::romAddressSegmentOffset(uInt16 address) const +inline uInt32 CartridgeEnhanced::romAddressSegmentOffset(uInt16 address) const { return myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs]; } diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 98fb8e910..33bd95993 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -275,7 +275,7 @@ class CartridgeEnhanced : public Cartridge @param address The address to get the offset for @return The calculated offset */ - uInt16 romAddressSegmentOffset(uInt16 address) const; + uInt32 romAddressSegmentOffset(uInt16 address) const; /** Get the RAM offset of the segment of the given address From 82a266da00700315d36a929d64d6f1247845c168 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 8 Sep 2020 12:23:46 -0230 Subject: [PATCH 041/263] Add QuadTari support to Xcode. --- src/debugger/gui/FlashWidget.cxx | 1 - src/macos/stella.xcodeproj/project.pbxproj | 24 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/debugger/gui/FlashWidget.cxx b/src/debugger/gui/FlashWidget.cxx index c432b16ca..1b7f06445 100644 --- a/src/debugger/gui/FlashWidget.cxx +++ b/src/debugger/gui/FlashWidget.cxx @@ -31,7 +31,6 @@ FlashWidget::FlashWidget(GuiObject* boss, const GUI::Font& font, void FlashWidget::init(GuiObject* boss, const GUI::Font& font, int x, int y, bool embedded) { - const int fontHeight = font.getFontHeight(); int xpos = x, ypos = y; myEmbedded = embedded; diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index 44732af79..cfff52861 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -228,6 +228,12 @@ DC21E5C021CA903E007D0E1A /* OSystemMACOS.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC21E5BA21CA903E007D0E1A /* OSystemMACOS.hxx */; }; DC21E5C121CA903E007D0E1A /* SerialPortMACOS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC21E5BB21CA903E007D0E1A /* SerialPortMACOS.cxx */; }; DC21E5C221CA903E007D0E1A /* SerialPortMACOS.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC21E5BC21CA903E007D0E1A /* SerialPortMACOS.hxx */; }; + DC22F12D2507D20800AB43E9 /* QuadTari.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC22F12B2507D20800AB43E9 /* QuadTari.hxx */; }; + DC22F12E2507D20800AB43E9 /* QuadTari.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC22F12C2507D20800AB43E9 /* QuadTari.cxx */; }; + DC22F1312507D22500AB43E9 /* QuadTariWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC22F12F2507D22500AB43E9 /* QuadTariWidget.hxx */; }; + DC22F1322507D22500AB43E9 /* QuadTariWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC22F1302507D22500AB43E9 /* QuadTariWidget.cxx */; }; + DC22F1352507D24E00AB43E9 /* QuadTariDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC22F1332507D24D00AB43E9 /* QuadTariDialog.hxx */; }; + DC22F1362507D24E00AB43E9 /* QuadTariDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC22F1342507D24E00AB43E9 /* QuadTariDialog.cxx */; }; DC2410E32274BDA8007A4CBF /* MinUICommandDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2410E12274BDA7007A4CBF /* MinUICommandDialog.hxx */; }; DC2410E42274BDA8007A4CBF /* MinUICommandDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC2410E22274BDA8007A4CBF /* MinUICommandDialog.cxx */; }; DC2874071F8F2278004BF21A /* TrapArray.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2874061F8F2278004BF21A /* TrapArray.hxx */; }; @@ -981,6 +987,12 @@ DC21E5BA21CA903E007D0E1A /* OSystemMACOS.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OSystemMACOS.hxx; sourceTree = SOURCE_ROOT; }; DC21E5BB21CA903E007D0E1A /* SerialPortMACOS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialPortMACOS.cxx; sourceTree = SOURCE_ROOT; }; DC21E5BC21CA903E007D0E1A /* SerialPortMACOS.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialPortMACOS.hxx; sourceTree = SOURCE_ROOT; }; + DC22F12B2507D20800AB43E9 /* QuadTari.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadTari.hxx; sourceTree = ""; }; + DC22F12C2507D20800AB43E9 /* QuadTari.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadTari.cxx; sourceTree = ""; }; + DC22F12F2507D22500AB43E9 /* QuadTariWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadTariWidget.hxx; sourceTree = ""; }; + DC22F1302507D22500AB43E9 /* QuadTariWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadTariWidget.cxx; sourceTree = ""; }; + DC22F1332507D24D00AB43E9 /* QuadTariDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadTariDialog.hxx; sourceTree = ""; }; + DC22F1342507D24E00AB43E9 /* QuadTariDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadTariDialog.cxx; sourceTree = ""; }; DC2410E12274BDA7007A4CBF /* MinUICommandDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MinUICommandDialog.hxx; sourceTree = ""; }; DC2410E22274BDA8007A4CBF /* MinUICommandDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MinUICommandDialog.cxx; sourceTree = ""; }; DC2874061F8F2278004BF21A /* TrapArray.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TrapArray.hxx; sourceTree = ""; }; @@ -1701,6 +1713,8 @@ DC9616291F817830008A2206 /* PointingDeviceWidget.hxx */, 2D20F9EE08C603EC00A73076 /* PromptWidget.cxx */, 2D20F9EF08C603EC00A73076 /* PromptWidget.hxx */, + DC22F1302507D22500AB43E9 /* QuadTariWidget.cxx */, + DC22F12F2507D22500AB43E9 /* QuadTariWidget.hxx */, 2D20F9F008C603EC00A73076 /* RamWidget.cxx */, 2D20F9F108C603EC00A73076 /* RamWidget.hxx */, DCE5CDE11BA10024005CD08A /* RiotRamWidget.cxx */, @@ -2002,6 +2016,8 @@ 2DE2DF850627AE34006BEC99 /* Props.hxx */, 2DE2DF860627AE34006BEC99 /* PropsSet.cxx */, 2DE2DF870627AE34006BEC99 /* PropsSet.hxx */, + DC22F12C2507D20800AB43E9 /* QuadTari.cxx */, + DC22F12B2507D20800AB43E9 /* QuadTari.hxx */, 2DE2DF890627AE34006BEC99 /* Random.hxx */, DC4AC6F10DC8DAEF00CD3AD2 /* SaveKey.cxx */, DC4AC6F20DC8DAEF00CD3AD2 /* SaveKey.hxx */, @@ -2105,6 +2121,8 @@ 2DDBEAC7084578BF00812C11 /* PopUpWidget.hxx */, 2DDBEAC8084578BF00812C11 /* ProgressDialog.cxx */, 2DDBEAC9084578BF00812C11 /* ProgressDialog.hxx */, + DC22F1342507D24E00AB43E9 /* QuadTariDialog.cxx */, + DC22F1332507D24D00AB43E9 /* QuadTariDialog.hxx */, DC5AAC2A1FCB24DF00C420A6 /* RadioButtonWidget.cxx */, DC5AAC2B1FCB24DF00C420A6 /* RadioButtonWidget.hxx */, DC4613650D92C03600D8DAB9 /* RomAuditDialog.cxx */, @@ -2467,6 +2485,7 @@ DCE801E3236DC25600D43EDD /* CartFC.hxx in Headers */, DC2AADB5194F390F0026C7A4 /* CartRamWidget.hxx in Headers */, 2D91740E09BA90380026E9FF /* ListWidget.hxx in Headers */, + DC22F1312507D22500AB43E9 /* QuadTariWidget.hxx in Headers */, 2D91740F09BA90380026E9FF /* Menu.hxx in Headers */, 2D91741009BA90380026E9FF /* OptionsDialog.hxx in Headers */, DCEC58591E945125002F0246 /* DelayQueueWidget.hxx in Headers */, @@ -2513,6 +2532,7 @@ 2D91745109BA90380026E9FF /* StringListWidget.hxx in Headers */, DC62E64A1960E87B007AEF05 /* SaveKeyWidget.hxx in Headers */, 2D91745209BA90380026E9FF /* CommandDialog.hxx in Headers */, + DC22F1352507D24E00AB43E9 /* QuadTariDialog.hxx in Headers */, 2D91745309BA90380026E9FF /* CommandMenu.hxx in Headers */, E0306E111F93E916003DDD52 /* JitterEmulation.hxx in Headers */, DC1E474F24D34F3B0047E61A /* WhatsNewDialog.hxx in Headers */, @@ -2584,6 +2604,7 @@ DC173F770E2CAC1E00320F94 /* ContextMenu.hxx in Headers */, DC0DF86A0F0DAAF500B0F1F3 /* GlobalPropsDialog.hxx in Headers */, E0DCD3A920A64E96000B614E /* ConvolutionBuffer.hxx in Headers */, + DC22F12D2507D20800AB43E9 /* QuadTari.hxx in Headers */, DC71EAA81FDA070D008827CB /* CartMNetworkWidget.hxx in Headers */, DC5D2C530F117CFD004D1660 /* StellaFont.hxx in Headers */, DC5D2C540F117CFD004D1660 /* StellaLargeFont.hxx in Headers */, @@ -2972,6 +2993,7 @@ DC21E5C121CA903E007D0E1A /* SerialPortMACOS.cxx in Sources */, E007231F210FBF5E002CF343 /* FpsMeter.cxx in Sources */, 2D9174FD09BA90380026E9FF /* RomListWidget.cxx in Sources */, + DC22F1362507D24E00AB43E9 /* QuadTariDialog.cxx in Sources */, DCF3A6F81DFC75E3008A8AF3 /* PaddleReader.cxx in Sources */, 2D9174FE09BA90380026E9FF /* RomWidget.cxx in Sources */, DCA82C731FEB4E780059340F /* TimeMachineDialog.cxx in Sources */, @@ -3034,6 +3056,7 @@ DCF7B0DD10A762FC007A2870 /* CartF0.cxx in Sources */, DCF7B0DF10A762FC007A2870 /* CartFA.cxx in Sources */, DCC527D210B9DA19005E1287 /* M6502.cxx in Sources */, + DC22F12E2507D20800AB43E9 /* QuadTari.cxx in Sources */, DC3EE86B1E2C0E6D00905161 /* uncompr.c in Sources */, DCC527D610B9DA19005E1287 /* System.cxx in Sources */, DC6B2BA411037FF200F199A7 /* CartDebug.cxx in Sources */, @@ -3066,6 +3089,7 @@ DCD6FC7E11C281ED005DA767 /* pngtrans.c in Sources */, DC6F394D21B897F300897AD8 /* ThreadDebugging.cxx in Sources */, DCD6FC7F11C281ED005DA767 /* pngwio.c in Sources */, + DC22F1322507D22500AB43E9 /* QuadTariWidget.cxx in Sources */, DCD6FC8011C281ED005DA767 /* pngwrite.c in Sources */, DC3EE8621E2C0E6D00905161 /* inffast.c in Sources */, DCD6FC8111C281ED005DA767 /* pngwtran.c in Sources */, From a755b7a1f5fb72e9f5a332ad3c44f114629895ae Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 8 Sep 2020 12:52:20 -0230 Subject: [PATCH 042/263] Guarantee 'inline' code actually happens. --- src/emucore/CartEnhanced.cxx | 12 ------------ src/emucore/CartEnhanced.hxx | 9 +++++++-- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 4696fc963..e24d5a5b7 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -294,18 +294,6 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) return myBankChanged = true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline uInt32 CartridgeEnhanced::romAddressSegmentOffset(uInt16 address) const -{ - return myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline uInt16 CartridgeEnhanced::ramAddressSegmentOffset(uInt16 address) const -{ - return uInt16(myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::getBank(uInt16 address) const { diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 33bd95993..fb5b35509 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -275,7 +275,9 @@ class CartridgeEnhanced : public Cartridge @param address The address to get the offset for @return The calculated offset */ - uInt32 romAddressSegmentOffset(uInt16 address) const; + uInt32 romAddressSegmentOffset(uInt16 address) const { + return myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs]; + } /** Get the RAM offset of the segment of the given address @@ -283,7 +285,10 @@ class CartridgeEnhanced : public Cartridge @param address The address to get the offset for @return The calculated offset */ - uInt16 ramAddressSegmentOffset(uInt16 address) const; + uInt16 ramAddressSegmentOffset(uInt16 address) const { + return static_cast((myCurrentSegOffset[ + ((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1); + } private: // Following constructors and assignment operators not supported From 2b83322951408abb008e961fbd407f9054c00ff6 Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Wed, 9 Sep 2020 12:25:57 +0200 Subject: [PATCH 043/263] updated docs for 'Dark' theme --- Changes.txt | 2 +- docs/graphics/options_misc_dark.png | Bin 0 -> 4280 bytes docs/index.html | 47 +++++++++++++++------------- 3 files changed, 26 insertions(+), 23 deletions(-) create mode 100644 docs/graphics/options_misc_dark.png diff --git a/Changes.txt b/Changes.txt index 0149e6966..b700ac28a 100644 --- a/Changes.txt +++ b/Changes.txt @@ -16,7 +16,7 @@ * Added adjustable autofire. - * Added 'Dark' UI theme. (TODO: DOC) + * Added 'Dark' UI theme. * Extended global hotkeys for debug options. diff --git a/docs/graphics/options_misc_dark.png b/docs/graphics/options_misc_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..79fad1166f0446f2b04727bdaabb2f9cdf92f990 GIT binary patch literal 4280 zcma)=c|26@-^aNNQ7D=yN+H`wTF92U$riH2oS6w@H`eU?GG&qsLJV?eiL7&Cj3pB$ z6fuM_*6dsM$RzvY?tVSb^ZPx|eZOA6KhEo1*XLZ<>vf&?_j|7I=Q>eF2HKn)XE>Oc zm^g3iXxwFD`VC-WVzxhg=s+2YttKDbn7!|6t1}h13(g&M4rA2rs4+2>#vR?UW;y5! z80nj8+S%Eqrly`hfBryFQBjeQkf^JxBauiU~nnj?Ea(@&*N*g;fYy%V<%ZZ1ZFS=X53%bwab$CLOTrDjzsfZ+%5O5 zSkU&D)=QEIbx7cemaZ-I*j=!Qn7eGxqK6v43sfaRWb7lLO4%*B-&1~Lq@vBhg zilJx{yp%DSD8@a{)4d&Cs{1yM?pe@kGkHpK4(er1%^Z2Yq)ERPy|6@Y1~TEvAW;2-Y}dAaWS+qM>Ln zmVvDE=wxU%#(H|el4HpV%)@U@_MXC>xexct==CN7(1Ta;^4wzjd{_#ehn2!WZ+joKUS33Mod7>wHGjsL8w z1gGG^a`SP}QOJqXK%hZ_{aa6MZ7=+RIzQG;faY{jIL0A&b0gICtjcEk`+_JOXqbqvu%(qnf+jUzZ?f4%F$x!orDMU&C=w5-l&8!za zUAH{CCk5}q4WwvWimPus@&OyYOW2w{z3s22VA%F9fj};rp>Pq6IE(#nMw2E+X3aC8 zrE5a|=nk`$vShU%+-_XTNJ=h1dxYkbEEqyexPWaeYM*qG;Hu$)yu@lPFurhk=Cf zQYY|W@ijDlbXi;-NePlF=`&MRPM|w)e9~Ypx?l{0H!Sv$G$q- zPtSL>BT?*B{c+iGdfE$b8<(3TA~}ZQ5UT zd*RMjeNXvo;g9z>D@u8mvMj4!r`y{{RN`KyS3eq5y;{1@x@6V83%5Y7M3Bdzn0?Rff))%Am~qKDPfY51w$%4rWtsQJ8*tHO%7%`~rD z9mg8?Dd#18OW@$@;I*7`V)``&=>4x}>$jiX+rj1DtN!Vgu{*wBbDeln*KgkDoHdJJ znA9!v6jkL-@N#lAm!<*G2F1tS%ru24A|Fg&Gg95%TGFZc#3l+Rnf2(fQk|XVY3C+j!?awnv_zq5VLM;Uh5X-y*^o7$I3og$N z)a1zX&~ z^EN5?xt0XfpjAkPnt|=7I9tbWDBuB>)W`MMUDERq(S5W(!i$gwb5EOG${H1_;fr-Y zvN|hvC_6Y_7zpC4$S%NNbn^)Z9IACp;h_Y4x@q`0#a&^NKC)qmBJhk=G z7gt{<@sDBng|HPzpv$pwW*ff32Db#HZG(P}>p3l^^xFk7|Nd<>fE{qCbEbdWF^~g# zh$SE52X6z8!xvDyNnqIR^OKfE@>R<&LN6YJYgGeP4tTiW6PF#wwIyWK!;C$mkR0_j zXICd{K8>JL27?ZMVZC#?_$mKa8TseqKRv&pG0cGV6txP|Urxo}at>8AShC{Jn!j|7 zlfoH1rFD(dh^1VEqATvy)gL_A#)>(-i{98TFl4Aav67|H*c(X0IRi3Xd;df;(%LsX zU(i0nMO2IS`*c%OF?SzPY3T~ccyohM70v4$C9q#`l{m*Felwm|{Klv<*D>!PJT z@KPXb&y3IrC(d76P+dQw@aej<5qN^-?che-F;R6J5F$RVLLQ z3ZbI{%QzxXq_w@HGHxDxfO!q^L2k8|fIw1SN_rL9T=N(uDN@MG7SIrx#?#8oOm#vD zHeLF3#FgV6?Vvod#Kt_mn9nQHE9ne==5+h@;?;=g#6Ay>-e;h`O8VMiM1tz%*uln8 zZpiwNndhqktoZ03q}X(|Vs=P=XO_Sd`_UdBA-XBw-C9GfuN^TzGGP)|m;A%D&PEbe zqKDn~vYLJH@aGQtW~4#Sy{vECX;X(!ma$Zindz3X#P)yCWb&T*gmP2Hl14`}f=XZO zzQY+N-jv*g@HNNP>W9)X6>~fFX}q%4Z=b=%_HVgs)LU&BYXa}IR7HrHBAINdFrpiO&%+Iy)GaWGHkHXi#Vv@!FyI! zrFttfV+{kzJ06>{h9{b9m&Qb<=bOK?&6ZCos&0SJA~#eFn+$~gbIxd6`SxJas0VJT z&ACSTP$~}+zKEI^3g{f&%Qs#f3*KbQNBfWVj5p(OU;|!R$u8vcA@bE4?-1h^p_q~j z=M31T(GN1k78~PT-b+HxLc*H*-&Y@op8M%p`SkL9`+4een8L+Qe?jfc!~XjA60qz+ z)AWEVdSu8#8IIO8tO1jbc#=ce67m1MBHVulm`hbr=yP^CEx3TrJA3F1Istj@21o@moPT=!9!Tc(XO~e^3~cX z6ZRAALOsdgLE+1=K-x~Z=4m3YFpwAHto?F*l7=PqhQ_k@>TNc%cP`f#$r1x9MIElB zO$@)fLca>0+Ti8@YR9GZNNf2YYBO_F8+G!C8q(-+`r2N-9WJknOSPG%gSBlda%Fq3 z=@GIy6D}X{uGhQcI&2c0yA1~}DP1QzoXw#BA7}pWe)bo$zbE;hs61eU(ZaV+2H|G5 z9+Odra_xW+1Z|+W!x6ffp9+d}9=o?&)Yn%{F^_Lq9CuB~?QwJqa+96~E z#Vquj$8wqZJ z4R%QiDpWXnl^?&Ef)a268;iVDf3XoeC7Ncl$g5I5PpoZ8nOGka2Nvi7xSD^2>B z=Pk3*!!pI`cbpNZo<6^uEn8+J-H-Ss{IEyT+fXe^dvXJImcFc3$=g%51m@u`*GapIF&Vc?FAAlz^(R*+h1tl7d36i#^Ut1D~ObFe#nSCSY z%gzK|T#_c9%-m2!!Y`~NV>zufk&O@iHW_p=E?YhMARd76Qdka<#AERTainLSpEWy| zt{&M&A>k%{tpq(8k-8jEy;0syF3c-yRy)>DK9wv8fFCOa6jDYxH;ie`5p#=3tZ2=$q z#7X6RLpxmTMs^Ep

    In addition to the built in ROM launcher, Stella can also be used from the - commandline (assuming your operating system has a commandline).

    + command line (assuming your operating system has a command line).

    -

    To run Stella from the commandline, use the following format:

    +

    To run Stella from the command line, use the following format:

       stella [options ...] ROM_FILENAME
    @@ -2360,7 +2360,7 @@
    - + @@ -2576,7 +2576,7 @@ - + @@ -3042,7 +3042,7 @@
    -logtoconsole <1|0>
    Indicate that logged output should be printed to the console/commandline as it's being collected. An internal log will still be kept, and the amount of logging is still controlled by 'loglevel'.Indicate that logged output should be printed to the console/command line as it's being collected. An internal log will still be kept, and the amount of logging is still controlled by 'loglevel'.
    -uipalette <standard|classic|light>
    -uipalette <standard|classic|light|dark>
    Use the specified palette for UI elements.
         - + @@ -3066,7 +3066,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    RendererUse specified rendering mode-video
    InterpolationEnable interpolation of the TIA image-tia.inter
    ZoomZoom level of the TIA image-tia.zoom
         - + @@ -3088,7 +3088,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    PalettePalette used for emulation mode-palette
    NTSC phaseAdjust phase shift for 'Custom' NTSC palette-pal.phase_ntsc
    PAL phaseAdjust phase shift for 'Custom' PAL palette-pal.phase_pal
         - + @@ -3114,7 +3114,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    TV modeDisable TV effects, or select TV preset-tv.filter
    Adjustable slidersSet specific attribute in 'Custom' TV mode-tv.sharpness, -tv.resolution, etc.
    Phosphor for all ROMsEnable phosphor mode for all ROMs-tv.phosphor
         - + @@ -3159,7 +3159,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Enable audioSelf-explanatory-audio.enabled
    VolumeSelf-explanatory-audio.volume
    DeviceUse the specified audio device.-audio.device
         - + @@ -3206,7 +3206,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Emulation speedEmulation speed-speed
    VSyncEnable vertical synced updates-vsync
    TurboEnable 'Turbo' mode for maximum emulation speed. This overwrites 'Emulation speed' setting and disables 'VSync'.-turbo
         - + @@ -3225,6 +3225,9 @@ + + +
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    ThemeTheme to use for UI elements (see examples)-uipalette
    Dialogs fontThe font used in the dialogs-dialogfont
    HiDPI modeScale the UI by a factor of two when enabled-hidpi
        

    @@ -3244,7 +3247,7 @@
         - + @@ -3357,7 +3360,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Save pathSpecifies where to save snapshots-snapsavedir
    Continuous snapshot intervalInterval (in seconds) between snapshots-ssinterval
         - + @@ -3382,7 +3385,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Joystick deadzone sizeDeadzone area for axes on joysticks/gamepads-joydeadzone
    (Analog paddle) SensitivitySensitivity of an analog paddle-psense
    Analog paddle) Dejitter averagingStrength of paddle input averaging, suppresses mouse jitter-dejitter.base
         - + @@ -3569,7 +3572,7 @@ which allow your particular operating system to 'see' the device (configuring this is outside the scope of this document). Once your operating system properly detects the AtariVox, you will need to tell Stella which serial - port it is connected to. This is done by using the '-avoxport' commandline + port it is connected to. This is done by using the '-avoxport' command line argument, or by setting it in the UI under the 'Devices & Ports' tab in Advanced Configuration - Input Devices.

    @@ -3631,7 +3634,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Use mouse as ...Allow the mouse to emulate various controllers-usemouse
    (Sensitivity) PaddleSensitivity used when emulating a paddle using a mouse-msense
    (Sensitivity) TrackballSensitivity used when emulating a trackball device using a mouse-tsense
         - + @@ -3668,7 +3671,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Player/Developer settingsSelects the active settings set-dev.settings
    Console info overlayOverlay console info on the TIA image during emulation.-plr.stats
    -dev.stats
    Detected settings infoDisplay detected settings when a ROM is loaded.-plr.detectedinfo
    -dev.detectedinfo
         - + @@ -3698,7 +3701,7 @@
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Chip typeType of emulated TIA chip. Allows testing for TIA versions which exhibit timing problems in certain games. The 'Custom' option allows testing for glitch combinations.-dev.tia.type
         - + @@ -3726,7 +3729,7 @@ - - - + + +
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Jitter/roll effectEmulate screen roll with inconsistent scanline count-plr.tv.jitter
    -dev.tv.jitter
    (Jitter/roll) RecoveryDetermines recovery time for screen rolling-plr.tv.jitter_recovery
    -dev.tv.jitter_recovery
    PAL color-lossUse PAL color-loss effect-plr.colorloss
    -dev.colorloss
    - + - - + + +
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Time Machine @@ -3780,7 +3783,7 @@      - + @@ -3803,7 +3806,7 @@ Developer Commands for more information.
  • Viewing TIA/console information overlaid on the TIA image. This option - can be enabled from the commandline or using the Alt-L key combo, + can be enabled from the command line or using the Alt-L key combo, and is extremely useful for viewing the current scanline count and associated frames per second, bankswitch and display formats, etc. The following shows an example of this information: @@ -3995,7 +3998,7 @@ Ms Pac-Man (Stella extended codes):

    Stella maintains a log of its operations when the program first starts up, and while it is running. In older releases, this information was only viewable from the - commandline. However, the current release allows + command line. However, the current release allows you to see this information from within the UI. This can be selected from the main Options menu, where it is labelled "System Logs". Clicking on the button will show a window similar to the following:

    @@ -4016,7 +4019,7 @@ Ms Pac-Man (Stella extended codes):

    The log levels are self-explanatory (None, Basic, Verbose). The "Print to console" option emulates the behaviour of older versions of Stella, whereby the logged output - is also shown on the commandline from which Stella was launched (if it was launched + is also shown on the command line from which Stella was launched (if it was launched in that fashion). Finally, the current contents of the system log can be saved to your home directory by clicking the "Save log to disk" button.


    From 40362ebc6cf6000db41e5b9be493610ef4c66ed6 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 12 Sep 2020 16:44:55 -0230 Subject: [PATCH 044/263] Added code to detect valid serial ports. Next we have to tie this into the UI, so AtariVox port can be more easily detected. --- src/emucore/SerialPort.hxx | 7 ++++++ src/macos/SerialPortMACOS.cxx | 24 ++++++++++++++++++++ src/macos/SerialPortMACOS.hxx | 20 +++++++++++------ src/unix/SerialPortUNIX.cxx | 26 +++++++++++++++++++++ src/unix/SerialPortUNIX.hxx | 9 +++++++- src/windows/SerialPortWINDOWS.cxx | 36 ++++++++++++++++++++++++++++++ src/windows/SerialPortWINDOWS.hxx | 7 ++++++ src/windows/Stella.vcxproj | 1 - src/windows/Stella.vcxproj.filters | 3 --- 9 files changed, 121 insertions(+), 12 deletions(-) diff --git a/src/emucore/SerialPort.hxx b/src/emucore/SerialPort.hxx index 5525a51c7..8736d14cd 100644 --- a/src/emucore/SerialPort.hxx +++ b/src/emucore/SerialPort.hxx @@ -65,6 +65,13 @@ class SerialPort */ virtual bool isCTS() { return true; } + /** + Get all valid serial ports detected on this system. + + @return The (possibly empty) list of detected serial ports + */ + virtual StringList portNames() { return StringList{}; } + private: // Following constructors and assignment operators not supported SerialPort(const SerialPort&) = delete; diff --git a/src/macos/SerialPortMACOS.cxx b/src/macos/SerialPortMACOS.cxx index 3a4d2530b..9006c2c74 100644 --- a/src/macos/SerialPortMACOS.cxx +++ b/src/macos/SerialPortMACOS.cxx @@ -25,6 +25,7 @@ #include #include +#include "FSNode.hxx" #include "SerialPortMACOS.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -92,3 +93,26 @@ bool SerialPortMACOS::isCTS() } return false; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +StringList SerialPortMACOS::portNames() +{ + StringList ports; + + // Get all possible devices in the '/dev' directory + FilesystemNode::NameFilter filter = [](const FilesystemNode& node) { + return BSPF::startsWithIgnoreCase(node.getPath(), "/dev/tty.usb"); + }; + FSList portList; + portList.reserve(16); + + FilesystemNode dev("/dev/"); + dev.getChildren(portList, FilesystemNode::ListMode::All, filter, false); + + // Add only those that can be opened + for(const auto& port: portList) + if(openPort(port.getPath())) + ports.emplace_back(port.getPath()); + + return ports; +} diff --git a/src/macos/SerialPortMACOS.hxx b/src/macos/SerialPortMACOS.hxx index 3fd9595d3..ea55ddc3d 100644 --- a/src/macos/SerialPortMACOS.hxx +++ b/src/macos/SerialPortMACOS.hxx @@ -21,8 +21,7 @@ #include "SerialPort.hxx" /** - Implement reading and writing from a serial port under macOS. For now, - reading isn't actually supported at all. + Implement reading and writing from a serial port under macOS. @author Stephen Anthony & D. Spice */ @@ -56,12 +55,19 @@ class SerialPortMACOS : public SerialPort */ bool writeByte(uInt8 data) override; - /** - Test for 'Clear To Send' enabled. + /** + Test for 'Clear To Send' enabled. - @return True if CTS signal enabled, else false - */ - bool isCTS() override; + @return True if CTS signal enabled, else false + */ + bool isCTS() override; + + /** + Get all valid serial ports detected on this system. + + @return The (possibly empty) list of detected serial ports + */ + StringList portNames() override; private: // File descriptor for serial connection diff --git a/src/unix/SerialPortUNIX.cxx b/src/unix/SerialPortUNIX.cxx index 7c39b3fb9..b155d5240 100644 --- a/src/unix/SerialPortUNIX.cxx +++ b/src/unix/SerialPortUNIX.cxx @@ -24,6 +24,7 @@ #include #include +#include "FSNode.hxx" #include "SerialPortUNIX.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -95,3 +96,28 @@ bool SerialPortUNIX::isCTS() } return false; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +StringList SerialPortUNIX::portNames() +{ + StringList ports; + + // Get all possible devices in the '/dev' directory + FilesystemNode::NameFilter filter = [](const FilesystemNode& node) { + return BSPF::startsWithIgnoreCase(node.getPath(), "/dev/ttyACM") || + BSPF::startsWithIgnoreCase(node.getPath(), "/dev/ttyS") || + BSPF::startsWithIgnoreCase(node.getPath(), "/dev/ttyUSB"); + }; + FSList portList; + portList.reserve(16); + + FilesystemNode dev("/dev/"); + dev.getChildren(portList, FilesystemNode::ListMode::All, filter, false); + + // Add only those that can be opened + for(const auto& port: portList) + if(openPort(port.getPath())) + ports.emplace_back(port.getPath()); + + return ports; +} diff --git a/src/unix/SerialPortUNIX.hxx b/src/unix/SerialPortUNIX.hxx index dbf5f3299..640ee9b85 100644 --- a/src/unix/SerialPortUNIX.hxx +++ b/src/unix/SerialPortUNIX.hxx @@ -22,7 +22,7 @@ /** Implement reading and writing from a serial port under UNIX. For now, - it seems to be Linux-only, and reading isn't actually supported at all. + it seems to be Linux-only. @author Stephen Anthony */ @@ -63,6 +63,13 @@ class SerialPortUNIX : public SerialPort */ bool isCTS() override; + /** + Get all valid serial ports detected on this system. + + @return The (possibly empty) list of detected serial ports + */ + StringList portNames() override; + private: // File descriptor for serial connection int myHandle{0}; diff --git a/src/windows/SerialPortWINDOWS.cxx b/src/windows/SerialPortWINDOWS.cxx index 2772821d6..8ec755091 100644 --- a/src/windows/SerialPortWINDOWS.cxx +++ b/src/windows/SerialPortWINDOWS.cxx @@ -112,3 +112,39 @@ bool SerialPortWINDOWS::isCTS() } return false; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +StringList SerialPortWINDOWS::portNames() +{ + StringList ports; + + HKEY hKey = NULL; + LSTATUS result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &hKey); + if (result == ERROR_SUCCESS) + { + TCHAR deviceName[2048], friendlyName[32]; + DWORD numValues = 0; + + result = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, + &numValues, NULL, NULL, NULL, NULL); + if (result == ERROR_SUCCESS) + { + DWORD type = 0; + DWORD deviceNameLen = 2047; + DWORD friendlyNameLen = 31; + + for (DWORD i = 0; i < numValues; ++i) + { + result = RegEnumValue(hKey, i, deviceName, &deviceNameLen, + NULL, &type, (LPBYTE)friendlyName, &friendlyNameLen); + + if (result == ERROR_SUCCESS && type == REG_SZ) + ports.emplace_back(friendlyName); + } + } + } + RegCloseKey(hKey); + + return ports; +} diff --git a/src/windows/SerialPortWINDOWS.hxx b/src/windows/SerialPortWINDOWS.hxx index 9a7aec2e6..8c2215c51 100644 --- a/src/windows/SerialPortWINDOWS.hxx +++ b/src/windows/SerialPortWINDOWS.hxx @@ -63,6 +63,13 @@ class SerialPortWINDOWS : public SerialPort */ bool isCTS() override; + /** + Get all valid serial ports detected on this system. + + @return The (possibly empty) list of detected serial ports + */ + StringList portNames() override; + private: // Handle to serial port HANDLE myHandle{0}; diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index f37614cda..843abc45d 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -1742,7 +1742,6 @@ - diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 217dfaecf..35b428e4f 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1829,9 +1829,6 @@ Header Files - - Header Files\emucore - Header Files\emucore From 6d94f64b24fb8c919dfa7ccdf0b8b4abf6239006 Mon Sep 17 00:00:00 2001 From: cd-w Date: Sun, 13 Sep 2020 13:16:34 -0700 Subject: [PATCH 045/263] Preliminary support for CDFJ+ bankswitching --- src/debugger/gui/CartCDFInfoWidget.cxx | 31 +++- src/debugger/gui/CartCDFWidget.cxx | 6 +- src/emucore/CartBUS.cxx | 8 +- src/emucore/CartCDF.cxx | 206 ++++++++++++++++--------- src/emucore/CartCDF.hxx | 27 ++-- src/emucore/CartDPCPlus.cxx | 3 + src/emucore/CartDetector.cxx | 12 +- src/emucore/Thumbulator.cxx | 33 ++-- src/emucore/Thumbulator.hxx | 16 +- 9 files changed, 219 insertions(+), 123 deletions(-) diff --git a/src/debugger/gui/CartCDFInfoWidget.cxx b/src/debugger/gui/CartCDFInfoWidget.cxx index b56c61ca1..ab183af33 100644 --- a/src/debugger/gui/CartCDFInfoWidget.cxx +++ b/src/debugger/gui/CartCDFInfoWidget.cxx @@ -23,16 +23,28 @@ CartridgeCDFInfoWidget::CartridgeCDFInfoWidget( int x, int y, int w, int h, CartridgeCDF& cart) : CartDebugWidget(boss, lfont, nfont, x, y, w, h) { - uInt16 size = 8 * 4096; - + uInt32 size; ostringstream info; - info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n" - << "32K ROM, seven 4K banks are accessible to 2600\n" - << "8K CDF RAM\n" - << "CDF registers accessible @ $FFF0 - $FFF3\n" - << "Banks accessible at hotspots $FFF5 to $FFFB\n" - << "Startup bank = " << cart.startBank() << "\n"; + if (cart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJplus) { + size = 512 * 1024; + info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n" + << "512K ROM (seven 4K banks are accessible to 2600)\n" + << "32K RAM\n" + << "Functions accessible @ $FFF0 - $FFF3\n" + << "Banks accessible @ $FFF4 to $FFFB\n" + << "Startup bank = " << cart.startBank() << "\n"; + + } else { + size = 8 * 4096; + info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n" + << "32K ROM (seven 4K banks are accessible to 2600)\n" + << "8K RAM\n" + << "Functions accessible @ $FFF0 - $FFF3\n" + << "Banks accessible @ $FFF4 to $FFFB\n" + << "Startup bank = " << cart.startBank() << "\n"; + } + #if 0 // Eventually, we should query this from the debugger/disassembler for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < 7; ++i, offset += 0x1000) @@ -61,6 +73,9 @@ string CartridgeCDFInfoWidget::describeCDFVersion(CartridgeCDF::CDFSubtype subty case CartridgeCDF::CDFSubtype::CDFJ: return "CDFJ"; + case CartridgeCDF::CDFSubtype::CDFJplus: + return "CDFJ+"; + default: throw runtime_error("unreachable"); } diff --git a/src/debugger/gui/CartCDFWidget.cxx b/src/debugger/gui/CartCDFWidget.cxx index 8c4fdf2fc..3488dd9fe 100644 --- a/src/debugger/gui/CartCDFWidget.cxx +++ b/src/debugger/gui/CartCDFWidget.cxx @@ -467,6 +467,9 @@ string CartridgeCDFWidget::describeCDFVersion(CartridgeCDF::CDFSubtype subtype) case CartridgeCDF::CDFSubtype::CDFJ: return "CDFJ"; + case CartridgeCDF::CDFSubtype::CDFJplus: + return "CDFJ+"; + default: throw runtime_error("unreachable"); } @@ -475,5 +478,6 @@ string CartridgeCDFWidget::describeCDFVersion(CartridgeCDF::CDFSubtype subtype) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeCDFWidget::isCDFJ() const { - return myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ; + return (myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ || + myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJplus); // FIXME: Separate settings for CDFJ+ } diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index 46d220bbf..edd56d72c 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -68,8 +68,12 @@ CartridgeBUS::CartridgeBUS(const ByteBuffer& image, size_t size, reinterpret_cast(myImage.get()), reinterpret_cast(myRAM.data()), static_cast(32_KB), - devSettings ? settings.getBool("dev.thumb.trapfatal") : false, Thumbulator::ConfigureFor::BUS, this - ); + 0x00000800, + 0x00000808, + 0x40001FDC, + devSettings ? settings.getBool("dev.thumb.trapfatal") : false, + Thumbulator::ConfigureFor::BUS, + this); setInitialState(); } diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index e09480464..867b66a7b 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -29,14 +29,17 @@ #include "TIA.hxx" #include "exception/FatalEmulationError.hxx" -#define DSRAM 0x0800 - #define COMMSTREAM 0x20 #define JUMPSTREAM_BASE 0x21 #define FAST_FETCH_ON ((myMode & 0x0F) == 0) #define DIGITAL_AUDIO_ON ((myMode & 0xF0) == 0) +#define getUInt32(_array, _address) ((_array)[(_address) + 0] + \ + ((_array)[(_address) + 1] << 8) + \ + ((_array)[(_address) + 2] << 16) + \ + ((_array)[(_address) + 3] << 24)) + namespace { Thumbulator::ConfigureFor thumulatorConfiguration(CartridgeCDF::CDFSubtype subtype) { @@ -50,6 +53,9 @@ namespace { case CartridgeCDF::CDFSubtype::CDFJ: return Thumbulator::ConfigureFor::CDFJ; + case CartridgeCDF::CDFSubtype::CDFJplus: + return Thumbulator::ConfigureFor::CDFJplus; + default: throw runtime_error("unreachable"); } @@ -60,34 +66,53 @@ namespace { CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) : Cartridge(settings, md5), - myImage(make_unique(32_KB)) + myImage(make_unique(512_KB)) { // Copy the ROM image into my buffer - std::fill_n(myImage.get(), 32_KB, 0); - std::copy_n(image.get(), std::min(32_KB, size), myImage.get()); + std::fill_n(myImage.get(), 512_KB, 0); + std::copy_n(image.get(), std::min(512_KB, size), myImage.get()); - // even though the ROM is 32K, only 28K is accessible to the 6507 - createRomAccessArrays(28_KB); + // Detect cart version + setupVersion(); - // Pointer to the program ROM (28K @ 0 byte offset) - // which starts after the 2K CDF Driver and 2K C Code - myProgramImage = myImage.get() + 4_KB; + // CDFJ+ has different settings + bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); + + // The lowest 2K is not accessible to the debugger + createRomAccessArrays(cdfjPlus ? 510_KB : 28_KB); + + // Pointer to the program ROM + // which starts after the 2K driver (and 2K C Code for CDF) + myProgramImage = myImage.get() + (cdfjPlus ? 2_KB : 4_KB); // Pointer to CDF driver in RAM myDriverImage = myRAM.data(); - // Pointer to the display RAM - myDisplayImage = myRAM.data() + DSRAM; + // Pointer to the display RAM (starts after 2K driver) + myDisplayImage = myRAM.data() + 2_KB; - setupVersion(); + // C addresses + uInt32 cBase, cStart, cStack; + if (cdfjPlus) { + cBase = getUInt32(myImage.get(), 0x17F8) & 0xFFFFFFFE; // C Base Address + cStart = cBase; // C Start Address + cStack = getUInt32(myImage.get(), 0x17F4); // C Stack + } else { + cBase = 0x800; // C Base Address + cStart = 0x808; // C Start Address (skip ARM header) + cStack = 0x40001FDC; // C Stack + } // Create Thumbulator ARM emulator bool devSettings = settings.getBool("dev.settings"); myThumbEmulator = make_unique( reinterpret_cast(myImage.get()), reinterpret_cast(myRAM.data()), - static_cast(32_KB), - devSettings ? settings.getBool("dev.thumb.trapfatal") : false, thumulatorConfiguration(myCDFSubtype), this); + static_cast(512_KB), + cBase, cStart, cStack, + devSettings ? settings.getBool("dev.thumb.trapfatal") : false, + thumulatorConfiguration(myCDFSubtype), + this); setInitialState(); } @@ -97,8 +122,8 @@ void CartridgeCDF::reset() { initializeRAM(myRAM.data()+2_KB, myRAM.size()-2_KB); - // CDF always starts in bank 6 - initializeStartBank(6); + // CDF always starts in bank 6, CDFJ+ in bank 0 + initializeStartBank((myCDFSubtype == CDFSubtype::CDFJplus) ? 0 : 6); myAudioCycles = myARMCycles = 0; myFractionalClocks = 0.0; @@ -123,7 +148,6 @@ void CartridgeCDF::setInitialState() myBankOffset = myLDAimmediateOperandAddress = myJMPoperandAddress = 0; myFastJumpActive = myFastJumpStream = 0; - } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -194,8 +218,9 @@ inline void CartridgeCDF::callFunction(uInt8 value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeCDF::peek(uInt16 address) { - address &= 0x0FFF; + bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); + address &= 0x0FFF; uInt8 peekvalue = myProgramImage[myBankOffset + address]; // In debugger/bank-locked mode, we ignore all hotspots and in general @@ -214,8 +239,14 @@ uInt8 CartridgeCDF::peek(uInt16 address) ++myJMPoperandAddress; pointer = getDatastreamPointer(myFastJumpStream); - value = myDisplayImage[ pointer >> 20 ]; - pointer += 0x100000; // always increment by 1 + if (cdfjPlus) { + value = myDisplayImage[ pointer >> 16 ]; + pointer += 0x00010000; // always increment by 1 + } else { + value = myDisplayImage[ pointer >> 20 ]; + pointer += 0x00100000; // always increment by 1 + } + setDatastreamPointer(myFastJumpStream, pointer); return value; @@ -254,9 +285,9 @@ uInt8 CartridgeCDF::peek(uInt16 address) uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> 21); // get sample value from ROM or RAM - if (sampleaddress < 0x8000) + if (sampleaddress < 0x00080000) peekvalue = myImage[sampleaddress]; - else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40002000) // check for RAM + else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40008000) // check for RAM peekvalue = myRAM[sampleaddress - 0x40000000]; else peekvalue = 0; @@ -284,39 +315,36 @@ uInt8 CartridgeCDF::peek(uInt16 address) // Switch banks if necessary switch(address) { - case 0xFF5: - // Set the current bank to the first 4k bank - bank(0); + case 0x0FF4: + bank(cdfjPlus ? 0 : 6); + break; + + case 0x0FF5: + bank(cdfjPlus ? 1 : 0); break; case 0x0FF6: - // Set the current bank to the second 4k bank - bank(1); + bank(cdfjPlus ? 2 : 1); break; case 0x0FF7: - // Set the current bank to the third 4k bank - bank(2); + bank(cdfjPlus ? 3 : 2); break; case 0x0FF8: - // Set the current bank to the fourth 4k bank - bank(3); + bank(cdfjPlus ? 4 : 3); break; case 0x0FF9: - // Set the current bank to the fifth 4k bank - bank(4); + bank(cdfjPlus ? 5 : 4); break; case 0x0FFA: - // Set the current bank to the sixth 4k bank - bank(5); + bank(cdfjPlus ? 6 : 5); break; case 0x0FFB: - // Set the current bank to the last 4k bank - bank(6); + bank(cdfjPlus ? 0 : 6); break; default: @@ -333,67 +361,74 @@ uInt8 CartridgeCDF::peek(uInt16 address) bool CartridgeCDF::poke(uInt16 address, uInt8 value) { uInt32 pointer; + bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); address &= 0x0FFF; - switch(address) { - case 0xFF0: // DSWRITE + case 0x0FF0: // DSWRITE pointer = getDatastreamPointer(COMMSTREAM); - myDisplayImage[ pointer >> 20 ] = value; - pointer += 0x100000; // always increment by 1 when writing + if (cdfjPlus) { + myDisplayImage[ pointer >> 16 ] = value; + pointer += 0x00010000; // always increment by 1 when writing + } else { + myDisplayImage[ pointer >> 20 ] = value; + pointer += 0x00100000; // always increment by 1 when writing + } setDatastreamPointer(COMMSTREAM, pointer); break; - case 0xFF1: // DSPTR + case 0x0FF1: // DSPTR pointer = getDatastreamPointer(COMMSTREAM); - pointer <<=8; - pointer &= 0xf0000000; - pointer |= (value << 20); + pointer <<= 8; + if (cdfjPlus) { + pointer &= 0xff000000; + pointer |= (value << 16); + } else { + pointer &= 0xf0000000; + pointer |= (value << 20); + } setDatastreamPointer(COMMSTREAM, pointer); break; - case 0xFF2: // SETMODE + case 0x0FF2: // SETMODE myMode = value; break; - case 0xFF3: // CALLFN + case 0x0FF3: // CALLFN callFunction(value); break; - case 0xFF5: - // Set the current bank to the first 4k bank - bank(0); + case 0x00FF4: + bank(cdfjPlus ? 0 : 6); + break; + + case 0x0FF5: + bank(cdfjPlus ? 1 : 0); break; case 0x0FF6: - // Set the current bank to the second 4k bank - bank(1); + bank(cdfjPlus ? 2 : 1); break; case 0x0FF7: - // Set the current bank to the third 4k bank - bank(2); + bank(cdfjPlus ? 3 : 2); break; case 0x0FF8: - // Set the current bank to the fourth 4k bank - bank(3); + bank(cdfjPlus ? 4 : 3); break; case 0x0FF9: - // Set the current bank to the fifth 4k bank - bank(4); + bank(cdfjPlus ? 5 : 4); break; case 0x0FFA: - // Set the current bank to the sixth 4k bank - bank(5); + bank(cdfjPlus ? 6 : 5); break; case 0x0FFB: - // Set the current bank to the last 4k bank - bank(6); + bank(cdfjPlus ? 0 : 6); break; default: @@ -419,7 +454,7 @@ bool CartridgeCDF::bank(uInt16 bank, uInt16) { access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + 28_KB]; + access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + 28_KB]; // TODO: Change for CDFJ+??? mySystem->setPageAccess(addr, access); } return myBankChanged = true; @@ -455,7 +490,7 @@ bool CartridgeCDF::patch(uInt16 address, uInt8 value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const ByteBuffer& CartridgeCDF::getImage(size_t& size) const { - size = 32_KB; + size = 512_KB; return myImage; } @@ -617,11 +652,13 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const (myRAM[address + 2] << 16) + (myRAM[address + 3] << 24); // high byte - result -= (0x40000000 + DSRAM); - - if (result >= 4096) - result &= 4095; + result -= (0x40000000 + 2_KB); + if (myCDFSubtype != CDFSubtype::CDFJplus) { + if (result >= 4096) { + result &= 4095; + } + } return result; } @@ -659,8 +696,17 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index) uInt32 pointer = getDatastreamPointer(index); uInt16 increment = getDatastreamIncrement(index); - uInt8 value = myDisplayImage[ pointer >> 20 ]; - pointer += (increment << 12); + + uInt8 value; + bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); + if (cdfjPlus) { + value = myDisplayImage[ pointer >> 16 ]; + pointer += (increment << 8); + } else { + value = myDisplayImage[ pointer >> 20 ]; + pointer += (increment << 12); + } + setDatastreamPointer(index, pointer); return value; } @@ -668,8 +714,21 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCDF::setupVersion() { - uInt8 subversion = 0; + // CDFJ+ detection + if (getUInt32(myImage.get(), 0x174) == 0x53554c50 && // Plus + getUInt32(myImage.get(), 0x178) == 0x4a464443 && // CDFJ + getUInt32(myImage.get(), 0x17C) == 0x00000001) { // V1 + myCDFSubtype = CDFSubtype::CDFJplus; + myAmplitudeStream = 0x23; + myFastjumpStreamIndexMask = 0xfe; + myDatastreamBase = 0x0098; + myDatastreamIncrementBase = 0x0124; + myWaveformBase = 0x01b0; + return; + } + + uInt8 subversion = 0; for(uInt32 i = 0; i < 2048; i += 4) { // CDF signature occurs 3 times in a row, i+3 (+7 or +11) is version @@ -683,6 +742,7 @@ void CartridgeCDF::setupVersion() } switch (subversion) { + case 0x4a: myCDFSubtype = CDFSubtype::CDFJ; @@ -727,6 +787,8 @@ string CartridgeCDF::name() const return "CartridgeCDF1"; case CDFSubtype::CDFJ: return "CartridgeCDFJ"; + case CDFSubtype::CDFJplus: + return "CartridgeCDFJplus"; default: return "Cart unknown"; } diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index cf172b8d2..180c08f44 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -25,16 +25,15 @@ class Thumbulator; #include "Cart.hxx" /** - Cartridge class used for CDF. + Cartridge class used for CDF/CDFJ/CDFJ+. There are seven 4K program banks, a 4K Display Data RAM, 1K C Variable and Stack, and the CDF chip. CDF chip access is mapped to $1000 - $103F (both read and write). - Program banks are accessible by read/write to $1FF5 - $1FFB. - + Program banks are accessible by read/write to $1FF5 - $1FFB FIXME: THIS NEEDS TO BE UPDATED - @authors: Darrell Spice Jr, Chris Walton, Fred Quimby, + @authors: Darrell Spice Jr, Chris Walton, Fred Quimby, John Champeau Stephen Anthony, Bradford W. Mott */ class CartridgeCDF : public Cartridge @@ -48,7 +47,8 @@ class CartridgeCDF : public Cartridge enum class CDFSubtype { CDF0, CDF1, - CDFJ + CDFJ, + CDFJplus }; public: @@ -220,23 +220,26 @@ class CartridgeCDF : public Cartridge void setupVersion(); private: - // The 32K ROM image of the cartridge + // The ROM image of the cartridge ByteBuffer myImage; - // Pointer to the 28K program ROM image of the cartridge + // Pointer to the program ROM image of the cartridge uInt8* myProgramImage{nullptr}; - // Pointer to the 4K display ROM image of the cartridge + // Pointer to the display ROM image of the cartridge uInt8* myDisplayImage{nullptr}; - // Pointer to the 2K CDF driver image in RAM + // Pointer to the driver image in RAM uInt8* myDriverImage{nullptr}; - // The CDF 8k RAM image, used as: - // $0000 - 2K CDF driver + // The CDFJ 8K RAM image, used as: + // $0000 - 2K Driver // $0800 - 4K Display Data // $1800 - 2K C Variable & Stack - std::array myRAM; + // For CDFJ+, used as: + // $0000 - 2K Driver + // $0800 - Display Data, C Variables & Stack + std::array myRAM; // Pointer to the Thumb ARM emulator object unique_ptr myThumbEmulator; diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 71500ee94..17494b8cb 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -54,6 +54,9 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size, (reinterpret_cast(myImage.get()), reinterpret_cast(myDPCRAM.data()), static_cast(32_KB), + 0x00000C00, + 0x00000C08, + 0x40001FDC, devSettings ? settings.getBool("dev.thumb.trapfatal") : false, Thumbulator::ConfigureFor::DPCplus, this); diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index dba8bb3e4..6874c2576 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -169,6 +169,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si type = Bankswitch::Type::_3E; else if(isProbably3F(image, size)) type = Bankswitch::Type::_3F; + else if (isProbablyCDF(image, size)) + type = Bankswitch::Type::_CDF; else if(isProbably4A50(image, size)) type = Bankswitch::Type::_4A50; else if(isProbablyEF(image, size, type)) @@ -188,6 +190,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si ; // type has been set directly in the function else if(isProbably3F(image, size)) type = Bankswitch::Type::_3F; + else if (isProbablyCDF(image, size)) + type = Bankswitch::Type::_CDF; else if(isProbably4A50(image, size)) type = Bankswitch::Type::_4A50; else /*if(isProbablySB(image, size))*/ @@ -203,6 +207,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si ; // type has been set directly in the function else if(isProbably3F(image, size)) type = Bankswitch::Type::_3F; + else if (isProbablyCDF(image, size)) + type = Bankswitch::Type::_CDF; else /*if(isProbablySB(image, size))*/ type = Bankswitch::Type::_SB; } @@ -216,6 +222,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si type = Bankswitch::Type::_3E; else if(isProbably3F(image, size)) type = Bankswitch::Type::_3F; + else if (isProbablyCDF(image, size)) + type = Bankswitch::Type::_CDF; } else // what else can we do? { @@ -444,7 +452,9 @@ bool CartDetector::isProbablyCDF(const ByteBuffer& image, size_t size) // Note: all Harmony/Melody custom drivers also contain the value // 0x10adab1e (LOADABLE) if needed for future improvement uInt8 cdf[] = { 'C', 'D', 'F' }; - return searchForBytes(image, size, cdf, 3, 3); + uInt8 cdfjplus[] = { 'P', 'L', 'U', 'S', 'C', 'D', 'F', 'J' }; + return (searchForBytes(image, size, cdf, 3, 3) || + searchForBytes(image, size, cdfjplus, 8, 1)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Thumbulator.cxx b/src/emucore/Thumbulator.cxx index 2984159cd..a9d5f3435 100644 --- a/src/emucore/Thumbulator.cxx +++ b/src/emucore/Thumbulator.cxx @@ -54,10 +54,14 @@ using Common::Base; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt16 rom_size, + const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack, bool traponfatal, Thumbulator::ConfigureFor configurefor, Cartridge* cartridge) : rom(rom_ptr), romSize(rom_size), + cBase(c_base), + cStart(c_start), + cStack(c_stack), decodedRom(make_unique(romSize / 2)), // NOLINT ram(ram_ptr), configuration(configurefor), @@ -217,7 +221,7 @@ uInt32 Thumbulator::fetch16(uInt32 addr) void Thumbulator::write16(uInt32 addr, uInt32 data) { #ifndef UNSAFE_OPTIMIZATIONS - if((addr > 0x40001fff) && (addr < 0x50000000)) + if((addr > 0x40007fff) && (addr < 0x50000000)) fatalError("write16", addr, "abort - out of range"); if (isProtected(addr)) fatalError("write16", addr, "to driver area"); @@ -376,6 +380,7 @@ bool Thumbulator::isProtected(uInt32 addr) return (addr < 0x0800) && (addr > 0x0028) && !((addr >= 0x00a0) && (addr < (0x00a0 + 284))); case ConfigureFor::CDFJ: + case ConfigureFor::CDFJplus: return (addr < 0x0800) && (addr > 0x0028) && !((addr >= 0x0098) && (addr < (0x0098 + 292))); case ConfigureFor::BUS: @@ -391,9 +396,9 @@ uInt32 Thumbulator::read16(uInt32 addr) { uInt32 data; #ifndef UNSAFE_OPTIMIZATIONS - if((addr > 0x40001fff) && (addr < 0x50000000)) + if((addr > 0x40007fff) && (addr < 0x50000000)) fatalError("read16", addr, "abort - out of range"); - else if((addr > 0x7fff) && (addr < 0x10000000)) + else if((addr > 0x0007ffff) && (addr < 0x10000000)) fatalError("read16", addr, "abort - out of range"); if(addr & 1) fatalError("read16", addr, "abort - misaligned"); @@ -1424,6 +1429,7 @@ int Thumbulator::execute() case ConfigureFor::CDF1: case ConfigureFor::CDFJ: + case ConfigureFor::CDFJplus: // this subroutine interface is used in the CDF driver, // it starts at address 0x00000750 // _SetNote: @@ -2521,25 +2527,10 @@ int Thumbulator::execute() int Thumbulator::reset() { reg_norm.fill(0); - reg_norm[13] = 0x40001FB4; - switch(configuration) - { - // future 2K Harmony/Melody drivers will most likely use these settings - case ConfigureFor::BUS: - case ConfigureFor::CDF: - case ConfigureFor::CDF1: - case ConfigureFor::CDFJ: - reg_norm[14] = 0x00000800; // Link Register - reg_norm[15] = 0x0000080B; // Program Counter - break; - - // future 3K Harmony/Melody drivers will most likely use these settings - case ConfigureFor::DPCplus: - reg_norm[14] = 0x00000C00; // Link Register - reg_norm[15] = 0x00000C0B; // Program Counter - break; - } + reg_norm[13] = cStack; // SP + reg_norm[14] = cBase; // LR + reg_norm[15] = (cStart + 2) | 1; // PC (+2 for pipeline, lower bit for THUMB) cpsr = mamcr = 0; handler_mode = false; diff --git a/src/emucore/Thumbulator.hxx b/src/emucore/Thumbulator.hxx index ae62d1755..2fd043627 100644 --- a/src/emucore/Thumbulator.hxx +++ b/src/emucore/Thumbulator.hxx @@ -35,11 +35,11 @@ class Cartridge; #define NO_THUMB_STATS #endif -#define ROMADDMASK 0x7FFF -#define RAMADDMASK 0x1FFF +#define ROMADDMASK 0x7FFFF +#define RAMADDMASK 0x7FFF -#define ROMSIZE (ROMADDMASK+1) -#define RAMSIZE (RAMADDMASK+1) +#define ROMSIZE (ROMADDMASK+1) // 512KB +#define RAMSIZE (RAMADDMASK+1) // 32KB #define CPSR_N (1u<<31) #define CPSR_Z (1u<<30) @@ -55,11 +55,13 @@ class Thumbulator BUS, // cartridges of type BUS CDF, // cartridges of type CDF CDF1, // cartridges of type CDF version 1 - CDFJ, // cartrdiges of type CDFJ + CDFJ, // cartridges of type CDFJ + CDFJplus, // cartridges of type CDFJ+ DPCplus // cartridges of type DPC+ }; Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt16 rom_size, + const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack, bool traponfatal, Thumbulator::ConfigureFor configurefor, Cartridge* cartridge); @@ -187,9 +189,11 @@ class Thumbulator private: const uInt16* rom{nullptr}; uInt16 romSize{0}; + uInt32 cBase{0}; + uInt32 cStart{0}; + uInt32 cStack{0}; const unique_ptr decodedRom; // NOLINT uInt16* ram{nullptr}; - std::array reg_norm; // normal execution mode, do not have a thread mode uInt32 cpsr{0}, mamcr{0}; bool handler_mode{false}; From c8755f8905ca8674f1bc8a471bb9f7ef816e8bad Mon Sep 17 00:00:00 2001 From: cd-w Date: Sat, 19 Sep 2020 09:23:24 -0700 Subject: [PATCH 046/263] Update debugger widget for CDFJ+ --- src/.vscode/settings.json | 61 ++++++++++++++++++++++++ src/debugger/gui/CartCDFWidget.cxx | 75 +++++++++++++++++++----------- src/debugger/gui/CartCDFWidget.hxx | 1 + src/emucore/CartCDF.cxx | 2 +- 4 files changed, 112 insertions(+), 27 deletions(-) create mode 100644 src/.vscode/settings.json diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json new file mode 100644 index 000000000..f1745352d --- /dev/null +++ b/src/.vscode/settings.json @@ -0,0 +1,61 @@ +{ + "files.associations": { + "array": "cpp", + "bitset": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "regex": "cpp", + "utility": "cpp", + "memory": "cpp", + "random": "cpp", + "optional": "cpp", + "atomic": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "ratio": "cpp", + "set": "cpp", + "string": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "fstream": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/src/debugger/gui/CartCDFWidget.cxx b/src/debugger/gui/CartCDFWidget.cxx index 3488dd9fe..f037e1412 100644 --- a/src/debugger/gui/CartCDFWidget.cxx +++ b/src/debugger/gui/CartCDFWidget.cxx @@ -34,13 +34,23 @@ CartridgeCDFWidget::CartridgeCDFWidget( int xpos = HBORDER, ypos = VBORDER; VariantList items; - VarList::push_back(items, "0 ($FFF5)"); - VarList::push_back(items, "1 ($FFF6)"); - VarList::push_back(items, "2 ($FFF7)"); - VarList::push_back(items, "3 ($FFF8)"); - VarList::push_back(items, "4 ($FFF9)"); - VarList::push_back(items, "5 ($FFFA)"); - VarList::push_back(items, "6 ($FFFB)"); + if (isCDFJplus()) { + VarList::push_back(items, "0 ($FFF4)"); + VarList::push_back(items, "1 ($FFF5)"); + VarList::push_back(items, "2 ($FFF6)"); + VarList::push_back(items, "3 ($FFF7)"); + VarList::push_back(items, "4 ($FFF8)"); + VarList::push_back(items, "5 ($FFF9)"); + VarList::push_back(items, "6 ($FFFA)"); + } else { + VarList::push_back(items, "0 ($FFF5)"); + VarList::push_back(items, "1 ($FFF6)"); + VarList::push_back(items, "2 ($FFF7)"); + VarList::push_back(items, "3 ($FFF8)"); + VarList::push_back(items, "4 ($FFF9)"); + VarList::push_back(items, "5 ($FFFA)"); + VarList::push_back(items, "6 ($FFFB)"); + } myBank = new PopUpWidget(boss, _font, xpos, ypos, _font.getStringWidth("0 ($FFFx)"), myLineHeight, items, "Set bank ", 0, kBankChanged); @@ -73,7 +83,7 @@ CartridgeCDFWidget::CartridgeCDFWidget( myCommandStreamPointer->setTarget(this); myCommandStreamPointer->setEditable(false); - if (isCDFJ()) + if (isCDFJ() || isCDFJplus()) myJumpStreamPointers = new DataGridWidget(boss, _nfont, DS_X + myDatastreamPointers->getWidth() * 2 / 4, ypos+myLineHeight + 9*myLineHeight, 2, 1, 6, 32, Common::Base::Fmt::_16_3_2); @@ -102,7 +112,7 @@ CartridgeCDFWidget::CartridgeCDFWidget( new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "), ypos+myLineHeight + 9*myLineHeight + 2, lwidth, myFontHeight, - isCDFJ() ? "Jump Data (21|22)" : "Jump Data (21)"); + (isCDFJ() || isCDFJplus()) ? "Jump Data (21|22)" : "Jump Data (21)"); // Datastream Increments xpos = DS_X + myDatastreamPointers->getWidth() + 16; @@ -121,7 +131,7 @@ CartridgeCDFWidget::CartridgeCDFWidget( myCommandStreamIncrement->setEditable(false); myJumpStreamIncrements = new DataGridWidget(boss, _nfont, xpos, - ypos+myLineHeight + 9*myLineHeight, isCDFJ() ? 2 : 1, 1, 5, 32, + ypos+myLineHeight + 9*myLineHeight, (isCDFJ() || isCDFJplus()) ? 2 : 1, 1, 5, 32, Common::Base::Fmt::_16_2_2); myJumpStreamIncrements->setTarget(this); myJumpStreamIncrements->setEditable(false); @@ -205,7 +215,7 @@ void CartridgeCDFWidget::saveOldState() myOldState.internalram.clear(); myOldState.samplepointer.clear(); - for(uInt32 i = 0; i < static_cast(isCDFJ() ? 35 : 34); ++i) + for(uInt32 i = 0; i < static_cast((isCDFJ() || isCDFJplus()) ? 35 : 34); ++i) { // Pointers are stored as: // PPPFF--- @@ -281,7 +291,7 @@ void CartridgeCDFWidget::loadConfig() myCommandStreamPointer->setList(alist, vlist, changed); alist.clear(); vlist.clear(); changed.clear(); - for(int i = 0; i < (isCDFJ() ? 2 : 1); ++i) + for(int i = 0; i < ((isCDFJ() || isCDFJplus()) ? 2 : 1); ++i) { Int32 pointervalue = myCart.getDatastreamPointer(0x21 + i) >> 12; alist.push_back(0); vlist.push_back(pointervalue); @@ -305,7 +315,7 @@ void CartridgeCDFWidget::loadConfig() myCommandStreamIncrement->setList(alist, vlist, changed); alist.clear(); vlist.clear(); changed.clear(); - for(int i = 0; i < (isCDFJ() ? 2 : 1); ++i) + for(int i = 0; i < ((isCDFJ() || isCDFJplus()) ? 2 : 1); ++i) { Int32 pointervalue = myCart.getDatastreamIncrement(0x21 + i) >> 12; alist.push_back(0); vlist.push_back(pointervalue); @@ -387,11 +397,12 @@ string CartridgeCDFWidget::bankState() { ostringstream& buf = buffer(); - static constexpr std::array spot = { - "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB" + static constexpr std::array spot = { + "$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB" }; + buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; + << ", hotspot = " << spot[myCart.getBank() + (isCDFJplus() ? 0 : 1)]; return buf.str(); } @@ -399,7 +410,7 @@ string CartridgeCDFWidget::bankState() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeCDFWidget::internalRamSize() { - return 8*1024; + return isCDFJplus() ? 32*1024 : 8*1024; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -412,13 +423,21 @@ uInt32 CartridgeCDFWidget::internalRamRPort(int start) string CartridgeCDFWidget::internalRamDescription() { ostringstream desc; - desc << "$0000 - $07FF - CDF driver\n" - << " not accessible to 6507\n" - << "$0800 - $17FF - 4K Data Stream storage\n" - << " indirectly accessible to 6507\n" - << " via CDF's Data Stream registers\n" - << "$1800 - $1FFF - 2K C variable storage and stack\n" - << " not accessible to 6507"; + if (isCDFJplus()) { + desc << "$0000 - $07FF - CDFJ+ driver\n" + << " not accessible to 6507\n" + << "$0800 - $7FFF - 30K Data Stream storage\n" + << " indirectly accessible to 6507\n" + << " via fast fecthers\n"; + } else { + desc << "$0000 - $07FF - CDF/CDFJ driver\n" + << " not accessible to 6507\n" + << "$0800 - $17FF - 4K Data Stream storage\n" + << " indirectly accessible to 6507\n" + << " via fast fetchers\n" + << "$1800 - $1FFF - 2K C variable storage and stack\n" + << " not accessible to 6507"; + } return desc.str(); } @@ -478,6 +497,10 @@ string CartridgeCDFWidget::describeCDFVersion(CartridgeCDF::CDFSubtype subtype) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeCDFWidget::isCDFJ() const { - return (myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ || - myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJplus); // FIXME: Separate settings for CDFJ+ + return (myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ); } + +bool CartridgeCDFWidget::isCDFJplus() const +{ + return (myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJplus); +} \ No newline at end of file diff --git a/src/debugger/gui/CartCDFWidget.hxx b/src/debugger/gui/CartCDFWidget.hxx index fdf5622a9..431553db6 100644 --- a/src/debugger/gui/CartCDFWidget.hxx +++ b/src/debugger/gui/CartCDFWidget.hxx @@ -75,6 +75,7 @@ class CartridgeCDFWidget : public CartDebugWidget private: bool isCDFJ() const; + bool isCDFJplus() const; static string describeCDFVersion(CartridgeCDF::CDFSubtype subtype); diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 867b66a7b..dc24eb29b 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -788,7 +788,7 @@ string CartridgeCDF::name() const case CDFSubtype::CDFJ: return "CartridgeCDFJ"; case CDFSubtype::CDFJplus: - return "CartridgeCDFJplus"; + return "CartridgeCDFJ+"; default: return "Cart unknown"; } From 6636429e2b3f502369aa82c7a6ae55606f26594e Mon Sep 17 00:00:00 2001 From: cd-w Date: Sat, 19 Sep 2020 09:48:32 -0700 Subject: [PATCH 047/263] Remove vscode settings --- .gitignore | 1 + .vscode/settings.json | 98 ------------------------------------------- 2 files changed, 1 insertion(+), 98 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 8e6d3e86a..e1dce7f74 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ build/ src/macosx/M6502.ins *.dSYM .vscode/c_cpp_properties.json +.vscode/settings.json src/windows/sdl/* src/windows/x64/* src/windows/Win32/* diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 40ad65881..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,98 +0,0 @@ -// Platzieren Sie Ihre Einstellungen in dieser Datei, um Standard- und Benutzereinstellungen zu überschreiben. -{ - "editor.tabSize": 2, - "files.trimTrailingWhitespace": true, - "files.exclude": { - "**/.git": true, - "**/.svn": true, - "**/.hg": true, - "**/.DS_Store": true, - "src/**/*.o": true - }, - "editor.trimAutoWhitespace": true, - "editor.useTabStops": false, - "C_Cpp.intelliSenseEngine": "Default", - "files.insertFinalNewline": true, - "files.associations": { - "__functional_base": "cpp", - "array": "cpp", - "istream": "cpp", - "locale": "cpp", - "memory": "cpp", - "thread": "cpp", - "tuple": "cpp", - "utility": "cpp", - "*.tcc": "cpp", - "functional": "cpp", - "iomanip": "cpp", - "__cxx_version": "cpp", - "string": "cpp", - "type_traits": "cpp", - "ostream": "cpp", - "__bit_reference": "cpp", - "__config": "cpp", - "__debug": "cpp", - "__errc": "cpp", - "__hash_table": "cpp", - "__locale": "cpp", - "__mutex_base": "cpp", - "__node_handle": "cpp", - "__nullptr": "cpp", - "__split_buffer": "cpp", - "__string": "cpp", - "__threading_support": "cpp", - "__tree": "cpp", - "__tuple": "cpp", - "algorithm": "cpp", - "atomic": "cpp", - "bit": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "codecvt": "cpp", - "complex": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "exception": "cpp", - "fstream": "cpp", - "initializer_list": "cpp", - "ios": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "iterator": "cpp", - "limits": "cpp", - "list": "cpp", - "map": "cpp", - "mutex": "cpp", - "new": "cpp", - "numeric": "cpp", - "optional": "cpp", - "queue": "cpp", - "random": "cpp", - "ratio": "cpp", - "set": "cpp", - "sstream": "cpp", - "stack": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "typeinfo": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "memory_resource": "cpp", - "cfenv": "cpp", - "cinttypes": "cpp" - } -} From c975ca0850138e4fb7764bdf0adc57368936382e Mon Sep 17 00:00:00 2001 From: cd-w Date: Sat, 19 Sep 2020 10:30:55 -0700 Subject: [PATCH 048/263] Revert "Remove vscode settings" This reverts commit 6636429e2b3f502369aa82c7a6ae55606f26594e. --- .gitignore | 1 - .vscode/settings.json | 98 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index e1dce7f74..8e6d3e86a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ build/ src/macosx/M6502.ins *.dSYM .vscode/c_cpp_properties.json -.vscode/settings.json src/windows/sdl/* src/windows/x64/* src/windows/Win32/* diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..40ad65881 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,98 @@ +// Platzieren Sie Ihre Einstellungen in dieser Datei, um Standard- und Benutzereinstellungen zu überschreiben. +{ + "editor.tabSize": 2, + "files.trimTrailingWhitespace": true, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/.DS_Store": true, + "src/**/*.o": true + }, + "editor.trimAutoWhitespace": true, + "editor.useTabStops": false, + "C_Cpp.intelliSenseEngine": "Default", + "files.insertFinalNewline": true, + "files.associations": { + "__functional_base": "cpp", + "array": "cpp", + "istream": "cpp", + "locale": "cpp", + "memory": "cpp", + "thread": "cpp", + "tuple": "cpp", + "utility": "cpp", + "*.tcc": "cpp", + "functional": "cpp", + "iomanip": "cpp", + "__cxx_version": "cpp", + "string": "cpp", + "type_traits": "cpp", + "ostream": "cpp", + "__bit_reference": "cpp", + "__config": "cpp", + "__debug": "cpp", + "__errc": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__mutex_base": "cpp", + "__node_handle": "cpp", + "__nullptr": "cpp", + "__split_buffer": "cpp", + "__string": "cpp", + "__threading_support": "cpp", + "__tree": "cpp", + "__tuple": "cpp", + "algorithm": "cpp", + "atomic": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "exception": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "map": "cpp", + "mutex": "cpp", + "new": "cpp", + "numeric": "cpp", + "optional": "cpp", + "queue": "cpp", + "random": "cpp", + "ratio": "cpp", + "set": "cpp", + "sstream": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "memory_resource": "cpp", + "cfenv": "cpp", + "cinttypes": "cpp" + } +} From 9090acc1c906abf33e21918e34386f82dd9d052e Mon Sep 17 00:00:00 2001 From: cd-w Date: Sat, 19 Sep 2020 13:03:04 -0700 Subject: [PATCH 049/263] Add romSize and ramSize functions --- .gitignore | 1 + src/.vscode/settings.json | 61 --------------------- src/debugger/gui/CartCDFInfoWidget.cxx | 28 +++------- src/debugger/gui/CartCDFWidget.cxx | 4 +- src/emucore/CartCDF.cxx | 73 +++++++++++++++----------- src/emucore/CartCDF.hxx | 15 ++++++ 6 files changed, 67 insertions(+), 115 deletions(-) delete mode 100644 src/.vscode/settings.json diff --git a/.gitignore b/.gitignore index 8e6d3e86a..e1dce7f74 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ build/ src/macosx/M6502.ins *.dSYM .vscode/c_cpp_properties.json +.vscode/settings.json src/windows/sdl/* src/windows/x64/* src/windows/Win32/* diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json deleted file mode 100644 index f1745352d..000000000 --- a/src/.vscode/settings.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "files.associations": { - "array": "cpp", - "bitset": "cpp", - "string_view": "cpp", - "initializer_list": "cpp", - "regex": "cpp", - "utility": "cpp", - "memory": "cpp", - "random": "cpp", - "optional": "cpp", - "atomic": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "list": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "map": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "ratio": "cpp", - "set": "cpp", - "string": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "fstream": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "ostream": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp" - } -} \ No newline at end of file diff --git a/src/debugger/gui/CartCDFInfoWidget.cxx b/src/debugger/gui/CartCDFInfoWidget.cxx index ab183af33..a1db55cdf 100644 --- a/src/debugger/gui/CartCDFInfoWidget.cxx +++ b/src/debugger/gui/CartCDFInfoWidget.cxx @@ -23,27 +23,15 @@ CartridgeCDFInfoWidget::CartridgeCDFInfoWidget( int x, int y, int w, int h, CartridgeCDF& cart) : CartDebugWidget(boss, lfont, nfont, x, y, w, h) { - uInt32 size; ostringstream info; - if (cart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJplus) { - size = 512 * 1024; - info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n" - << "512K ROM (seven 4K banks are accessible to 2600)\n" - << "32K RAM\n" - << "Functions accessible @ $FFF0 - $FFF3\n" - << "Banks accessible @ $FFF4 to $FFFB\n" - << "Startup bank = " << cart.startBank() << "\n"; - - } else { - size = 8 * 4096; - info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n" - << "32K ROM (seven 4K banks are accessible to 2600)\n" - << "8K RAM\n" - << "Functions accessible @ $FFF0 - $FFF3\n" - << "Banks accessible @ $FFF4 to $FFFB\n" - << "Startup bank = " << cart.startBank() << "\n"; - } + info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n" + << (cart.romSize() / 1024) << "K ROM\n" + << (cart.ramSize() / 1024) << "K RAM\n" + << "Seven 4K banks are available to 2600\n" + << "Functions accessible @ $FFF0 - $FFF3\n" + << (cart.isCDFJplus() ? "Banks accessible @ $FFF4 to $FFFA\n" : "Banks accessible @ $FFF5 to $FFFB\n") + << "Startup bank = " << cart.startBank() << "\n"; #if 0 // Eventually, we should query this from the debugger/disassembler @@ -56,7 +44,7 @@ CartridgeCDFInfoWidget::CartridgeCDFInfoWidget( } #endif - addBaseInformation(size, "AtariAge", info.str()); + addBaseInformation(cart.romSize(), "AtariAge", info.str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/CartCDFWidget.cxx b/src/debugger/gui/CartCDFWidget.cxx index f037e1412..23027495e 100644 --- a/src/debugger/gui/CartCDFWidget.cxx +++ b/src/debugger/gui/CartCDFWidget.cxx @@ -410,7 +410,7 @@ string CartridgeCDFWidget::bankState() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeCDFWidget::internalRamSize() { - return isCDFJplus() ? 32*1024 : 8*1024; + return myCart.ramSize(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -502,5 +502,5 @@ bool CartridgeCDFWidget::isCDFJ() const bool CartridgeCDFWidget::isCDFJplus() const { - return (myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJplus); + return (myCart.isCDFJplus()); } \ No newline at end of file diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index dc24eb29b..1155c307a 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -75,15 +75,12 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, // Detect cart version setupVersion(); - // CDFJ+ has different settings - bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); - // The lowest 2K is not accessible to the debugger - createRomAccessArrays(cdfjPlus ? 510_KB : 28_KB); + createRomAccessArrays(isCDFJplus() ? 510_KB : 28_KB); // Pointer to the program ROM // which starts after the 2K driver (and 2K C Code for CDF) - myProgramImage = myImage.get() + (cdfjPlus ? 2_KB : 4_KB); + myProgramImage = myImage.get() + (isCDFJplus() ? 2_KB : 4_KB); // Pointer to CDF driver in RAM myDriverImage = myRAM.data(); @@ -93,7 +90,7 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, // C addresses uInt32 cBase, cStart, cStack; - if (cdfjPlus) { + if (isCDFJplus()) { cBase = getUInt32(myImage.get(), 0x17F8) & 0xFFFFFFFE; // C Base Address cStart = cBase; // C Start Address cStack = getUInt32(myImage.get(), 0x17F4); // C Stack @@ -123,7 +120,7 @@ void CartridgeCDF::reset() initializeRAM(myRAM.data()+2_KB, myRAM.size()-2_KB); // CDF always starts in bank 6, CDFJ+ in bank 0 - initializeStartBank((myCDFSubtype == CDFSubtype::CDFJplus) ? 0 : 6); + initializeStartBank(isCDFJplus() ? 0 : 6); myAudioCycles = myARMCycles = 0; myFractionalClocks = 0.0; @@ -218,8 +215,6 @@ inline void CartridgeCDF::callFunction(uInt8 value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeCDF::peek(uInt16 address) { - bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); - address &= 0x0FFF; uInt8 peekvalue = myProgramImage[myBankOffset + address]; @@ -239,7 +234,7 @@ uInt8 CartridgeCDF::peek(uInt16 address) ++myJMPoperandAddress; pointer = getDatastreamPointer(myFastJumpStream); - if (cdfjPlus) { + if (isCDFJplus()) { value = myDisplayImage[ pointer >> 16 ]; pointer += 0x00010000; // always increment by 1 } else { @@ -316,35 +311,35 @@ uInt8 CartridgeCDF::peek(uInt16 address) switch(address) { case 0x0FF4: - bank(cdfjPlus ? 0 : 6); + bank(isCDFJplus() ? 0 : 6); break; case 0x0FF5: - bank(cdfjPlus ? 1 : 0); + bank(isCDFJplus() ? 1 : 0); break; case 0x0FF6: - bank(cdfjPlus ? 2 : 1); + bank(isCDFJplus() ? 2 : 1); break; case 0x0FF7: - bank(cdfjPlus ? 3 : 2); + bank(isCDFJplus() ? 3 : 2); break; case 0x0FF8: - bank(cdfjPlus ? 4 : 3); + bank(isCDFJplus() ? 4 : 3); break; case 0x0FF9: - bank(cdfjPlus ? 5 : 4); + bank(isCDFJplus() ? 5 : 4); break; case 0x0FFA: - bank(cdfjPlus ? 6 : 5); + bank(isCDFJplus() ? 6 : 5); break; case 0x0FFB: - bank(cdfjPlus ? 0 : 6); + bank(isCDFJplus() ? 0 : 6); break; default: @@ -361,14 +356,13 @@ uInt8 CartridgeCDF::peek(uInt16 address) bool CartridgeCDF::poke(uInt16 address, uInt8 value) { uInt32 pointer; - bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); address &= 0x0FFF; switch(address) { case 0x0FF0: // DSWRITE pointer = getDatastreamPointer(COMMSTREAM); - if (cdfjPlus) { + if (isCDFJplus()) { myDisplayImage[ pointer >> 16 ] = value; pointer += 0x00010000; // always increment by 1 when writing } else { @@ -381,7 +375,7 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value) case 0x0FF1: // DSPTR pointer = getDatastreamPointer(COMMSTREAM); pointer <<= 8; - if (cdfjPlus) { + if (isCDFJplus()) { pointer &= 0xff000000; pointer |= (value << 16); } else { @@ -400,35 +394,35 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value) break; case 0x00FF4: - bank(cdfjPlus ? 0 : 6); + bank(isCDFJplus() ? 0 : 6); break; case 0x0FF5: - bank(cdfjPlus ? 1 : 0); + bank(isCDFJplus() ? 1 : 0); break; case 0x0FF6: - bank(cdfjPlus ? 2 : 1); + bank(isCDFJplus() ? 2 : 1); break; case 0x0FF7: - bank(cdfjPlus ? 3 : 2); + bank(isCDFJplus() ? 3 : 2); break; case 0x0FF8: - bank(cdfjPlus ? 4 : 3); + bank(isCDFJplus() ? 4 : 3); break; case 0x0FF9: - bank(cdfjPlus ? 5 : 4); + bank(isCDFJplus() ? 5 : 4); break; case 0x0FFA: - bank(cdfjPlus ? 6 : 5); + bank(isCDFJplus() ? 6 : 5); break; case 0x0FFB: - bank(cdfjPlus ? 0 : 6); + bank(isCDFJplus() ? 0 : 6); break; default: @@ -654,7 +648,7 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const result -= (0x40000000 + 2_KB); - if (myCDFSubtype != CDFSubtype::CDFJplus) { + if (!isCDFJplus()) { if (result >= 4096) { result &= 4095; } @@ -698,8 +692,7 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index) uInt16 increment = getDatastreamIncrement(index); uInt8 value; - bool cdfjPlus = (myCDFSubtype == CDFSubtype::CDFJplus); - if (cdfjPlus) { + if (isCDFJplus()) { value = myDisplayImage[ pointer >> 16 ]; pointer += (increment << 8); } else { @@ -794,6 +787,22 @@ string CartridgeCDF::name() const } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeCDF::isCDFJplus() const +{ + return (myCDFSubtype == CDFSubtype::CDFJplus); +} + +uInt32 CartridgeCDF::ramSize() const +{ + return isCDFJplus() ? 32_KB : 8_KB; +} + +uInt32 CartridgeCDF::romSize() const +{ + return isCDFJplus() ? 512_KB : 32_KB; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #ifdef DEBUGGER_SUPPORT CartDebugWidget* CartridgeCDF::debugWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 180c08f44..fd374d9df 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -154,6 +154,21 @@ class CartridgeCDF : public Cartridge */ uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) override; + /** + Set if we are using CDFJ+ bankswitching + */ + bool isCDFJplus() const; + + /** + Size of SRAM (RAM) area in cart + */ + uInt32 ramSize() const; + + /** + Size of Flash memory (ROM) area in cart + */ + uInt32 romSize() const; + #ifdef DEBUGGER_SUPPORT /** Get debugger widget responsible for accessing the inner workings From e0a74d2346c1e64f78a6c18fce67d84ac0773577 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 19 Sep 2020 22:35:39 +0200 Subject: [PATCH 050/263] fixed warnings --- src/emucore/CartCDF.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 1155c307a..93e330c39 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -646,7 +646,7 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const (myRAM[address + 2] << 16) + (myRAM[address + 3] << 24); // high byte - result -= (0x40000000 + 2_KB); + result -= (0x40000000 + uInt32(2_KB)); if (!isCDFJplus()) { if (result >= 4096) { @@ -795,12 +795,12 @@ bool CartridgeCDF::isCDFJplus() const uInt32 CartridgeCDF::ramSize() const { - return isCDFJplus() ? 32_KB : 8_KB; + return uInt32(isCDFJplus() ? 32_KB : 8_KB); } uInt32 CartridgeCDF::romSize() const { - return isCDFJplus() ? 512_KB : 32_KB; + return uInt32(isCDFJplus() ? 512_KB : 32_KB); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 96d5986ddd77ceadd893a7a647ad23be81de12d5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 19 Sep 2020 22:39:44 +0200 Subject: [PATCH 051/263] updated docs for CDFJ+ --- Changes.txt | 2 ++ docs/index.html | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Changes.txt b/Changes.txt index b700ac28a..682031785 100644 --- a/Changes.txt +++ b/Changes.txt @@ -41,6 +41,8 @@ * Added option to select the audio device. + * Added support for CDFJ+ bankswitching type. + * Further enhanced UA bankswitching to support more Brazilian carts. * Added option to display detected settings info when a ROM is loaded. diff --git a/docs/index.html b/docs/index.html index 3014e6826..b8ead55cb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -287,7 +287,7 @@ AtariVox and SaveKey controllers, as well as FLASH support in various cartridge schemes
  • Supports all known bankswitching schemes (let us know if there's one we missed)
  • -
  • Supports DPC+/CDF(J) bankswitching schemes from the Harmony Cart, +
  • Supports DPC+/CDF(J)(+) bankswitching schemes from the Harmony Cart, including partial emulation of the ARM processor
  • Supports cartridge autodetection for almost all bankswitching schemes
  • Supports using ROM filename extensions to force specific bankswitching schemes
  • @@ -4106,7 +4106,7 @@ Ms Pac-Man (Stella extended codes): - + From dc3fc32c849236f3d7cefaeeffb84141c8b83043 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 19 Sep 2020 18:22:57 -0230 Subject: [PATCH 052/263] Fix minor warning (missing newline), and minor cleanup. --- src/debugger/gui/CartCDFWidget.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/debugger/gui/CartCDFWidget.cxx b/src/debugger/gui/CartCDFWidget.cxx index 23027495e..8b43d0fc8 100644 --- a/src/debugger/gui/CartCDFWidget.cxx +++ b/src/debugger/gui/CartCDFWidget.cxx @@ -497,10 +497,11 @@ string CartridgeCDFWidget::describeCDFVersion(CartridgeCDF::CDFSubtype subtype) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeCDFWidget::isCDFJ() const { - return (myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ); + return myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeCDFWidget::isCDFJplus() const { - return (myCart.isCDFJplus()); -} \ No newline at end of file + return myCart.isCDFJplus(); +} From 85abd89c747e0f9dc941493c6b2670a7588e6b89 Mon Sep 17 00:00:00 2001 From: cd-w Date: Sat, 19 Sep 2020 15:05:36 -0700 Subject: [PATCH 053/263] CDFJ+ test binaries --- src/emucore/CartCDF.hxx | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index fd374d9df..812792f3f 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -27,14 +27,30 @@ class Thumbulator; /** Cartridge class used for CDF/CDFJ/CDFJ+. - There are seven 4K program banks, a 4K Display Data RAM, - 1K C Variable and Stack, and the CDF chip. - CDF chip access is mapped to $1000 - $103F (both read and write). - Program banks are accessible by read/write to $1FF5 - $1FFB - FIXME: THIS NEEDS TO BE UPDATED + CDFJ bankswitching for Atari games using ARM/C code. + There are two variants supported: + 1) CDF/CDFJ - initial scheme with 32K ROM and 8K RAM + 2) CDFJ+ - support for larger ROM sizes (64/128/256/512K) and RAM sizes (16/32K) + + Features: + 32 fast fetchers + 2 fast jump queues + 1 parameter queue + 3 channel digital audio/1 channel sampled sound + 7 banks (4K) of atari code + 4K display data (16K and 32K available with CDFJ+) + + Note that for CDFJ+, the same driver is used for all RAM/RAM combinations. + It is left to the programmer to ensure that only the available RAM/ROM on the target device is used. + + Bankswitching Note: + CDF/CDFJ uses $FFF5 through $FFFB (initial bank 6) + CDFJ+ uses $FFF4 through $FFFA (initial bank 0) + + The letters CDFJ stand for Chris, Darrell, Fred, and John. @authors: Darrell Spice Jr, Chris Walton, Fred Quimby, John Champeau - Stephen Anthony, Bradford W. Mott + Thomas Jentzsch, Stephen Anthony, Bradford W. Mott */ class CartridgeCDF : public Cartridge { From 7d2be44a5ce82ed5f5fd9a4bcde8d5b2dc23c583 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 19 Sep 2020 19:41:34 -0230 Subject: [PATCH 054/263] Autodetect serial port for AVox-USB adaptor on startup, and set 'avoxport' argument. This completely automates the discovery of the AVox port when only one such port exists. If there is more than one, this code selects the first one. Further work will allow the user to go into the Input dialog and select the correct one, if more than one exists. On my system, this adds about a 0.02 second delay to startup, so I think we can just leave it enabled. If it ends up being too slow on some systems, we can introduce an option to disable autodetection. --- src/common/bspf.hxx | 6 ++++++ src/emucore/OSystem.cxx | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index b23f6475b..9c7fb02df 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -160,6 +160,12 @@ namespace BSPF return (val < lower) ? upper : (val > upper) ? lower : val; } + // Test whether the vector contains the given value + template + bool contains(const std::vector& v, const T& elem) { + return !(v.empty() || std::find(v.begin(), v.end(), elem) == v.end()); + } + // Convert string to given case inline const string& toUpperCase(string& s) { diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index d0e04e1fd..d7cc5e602 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -185,6 +185,14 @@ bool OSystem::create() myPropSet->load(myPropertiesFile); + // Detect serial port for AtariVox-USB + // If a previously set port is available, use it; + // otherwise use the first one found (if any) + StringList ports = MediaFactory::createSerialPort()->portNames(); + bool oldPortFound = BSPF::contains(ports, mySettings->getString("avoxport")); + if(!oldPortFound && ports.size() > 0) + mySettings->setValue("avoxport", ports[0]); + return true; } From ffb0ccdf620b87b9e93f07c4c2532d4d69a78bfc Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 29 Sep 2020 15:56:27 -0230 Subject: [PATCH 055/263] Wrap 'windows.h' inside a C++ compatible header file. --- src/windows/FSNodeWINDOWS.cxx | 9 +-------- src/windows/SerialPortWINDOWS.cxx | 3 +-- src/windows/SerialPortWINDOWS.hxx | 3 +-- src/windows/Windows.hxx | 33 +++++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 src/windows/Windows.hxx diff --git a/src/windows/FSNodeWINDOWS.cxx b/src/windows/FSNodeWINDOWS.cxx index 0fecc3e1c..c8676e542 100644 --- a/src/windows/FSNodeWINDOWS.cxx +++ b/src/windows/FSNodeWINDOWS.cxx @@ -18,16 +18,8 @@ #include #pragma warning( disable : 4091 ) #include - -#ifdef ARRAYSIZE - #undef ARRAYSIZE -#endif - #include #include -#include -// winnt.h defines ARRAYSIZE, but we want our own one... -#undef ARRAYSIZE // F_OK, R_OK and W_OK are not defined under MSVC, so we define them here // For more information on the modes used by MSVC, check: @@ -44,6 +36,7 @@ #define W_OK 2 #endif +#include "Windows.hxx" #include "FSNodeWINDOWS.hxx" /** diff --git a/src/windows/SerialPortWINDOWS.cxx b/src/windows/SerialPortWINDOWS.cxx index 8ec755091..a9b738c7c 100644 --- a/src/windows/SerialPortWINDOWS.cxx +++ b/src/windows/SerialPortWINDOWS.cxx @@ -15,8 +15,7 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include - +#include "Windows.hxx" #include "SerialPortWINDOWS.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/windows/SerialPortWINDOWS.hxx b/src/windows/SerialPortWINDOWS.hxx index 8c2215c51..1fcc2882e 100644 --- a/src/windows/SerialPortWINDOWS.hxx +++ b/src/windows/SerialPortWINDOWS.hxx @@ -18,8 +18,7 @@ #ifndef SERIALPORT_WINDOWS_HXX #define SERIALPORT_WINDOWS_HXX -#include - +#include "Windows.hxx" #include "SerialPort.hxx" /** diff --git a/src/windows/Windows.hxx b/src/windows/Windows.hxx new file mode 100644 index 000000000..3c45cfcf2 --- /dev/null +++ b/src/windows/Windows.hxx @@ -0,0 +1,33 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef WINDOWS_LIB_HXX +#define WINDOWS_LIB_HXX + +/* + Using window.h directly can cause problems, since it's a C library + that doesn't support namespacing, etc. + + Anyone needing 'windows.h' should include this file instead. +*/ + +#include + +#undef MessageBox +#undef ARRAYSIZE + +#endif // WINDOWS_LIB_HXX From 7a0bd5344ddb2862be2ea737c8a1073c44fd38f6 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 29 Sep 2020 16:08:48 -0230 Subject: [PATCH 056/263] Forgot to include header file in VS project file. --- src/windows/Stella.vcxproj | 1 + src/windows/Stella.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 843abc45d..bf2c1c37d 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -2038,6 +2038,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 35b428e4f..ce790b6e7 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -2105,6 +2105,9 @@ Header Files\gui + + Header Files + From 7823640f2f624ab4aacec5bded1cad3458dcc59f Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 29 Sep 2020 16:10:59 -0230 Subject: [PATCH 057/263] Added autodetection for AVox-USB adaptor to UI (fixes #688). --- Changes.txt | 2 ++ src/common/bspf.hxx | 8 ++++++++ src/gui/InputDialog.cxx | 25 ++++++++++++++++++------- src/gui/InputDialog.hxx | 2 +- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Changes.txt b/Changes.txt index 682031785..154bb8440 100644 --- a/Changes.txt +++ b/Changes.txt @@ -37,6 +37,8 @@ are no longer corrupted/cut off. This includes properly supporting the 2600-daptor II, which is flashable to an AVox-USB converter. + * The serial port to use for an AtariVox-USB adaptor is now autodetected. + * Added QuadTari controller support. * Added option to select the audio device. diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 9c7fb02df..d03174558 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -93,6 +93,14 @@ constexpr size_t operator "" _KB(unsigned long long size) return static_cast(size * 1024); } +// Output contents of a vector +template +std::ostream& operator<< (std::ostream& out, const std::vector& v) { + for(const auto& elem: v) + out << elem << " "; + return out; +} + static const string EmptyString(""); // This is defined by some systems, but Stella has other uses for it diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index 727c9a874..d7b915e75 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -34,6 +34,7 @@ #include "Widget.hxx" #include "Font.hxx" #include "MessageBox.hxx" +#include "MediaFactory.hxx" #include "InputDialog.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -222,10 +223,11 @@ void InputDialog::addDevicePortTab() // Add AtariVox serial port ypos += lineHeight + VGAP * 3; lwidth = _font.getStringWidth("AtariVox serial port "); - fwidth = _w - HBORDER * 2 - 2 - lwidth; - new StaticTextWidget(myTab, _font, HBORDER, ypos + 2, "AtariVox serial port "); - myAVoxPort = new EditTextWidget(myTab, _font, HBORDER + lwidth, ypos, - fwidth, fontHeight); + fwidth = _w - HBORDER * 2 - 2 - lwidth - 20; + VariantList items; + VarList::push_back(items, "None detected", ""); + myAVoxPort = new PopUpWidget(myTab, _font, HBORDER, ypos, fwidth, lineHeight, items, + "AtariVox serial port ", lwidth, kCursorStateChanged); wid.push_back(myAVoxPort); // Add items for virtual device ports @@ -359,7 +361,16 @@ void InputDialog::loadConfig() myAutoFireRate->setValue(settings.getInt("autofirerate")); // AtariVox serial port - myAVoxPort->setText(settings.getString("avoxport")); + const string& avoxport = settings.getString("avoxport"); + StringList ports = MediaFactory::createSerialPort()->portNames(); + if(avoxport != EmptyString && !BSPF::contains(ports, avoxport)) + ports.push_back(avoxport); + VariantList items; + VarList::push_back(items, "None detected", ""); + for(const auto& port: ports) + VarList::push_back(items, port, port); + myAVoxPort->addItems(items); + myAVoxPort->setSelected(avoxport); // EEPROM erase (only enable in emulation mode and for valid controllers) if(instance().hasConsole()) @@ -440,7 +451,7 @@ void InputDialog::saveConfig() Controller::setAutoFireRate(rate); // AtariVox serial port - settings.setValue("avoxport", myAVoxPort->getText()); + settings.setValue("avoxport", myAVoxPort->getSelectedTag().toString()); // Allow all 4 joystick directions bool allowall4 = myAllowAll4->getState(); @@ -500,7 +511,7 @@ void InputDialog::setDefaults() // Autofire rate myAutoFireRate->setValue(0); // AtariVox serial port - myAVoxPort->setText(""); + myAVoxPort->setSelectedMax(); // Allow all 4 joystick directions myAllowAll4->setState(false); diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx index 6cb6c4742..201f807d3 100644 --- a/src/gui/InputDialog.hxx +++ b/src/gui/InputDialog.hxx @@ -94,7 +94,7 @@ class InputDialog : public Dialog CheckboxWidget* mySAPort{nullptr}; - EditTextWidget* myAVoxPort{nullptr}; + PopUpWidget* myAVoxPort{nullptr}; SliderWidget* myDeadzone{nullptr}; SliderWidget* myPaddleSpeed{nullptr}; From 8e9af80a01751eb7843e150183fa02d60d4097ef Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 29 Sep 2020 23:21:28 +0200 Subject: [PATCH 058/263] Adapt dialog for various font sizes --- src/gui/InputDialog.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index d7b915e75..cbb76e20c 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -130,7 +130,7 @@ void InputDialog::addDevicePortTab() myDeadzone->setTickmarkIntervals(4); wid.push_back(myDeadzone); - xpos = HBORDER; ypos += lineHeight + VGAP * 4; + xpos = HBORDER; ypos += lineHeight + VGAP * 3; new StaticTextWidget(myTab, _font, xpos, ypos+1, "Analog paddle:"); xpos += fontWidth * 2; @@ -165,7 +165,7 @@ void InputDialog::addDevicePortTab() wid.push_back(myDejitterDiff); // Add paddle speed (digital emulation) - ypos += lineHeight + VGAP * 4; + ypos += lineHeight + VGAP * 3; myDPaddleSpeed = new SliderWidget(myTab, _font, HBORDER, ypos - 1, 13 * fontWidth, lineHeight, "Digital paddle sensitivity", lwidth, kDPSpeedChanged, 4 * fontWidth, "%"); @@ -173,7 +173,7 @@ void InputDialog::addDevicePortTab() myDPaddleSpeed->setTickmarkIntervals(4); wid.push_back(myDPaddleSpeed); - ypos += lineHeight + VGAP * 4; + ypos += lineHeight + VGAP * 3; myAutoFireRate = new SliderWidget(myTab, _font, HBORDER, ypos - 1, 13 * fontWidth, lineHeight, "Autofire rate", lwidth, kAutoFireChanged, 5 * fontWidth, "Hz"); @@ -223,7 +223,7 @@ void InputDialog::addDevicePortTab() // Add AtariVox serial port ypos += lineHeight + VGAP * 3; lwidth = _font.getStringWidth("AtariVox serial port "); - fwidth = _w - HBORDER * 2 - 2 - lwidth - 20; + fwidth = _w - HBORDER * 2 - 2 - lwidth - PopUpWidget::dropDownWidth(_font); VariantList items; VarList::push_back(items, "None detected", ""); myAVoxPort = new PopUpWidget(myTab, _font, HBORDER, ypos, fwidth, lineHeight, items, From b1f28a83d1c7d88472c6f316bfa6b810d1fe145d Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sun, 4 Oct 2020 21:55:47 +0200 Subject: [PATCH 059/263] Add plain video mode. --- src/emucore/Console.cxx | 11 ++++++++++- src/emucore/Settings.cxx | 2 ++ src/emucore/TIASurface.cxx | 18 +++++++++++++++--- src/emucore/TIASurface.hxx | 16 ++++++++++------ 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 9cf1b57d2..04040c597 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -622,11 +622,20 @@ FBInitStatus Console::initializeVideo(bool full) if(full) { + uInt32 width, height; + if (myOSystem.settings().getBool("plain-video")) { + width = 2 * myTIA->width(); + height = myTIA->height(); + } else { + width = TIAConstants::viewableWidth; + height = TIAConstants::viewableHeight; + } + bool devSettings = myOSystem.settings().getBool("dev.settings"); const string& title = string("Stella ") + STELLA_VERSION + ": \"" + myProperties.get(PropType::Cart_Name) + "\""; fbstatus = myOSystem.frameBuffer().createDisplay(title, FrameBuffer::BufferType::Emulator, - TIAConstants::viewableWidth, TIAConstants::viewableHeight, false); + width, height, false); if(fbstatus != FBInitStatus::Success) return fbstatus; diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index e9d0de8c8..595ab35ec 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -48,6 +48,7 @@ Settings::Settings() setPermanent("windowedpos", Common::Point(50, 50)); setPermanent("display", 0); setPermanent("uimessages", "true"); + setTemporary("plain-video", "false"); // TIA specific options setPermanent("tia.inter", "false"); setPermanent("tia.zoom", "3"); @@ -417,6 +418,7 @@ void Settings::usage() const << " -palette \n" + << " -plain-video <1|0> Disable all scaling and postprocessing\n" << " -pal.phase_ntsc Phase shift for NTSC 'custom' palette\n" << " -pal.phase_pal Phase shift for PAL 'custom' palette\n" << " -pal.hue <-1.0 - 1.0> Adjust hue for current palette\n" diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx index 781ca203a..a6f11c956 100644 --- a/src/emucore/TIASurface.cxx +++ b/src/emucore/TIASurface.cxx @@ -56,7 +56,9 @@ TIASurface::TIASurface(OSystem& system) myTiaSurface = myFB.allocateSurface( AtariNTSC::outWidth(TIAConstants::frameBufferWidth), TIAConstants::frameBufferHeight, - interpolationModeFromSettings(myOSystem.settings()) + plainVideoEnabled() + ? FrameBuffer::ScalingInterpolation::none + : interpolationModeFromSettings(myOSystem.settings()) ); // Generate scanline data, and a pre-defined scanline surface @@ -276,6 +278,8 @@ uInt32 TIASurface::enableScanlines(int change) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIASurface::enablePhosphor(bool enable, int blend) { + enable = enable && !plainVideoEnabled(); + if(myPhosphorHandler.initialize(enable, blend)) { myFilter = Filter(enable ? uInt8(myFilter) | 0x01 : uInt8(myFilter) & 0x10); @@ -286,6 +290,8 @@ void TIASurface::enablePhosphor(bool enable, int blend) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIASurface::enableNTSC(bool enable) { + enable = enable && !plainVideoEnabled(); + myFilter = Filter(enable ? uInt8(myFilter) | 0x10 : uInt8(myFilter) & 0x01); uInt32 surfaceWidth = enable ? @@ -299,7 +305,7 @@ void TIASurface::enableNTSC(bool enable) mySLineSurface->setSrcSize(1, 2 * myTIA->height()); - myScanlinesEnabled = myOSystem.settings().getInt("tv.scanlines") > 0; + myScanlinesEnabled = !plainVideoEnabled() && myOSystem.settings().getInt("tv.scanlines") > 0; FBSurface::Attributes& sl_attr = mySLineSurface->attributes(); sl_attr.blending = myScanlinesEnabled; sl_attr.blendalpha = myOSystem.settings().getInt("tv.scanlines"); @@ -311,8 +317,9 @@ void TIASurface::enableNTSC(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string TIASurface::effectsInfo() const { - const FBSurface::Attributes& attr = mySLineSurface->attributes(); + if (plainVideoEnabled()) return "plain video mode"; + const FBSurface::Attributes& attr = mySLineSurface->attributes(); ostringstream buf; switch(myFilter) { @@ -515,3 +522,8 @@ void TIASurface::updateSurfaceSettings() interpolationModeFromSettings(myOSystem.settings()) ); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool TIASurface::plainVideoEnabled() const { + return myOSystem.settings().getBool("plain-video"); +} diff --git a/src/emucore/TIASurface.hxx b/src/emucore/TIASurface.hxx index 2b6213785..a8c17bda4 100644 --- a/src/emucore/TIASurface.hxx +++ b/src/emucore/TIASurface.hxx @@ -183,13 +183,10 @@ class TIASurface */ uInt32 averageBuffers(uInt32 bufOfs); + // Is plain video mode enabled? + bool plainVideoEnabled() const; + private: - OSystem& myOSystem; - FrameBuffer& myFB; - TIA* myTIA{nullptr}; - - shared_ptr myTiaSurface, mySLineSurface, myBaseTiaSurface; - // Enumeration created such that phosphor off/on is in LSB, // and Blargg off/on is in MSB enum class Filter: uInt8 { @@ -200,6 +197,13 @@ class TIASurface }; Filter myFilter{Filter::Normal}; + private: + OSystem& myOSystem; + FrameBuffer& myFB; + TIA* myTIA{nullptr}; + + shared_ptr myTiaSurface, mySLineSurface, myBaseTiaSurface; + // NTSC object to use in TIA rendering mode NTSCFilter myNTSCFilter; From c003d888132ce77f352240275fffac223b48e650 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 5 Oct 2020 14:26:11 +0200 Subject: [PATCH 060/263] added doc for plain video mode renamed plain video mode option --- Changes.txt | 5 +- docs/index.html | 155 +++++++++++++++++++------------------ src/emucore/Console.cxx | 2 +- src/emucore/Settings.cxx | 4 +- src/emucore/TIASurface.cxx | 4 +- 5 files changed, 89 insertions(+), 81 deletions(-) diff --git a/Changes.txt b/Changes.txt index 154bb8440..27ba6e9c1 100644 --- a/Changes.txt +++ b/Changes.txt @@ -37,7 +37,7 @@ are no longer corrupted/cut off. This includes properly supporting the 2600-daptor II, which is flashable to an AVox-USB converter. - * The serial port to use for an AtariVox-USB adaptor is now autodetected. + * Added auto-detection of the serial port used for an AtariVox-USB adaptor. * Added QuadTari controller support. @@ -51,11 +51,14 @@ * Added another oddball TIA glitch option for delayed background color. + * Added option to disable all scaling and postprocessing. + * Replaced "Re-disassemble" with "Disassemble @ current line" in debugger. * Fixed bug when taking fullscreen snapshots; the dimensions were sometimes cut off. + -Have fun! diff --git a/docs/index.html b/docs/index.html index b8ead55cb..e5b9be777 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2182,97 +2182,97 @@ shown. - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - + + + @@ -2284,6 +2284,11 @@ + + + + + - - + + diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 3ae8c203e..04eafc58a 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -623,7 +623,7 @@ FBInitStatus Console::initializeVideo(bool full) if(full) { uInt32 width, height; - if (myOSystem.settings().getBool("tia.plain_video")) { + if (myOSystem.settings().getBool("tia.correct_aspect")) { width = 2 * myTIA->width(); height = myTIA->height(); } else { diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 80b1d67e1..6f5dd951a 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -835,7 +835,8 @@ void FrameBuffer::setPauseDelay() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -shared_ptr FrameBuffer::allocateSurface(int w, int h, ScalingInterpolation interpolation, const uInt32* data) +shared_ptr FrameBuffer::allocateSurface(int w, int h, ScalingInterpolation interpolation, + const uInt32* data) { // Add new surface to the list mySurfaceList.push_back(createSurface(w, h, interpolation, data)); diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index f3f1ef61b..083b97467 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -57,7 +57,7 @@ Settings::Settings() setPermanent("tia.fs_overscan", "0"); setPermanent("tia.vsizeadjust", 0); setPermanent("tia.dbgcolors", "roygpb"); - setTemporary("tia.plain_video", "false"); + setTemporary("tia.correct_aspect", "true"); // Palette options setPermanent("palette", PaletteHandler::SETTING_STANDARD); setPermanent("pal.phase_ntsc", "26.2"); @@ -454,7 +454,7 @@ void Settings::usage() const << " -tia.fs_overscan <0-10> Add overscan to TIA image in fullscreen mode\n" << " -tia.dbgcolors Debug colors to use for each object (see manual\n" << " for description)\n" - << " -tia.plain_video <1|0> Disable all scaling and postprocessing\n" + << " -tia.correct_aspect <1|0> Enable aspect correct scaling\n" << endl << " -tv.filter <0-5> Set TV effects off (0) or to specified mode\n" << " (1-5)\n" diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx index a9cca5795..2a2cd0327 100644 --- a/src/emucore/TIASurface.cxx +++ b/src/emucore/TIASurface.cxx @@ -56,7 +56,7 @@ TIASurface::TIASurface(OSystem& system) myTiaSurface = myFB.allocateSurface( AtariNTSC::outWidth(TIAConstants::frameBufferWidth), TIAConstants::frameBufferHeight, - plainVideoEnabled() + !correctAspect() ? FrameBuffer::ScalingInterpolation::none : interpolationModeFromSettings(myOSystem.settings()) ); @@ -278,8 +278,6 @@ uInt32 TIASurface::enableScanlines(int change) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIASurface::enablePhosphor(bool enable, int blend) { - enable = enable && !plainVideoEnabled(); - if(myPhosphorHandler.initialize(enable, blend)) { myFilter = Filter(enable ? uInt8(myFilter) | 0x01 : uInt8(myFilter) & 0x10); @@ -290,8 +288,6 @@ void TIASurface::enablePhosphor(bool enable, int blend) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIASurface::enableNTSC(bool enable) { - enable = enable && !plainVideoEnabled(); - myFilter = Filter(enable ? uInt8(myFilter) | 0x10 : uInt8(myFilter) & 0x01); uInt32 surfaceWidth = enable ? @@ -305,7 +301,7 @@ void TIASurface::enableNTSC(bool enable) mySLineSurface->setSrcSize(1, 2 * myTIA->height()); - myScanlinesEnabled = !plainVideoEnabled() && myOSystem.settings().getInt("tv.scanlines") > 0; + myScanlinesEnabled = myOSystem.settings().getInt("tv.scanlines") > 0; FBSurface::Attributes& sl_attr = mySLineSurface->attributes(); sl_attr.blending = myScanlinesEnabled; sl_attr.blendalpha = myOSystem.settings().getInt("tv.scanlines"); @@ -317,10 +313,9 @@ void TIASurface::enableNTSC(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string TIASurface::effectsInfo() const { - if (plainVideoEnabled()) return "Plain video mode"; - const FBSurface::Attributes& attr = mySLineSurface->attributes(); ostringstream buf; + switch(myFilter) { case Filter::Normal: @@ -333,12 +328,12 @@ string TIASurface::effectsInfo() const buf << myNTSCFilter.getPreset() << ", scanlines=" << attr.blendalpha; break; case Filter::BlarggPhosphor: - buf << myNTSCFilter.getPreset() << ", phosphor, scanlines=" - << attr.blendalpha; + buf << myNTSCFilter.getPreset() << ", phosphor, scanlines=" << attr.blendalpha; break; } buf << ", inter=" << (myOSystem.settings().getBool("tia.inter") ? "enabled" : "disabled"); + buf << ", aspect correction=" << (correctAspect() ? "enabled" : "disabled"); return buf.str(); } @@ -524,6 +519,6 @@ void TIASurface::updateSurfaceSettings() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool TIASurface::plainVideoEnabled() const { - return myOSystem.settings().getBool("tia.plain_video"); +bool TIASurface::correctAspect() const { + return myOSystem.settings().getBool("tia.correct_aspect"); } diff --git a/src/emucore/TIASurface.hxx b/src/emucore/TIASurface.hxx index a8c17bda4..dd38b2de5 100644 --- a/src/emucore/TIASurface.hxx +++ b/src/emucore/TIASurface.hxx @@ -184,7 +184,7 @@ class TIASurface uInt32 averageBuffers(uInt32 bufOfs); // Is plain video mode enabled? - bool plainVideoEnabled() const; + bool correctAspect() const; private: // Enumeration created such that phosphor off/on is in LSB, From a83c794d1b183d82e6468ce9536b3ca372232e0a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 5 Oct 2020 16:18:34 -0230 Subject: [PATCH 062/263] Startup bank randomization is now disabled for BUS and DPC+ too (similar reasoning as for CDF). --- Changes.txt | 4 +++- src/emucore/CartBUS.hxx | 7 +++++++ src/emucore/CartCDF.hxx | 8 ++++---- src/emucore/CartDPCPlus.hxx | 7 +++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Changes.txt b/Changes.txt index 0276a60e7..dee6dc44a 100644 --- a/Changes.txt +++ b/Changes.txt @@ -53,12 +53,14 @@ * Added option to disable aspect correct scaling. + * Bankswitching schemes BUS, DPC+ and CDFx now work when startup bank + randomization is enabled (these schemes now ignore that setting). + * Replaced "Re-disassemble" with "Disassemble @ current line" in debugger. * Fixed bug when taking fullscreen snapshots; the dimensions were sometimes cut off. - -Have fun! diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 054324353..86947ed19 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -181,6 +181,13 @@ class CartridgeBUS : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: + /** + Checks if startup bank randomization is enabled. For this scheme, + randomization is not supported, since the ARM code is always in a + pre-defined bank, and we *must* start from there. + */ + bool randomStartBank() const override { return false; } + /** Sets the initial state of the DPC pointers and RAM */ diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 812792f3f..e02b8a83d 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -177,7 +177,7 @@ class CartridgeCDF : public Cartridge /** Size of SRAM (RAM) area in cart - */ + */ uInt32 ramSize() const; /** @@ -215,9 +215,9 @@ class CartridgeCDF : public Cartridge private: /** - Checks if startup bank randomization is enabled. - - @return Whether the startup bank(s) should be randomized + Checks if startup bank randomization is enabled. For this scheme, + randomization is not supported, since the ARM code is always in a + pre-defined bank, and we *must* start from there. */ bool randomStartBank() const override { return false; } diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 5c83da263..3cef0a47a 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -175,6 +175,13 @@ class CartridgeDPCPlus : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: + /** + Checks if startup bank randomization is enabled. For this scheme, + randomization is not supported, since the ARM code is always in a + pre-defined bank, and we *must* start from there. + */ + bool randomStartBank() const override { return false; } + /** Sets the initial state of the DPC pointers and RAM */ From 0c571080ea1d1b11595b8dbf0d1df6e0c40f23e6 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 5 Oct 2020 16:48:57 -0230 Subject: [PATCH 063/263] Added debugger pseudo-registers to detect timer access on wraparound (fixes #606). --- Changes.txt | 4 + src/debugger/Debugger.cxx | 29 +- src/debugger/Debugger.hxx | 2 +- src/debugger/DebuggerExpressions.hxx | 13 + src/debugger/RiotDebug.cxx | 12 + src/debugger/RiotDebug.hxx | 7 + src/emucore/M6532.cxx | 11 +- src/emucore/M6532.hxx | 4 + src/yacc/YaccParser.cxx | 16 + src/yacc/YaccParser.hxx | 2 + src/yacc/stella.y | 3 + src/yacc/y.tab.c | 956 +++++++++++++++------------ src/yacc/y.tab.h | 70 +- 13 files changed, 659 insertions(+), 470 deletions(-) diff --git a/Changes.txt b/Changes.txt index dee6dc44a..270497e81 100644 --- a/Changes.txt +++ b/Changes.txt @@ -53,6 +53,10 @@ * Added option to disable aspect correct scaling. + * Added debugger pseudo-registers '_timwrapread' and '_timwrapwrite', + which are set when the RIOT timer is read/written on timer wraparound, + respectively. + * Bankswitching schemes BUS, DPC+ and CDFx now work when startup bank randomization is enabled (these schemes now ignore that setting). diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 315a45c3b..d5e56a98a 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -877,23 +877,26 @@ std::array Debugger::ourBuiltinFunctions = { { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Names are defined here, but processed in YaccParser -std::array Debugger::ourPseudoRegisters = { { +std::array Debugger::ourPseudoRegisters = { { // Debugger::PseudoRegister Debugger::ourPseudoRegisters[NUM_PSEUDO_REGS] = { - { "_bank", "Currently selected bank" }, - { "_cclocks", "Color clocks on current scanline" }, - { "_cycleshi", "Higher 32 bits of number of cycles since emulation started" }, - { "_cycleslo", "Lower 32 bits of number of cycles since emulation started" }, - { "_fcount", "Number of frames since emulation started" }, - { "_fcycles", "Number of cycles since frame started" }, - { "_icycles", "Number of cycles of last instruction" }, - { "_scan", "Current scanline count" }, - { "_scanend", "Scanline count at end of last frame" }, - { "_scycles", "Number of cycles in current scanline" }, - { "_vblank", "Whether vertical blank is enabled (1 or 0)" }, - { "_vsync", "Whether vertical sync is enabled (1 or 0)" } + { "_bank", "Currently selected bank" }, + { "_cclocks", "Color clocks on current scanline" }, + { "_cycleshi", "Higher 32 bits of number of cycles since emulation started" }, + { "_cycleslo", "Lower 32 bits of number of cycles since emulation started" }, + { "_fcount", "Number of frames since emulation started" }, + { "_fcycles", "Number of cycles since frame started" }, + { "_icycles", "Number of cycles of last instruction" }, + { "_scan", "Current scanline count" }, + { "_scanend", "Scanline count at end of last frame" }, + { "_scycles", "Number of cycles in current scanline" }, + { "_timwrapread", "Timer read wrapped on this cycle" }, + { "_timwrapwrite", "Timer write wrapped on this cycle" }, + { "_vblank", "Whether vertical blank is enabled (1 or 0)" }, + { "_vsync", "Whether vertical sync is enabled (1 or 0)" } // CPU address access functions: /*{ "_lastread", "last CPU read address" }, { "_lastwrite", "last CPU write address" }, { "__lastbaseread", "last CPU read base address" }, { "__lastbasewrite", "last CPU write base address" }*/ } }; +// diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 6435a6d1a..d594820c6 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -363,7 +363,7 @@ class Debugger : public DialogContainer string name, help; }; static std::array ourBuiltinFunctions; - static std::array ourPseudoRegisters; + static std::array ourPseudoRegisters; private: // rewind/unwind n states diff --git a/src/debugger/DebuggerExpressions.hxx b/src/debugger/DebuggerExpressions.hxx index 6c422fc5a..060411c09 100644 --- a/src/debugger/DebuggerExpressions.hxx +++ b/src/debugger/DebuggerExpressions.hxx @@ -23,6 +23,7 @@ #include "bspf.hxx" #include "CartDebug.hxx" #include "CpuDebug.hxx" +#include "RiotDebug.hxx" #include "TIADebug.hxx" #include "Debugger.hxx" #include "Expression.hxx" @@ -310,6 +311,18 @@ class ShiftRightExpression : public Expression { return myLHS->evaluate() >> myRHS->evaluate(); } }; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class RiotMethodExpression : public Expression +{ + public: + RiotMethodExpression(RiotMethod method) : Expression(), myMethod(std::mem_fn(method)) { } + Int32 evaluate() const override + { return myMethod(Debugger::debugger().riotDebug()); } + + private: + std::function myMethod; +}; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class TiaMethodExpression : public Expression { diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx index 4484944aa..7d4bc6c0a 100644 --- a/src/debugger/RiotDebug.cxx +++ b/src/debugger/RiotDebug.cxx @@ -235,6 +235,18 @@ Int32 RiotDebug::timDivider() const return mySystem.m6532().myDivider; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int RiotDebug::timWrappedOnRead() const +{ + return mySystem.m6532().myTimWrappedOnRead; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int RiotDebug::timWrappedOnWrite() const +{ + return mySystem.m6532().myTimWrappedOnWrite; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool RiotDebug::diffP0(int newVal) { diff --git a/src/debugger/RiotDebug.hxx b/src/debugger/RiotDebug.hxx index b86968684..30f4defe8 100644 --- a/src/debugger/RiotDebug.hxx +++ b/src/debugger/RiotDebug.hxx @@ -22,6 +22,10 @@ class M6532; class Debugger; class RiotDebug; +// Function type for RiotDebug instance methods +class RiotDebug; +using RiotMethod = int (RiotDebug::*)() const; + #include "DebuggerSystem.hxx" class RiotState : public DebuggerState @@ -75,6 +79,9 @@ class RiotDebug : public DebuggerSystem Int32 timClocks() const; Int32 intimClocks() const; Int32 timDivider() const; + /* Debugger pseudo-registers for timer accesses */ + int timWrappedOnRead() const; + int timWrappedOnWrite() const; /* Console switches */ bool diffP0(int newVal = -1); diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx index 18f950e62..64df91377 100644 --- a/src/emucore/M6532.cxx +++ b/src/emucore/M6532.cxx @@ -145,6 +145,10 @@ void M6532::updateEmulation() } myLastCycle = mySystem->cycles(); + +#ifdef DEBUGGER_SUPPORT + myTimWrappedOnRead = myTimWrappedOnWrite = false; +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -220,7 +224,9 @@ uInt8 M6532::peek(uInt16 addr) { // Timer Flag is always cleared when accessing INTIM if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit; - + #ifdef DEBUGGER_SUPPORT + myTimWrappedOnRead = myWrappedThisCycle; + #endif return myTimer; } @@ -316,6 +322,9 @@ void M6532::setTimerRegister(uInt8 value, uInt8 interval) // Interrupt timer flag is cleared (and invalid) when writing to the timer if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit; +#ifdef DEBUGGER_SUPPORT + myTimWrappedOnWrite = myWrappedThisCycle; +#endif mySetTimerCycle = mySystem->cycles(); } diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index d35877ab8..650745811 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -250,6 +250,10 @@ class M6532 : public Device std::array myIOAccessCounter; // The array used to skip the first ZP access tracking std::array myZPAccessDelay; + + // Detect timer being accessed on wraparound + bool myTimWrappedOnRead{false}; + bool myTimWrappedOnWrite{false}; #endif // DEBUGGER_SUPPORT private: diff --git a/src/yacc/YaccParser.cxx b/src/yacc/YaccParser.cxx index 8bc728ca0..4de3c965f 100644 --- a/src/yacc/YaccParser.cxx +++ b/src/yacc/YaccParser.cxx @@ -228,6 +228,18 @@ CpuMethod getCpuSpecial(char* ch) return nullptr; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// special methods that get RIOT internal state +RiotMethod getRiotSpecial(char* ch) +{ + if(BSPF::equalsIgnoreCase(ch, "_timwrapread")) + return &RiotDebug::timWrappedOnRead; + else if(BSPF::equalsIgnoreCase(ch, "_timwrapwrite")) + return &RiotDebug::timWrappedOnWrite; + else + return nullptr; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // special methods that get TIA internal state TiaMethod getTiaSpecial(char* ch) @@ -281,6 +293,7 @@ int yylex() { { CartMethod cartMeth; CpuMethod cpuMeth; + RiotMethod riotMeth; TiaMethod tiaMeth; char *bufp = idbuf; @@ -309,6 +322,9 @@ int yylex() { } else if( (cartMeth = getCartSpecial(idbuf)) ) { yylval.cartMethod = cartMeth; return CART_METHOD; + } else if( (riotMeth = getRiotSpecial(idbuf)) ) { + yylval.riotMethod = riotMeth; + return RIOT_METHOD; } else if( (tiaMeth = getTiaSpecial(idbuf)) ) { yylval.tiaMethod = tiaMeth; return TIA_METHOD; diff --git a/src/yacc/YaccParser.hxx b/src/yacc/YaccParser.hxx index 0ce067c27..050d4a7e5 100644 --- a/src/yacc/YaccParser.hxx +++ b/src/yacc/YaccParser.hxx @@ -21,6 +21,7 @@ #include "Expression.hxx" #include "CartDebug.hxx" #include "CpuDebug.hxx" +#include "RiotDebug.hxx" #include "TIADebug.hxx" #include "bspf.hxx" @@ -37,6 +38,7 @@ namespace YaccParser CartMethod getCartSpecial(char* ch); CpuMethod getCpuSpecial(char* ch); + RiotMethod getRiotSpecial(char* ch); TiaMethod getTiaSpecial(char* ch); } diff --git a/src/yacc/stella.y b/src/yacc/stella.y index 4f13cb6d4..6836d00cd 100644 --- a/src/yacc/stella.y +++ b/src/yacc/stella.y @@ -30,6 +30,7 @@ void yyerror(const char *e) { char* Equate; CartMethod cartMethod; CpuMethod cpuMethod; + RiotMethod riotMethod; TiaMethod tiaMethod; Expression* exp; char* DefinedFunction; @@ -41,6 +42,7 @@ void yyerror(const char *e) { %token EQUATE %token CART_METHOD %token CPU_METHOD +%token RIOT_METHOD %token TIA_METHOD %token FUNCTION @@ -97,6 +99,7 @@ expression: expression '+' expression { if(DEBUG_EXP) fprintf(stderr, " +"); $$ | EQUATE { if(DEBUG_EXP) fprintf(stderr, "equate %s", $1); $$ = new EquateExpression($1); lastExp = $$; } | CPU_METHOD { if(DEBUG_EXP) fprintf(stderr, " (CpuMethod)"); $$ = new CpuMethodExpression($1); lastExp = $$; } | CART_METHOD { if(DEBUG_EXP) fprintf(stderr, " (CartMethod)"); $$ = new CartMethodExpression($1); lastExp = $$; } + | RIOT_METHOD { if(DEBUG_EXP) fprintf(stderr, " (RiotMethod)"); $$ = new RiotMethodExpression($1); lastExp = $$; } | TIA_METHOD { if(DEBUG_EXP) fprintf(stderr, " (TiaMethod)"); $$ = new TiaMethodExpression($1); lastExp = $$; } | FUNCTION { if(DEBUG_EXP) fprintf(stderr, " (DefinedFunction)"); $$ = new FunctionExpression($1); lastExp = $$; } | ERR { if(DEBUG_EXP) fprintf(stderr, " ERR: "); yyerror((const char*)"Invalid label or constant"); return 1; } diff --git a/src/yacc/y.tab.c b/src/yacc/y.tab.c index fcd1b4c72..ed1d99c58 100644 --- a/src/yacc/y.tab.c +++ b/src/yacc/y.tab.c @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.5.1. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +41,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.5.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -61,8 +65,8 @@ -/* Copy the first part of user declarations. */ -#line 1 "stella.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 1 "stella.y" #include @@ -89,13 +93,26 @@ void yyerror(const char *e) { } -#line 93 "y.tab.c" /* yacc.c:339 */ +#line 97 "y.tab.c" -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else -# define YY_NULLPTR 0 +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) # endif # endif @@ -107,8 +124,8 @@ void yyerror(const char *e) { # define YYERROR_VERBOSE 0 #endif -/* In a future release of Bison, this section will be replaced - by #include "y.tab.h". */ +/* Use api.header.include to #include this header + instead of duplicating it here. */ #ifndef YY_YY_Y_TAB_H_INCLUDED # define YY_YY_Y_TAB_H_INCLUDED /* Debug traces. */ @@ -129,19 +146,20 @@ extern int yydebug; EQUATE = 260, CART_METHOD = 261, CPU_METHOD = 262, - TIA_METHOD = 263, - FUNCTION = 264, - LOG_OR = 265, - LOG_AND = 266, - LOG_NOT = 267, - SHR = 268, - SHL = 269, - GTE = 270, - LTE = 271, - NE = 272, - EQ = 273, - DEREF = 274, - UMINUS = 275 + RIOT_METHOD = 263, + TIA_METHOD = 264, + FUNCTION = 265, + LOG_OR = 266, + LOG_AND = 267, + LOG_NOT = 268, + SHR = 269, + SHL = 270, + GTE = 271, + LTE = 272, + NE = 273, + EQ = 274, + DEREF = 275, + UMINUS = 276 }; #endif /* Tokens. */ @@ -150,38 +168,39 @@ extern int yydebug; #define EQUATE 260 #define CART_METHOD 261 #define CPU_METHOD 262 -#define TIA_METHOD 263 -#define FUNCTION 264 -#define LOG_OR 265 -#define LOG_AND 266 -#define LOG_NOT 267 -#define SHR 268 -#define SHL 269 -#define GTE 270 -#define LTE 271 -#define NE 272 -#define EQ 273 -#define DEREF 274 -#define UMINUS 275 +#define RIOT_METHOD 263 +#define TIA_METHOD 264 +#define FUNCTION 265 +#define LOG_OR 266 +#define LOG_AND 267 +#define LOG_NOT 268 +#define SHR 269 +#define SHL 270 +#define GTE 271 +#define LTE 272 +#define NE 273 +#define EQ 274 +#define DEREF 275 +#define UMINUS 276 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - union YYSTYPE { -#line 28 "stella.y" /* yacc.c:355 */ +#line 28 "stella.y" int val; char* Equate; CartMethod cartMethod; CpuMethod cpuMethod; + RiotMethod riotMethod; TiaMethod tiaMethod; Expression* exp; char* DefinedFunction; -#line 183 "y.tab.c" /* yacc.c:355 */ -}; +#line 202 "y.tab.c" +}; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 @@ -194,36 +213,81 @@ int yyparse (void); #endif /* !YY_YY_Y_TAB_H_INCLUDED */ -/* Copy the second part of user declarations. */ -#line 200 "y.tab.c" /* yacc.c:358 */ #ifdef short # undef short #endif -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif #endif -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; #else -typedef unsigned short int yytype_uint16; +typedef short yytype_int16; #endif -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; #else -typedef short int yytype_int16; +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif #endif #ifndef YYSIZE_T @@ -231,15 +295,27 @@ typedef short int yytype_int16; # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + +/* Stored state numbers (used for stacks). */ +typedef yytype_int8 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS @@ -253,30 +329,19 @@ typedef short int yytype_int16; # endif #endif -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else -# define YY_ATTRIBUTE(Spec) /* empty */ +# define YY_ATTRIBUTE_PURE # endif #endif -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - #ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# define YY_ATTRIBUTE_UNUSED # endif #endif @@ -287,13 +352,13 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value @@ -306,6 +371,20 @@ typedef short int yytype_int16; # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) #if ! defined yyoverflow || YYERROR_VERBOSE @@ -382,17 +461,17 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; + yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 @@ -405,11 +484,11 @@ union yyalloc # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ - YYSIZE_T yynewbytes; \ + YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) @@ -421,12 +500,12 @@ union yyalloc # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ - YYSIZE_T yyi; \ + YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ @@ -436,44 +515,45 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 26 +#define YYFINAL 27 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 227 +#define YYLAST 228 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 38 +#define YYNTOKENS 39 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 3 /* YYNRULES -- Number of rules. */ -#define YYNRULES 36 +#define YYNRULES 37 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 67 +#define YYNSTATES 68 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 275 +#define YYMAXUTOK 276 + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint8 yytranslate[] = + as returned by yylex. */ +static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 33, 2, 2, 2, 14, 20, 2, - 35, 36, 12, 11, 2, 10, 2, 13, 2, 2, + 2, 2, 2, 34, 2, 2, 2, 15, 21, 2, + 36, 37, 13, 12, 2, 11, 2, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 23, 2, 24, 2, 34, 2, 2, 2, 2, 2, + 24, 2, 25, 2, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 31, 2, 37, 19, 2, 2, 2, 2, 2, + 2, 32, 2, 38, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 18, 2, 32, 2, 2, 2, + 2, 2, 2, 2, 19, 2, 33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -487,18 +567,18 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 15, 16, 17, 21, 22, - 25, 26, 27, 28, 29, 30 + 5, 6, 7, 8, 9, 10, 16, 17, 18, 22, + 23, 26, 27, 28, 29, 30, 31 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = +static const yytype_int8 yyrline[] = { - 0, 66, 66, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102 + 0, 68, 68, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105 }; #endif @@ -508,72 +588,73 @@ static const yytype_uint8 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "NUMBER", "ERR", "EQUATE", "CART_METHOD", - "CPU_METHOD", "TIA_METHOD", "FUNCTION", "'-'", "'+'", "'*'", "'/'", - "'%'", "LOG_OR", "LOG_AND", "LOG_NOT", "'|'", "'^'", "'&'", "SHR", "SHL", - "'<'", "'>'", "GTE", "LTE", "NE", "EQ", "DEREF", "UMINUS", "'['", "'~'", - "'!'", "'@'", "'('", "')'", "']'", "$accept", "statement", "expression", YY_NULLPTR + "CPU_METHOD", "RIOT_METHOD", "TIA_METHOD", "FUNCTION", "'-'", "'+'", + "'*'", "'/'", "'%'", "LOG_OR", "LOG_AND", "LOG_NOT", "'|'", "'^'", "'&'", + "SHR", "SHL", "'<'", "'>'", "GTE", "LTE", "NE", "EQ", "DEREF", "UMINUS", + "'['", "'~'", "'!'", "'@'", "'('", "')'", "']'", "$accept", "statement", + "expression", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = +static const yytype_int16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 45, 43, 42, 47, 37, 265, 266, 267, 124, 94, - 38, 268, 269, 60, 62, 270, 271, 272, 273, 274, - 275, 91, 126, 33, 64, 40, 41, 93 + 265, 45, 43, 42, 47, 37, 266, 267, 268, 124, + 94, 38, 269, 270, 60, 62, 271, 272, 273, 274, + 275, 276, 91, 126, 33, 64, 40, 41, 93 }; # endif -#define YYPACT_NINF -15 +#define YYPACT_NINF (-16) -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-15))) +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF -1 +#define YYTABLE_NINF (-1) -#define yytable_value_is_error(Yytable_value) \ - (!!((Yytable_value) == (-1))) +#define yytable_value_is_error(Yyn) \ + ((Yyn) == YYTABLE_NINF) /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { - 35, -15, -15, -15, -15, -15, -15, -15, 35, 35, - 35, 35, 35, 35, 35, 35, 16, 116, -14, -14, - 187, 187, -14, -14, -14, 89, -15, 35, 35, 35, + 35, -16, -16, -16, -16, -16, -16, -16, -16, 35, + 35, 35, 35, 35, 35, 35, 35, 16, 116, -15, + -15, 187, 187, -15, -15, -15, 89, -16, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, -15, 136, 136, 150, - 150, 150, 164, 178, 29, 29, -13, 196, 196, 187, - 187, 187, 187, 187, 187, 61, -15 + 35, 35, 35, 35, 35, 35, 35, -16, 136, 136, + 150, 150, 150, 164, 178, 29, 29, -14, 196, 196, + 187, 187, 187, 187, 187, 187, 61, -16 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ -static const yytype_uint8 yydefact[] = +static const yytype_int8 yydefact[] = { - 0, 30, 36, 31, 33, 32, 34, 35, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 21, 24, - 26, 27, 22, 23, 25, 0, 1, 0, 0, 0, + 0, 30, 37, 31, 33, 32, 34, 35, 36, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 21, + 24, 26, 27, 22, 23, 25, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 28, 4, 3, 5, - 6, 7, 19, 20, 9, 10, 8, 17, 18, 11, - 12, 13, 14, 15, 16, 0, 29 + 0, 0, 0, 0, 0, 0, 0, 28, 4, 3, + 5, 6, 7, 19, 20, 9, 10, 8, 17, 18, + 11, 12, 13, 14, 15, 16, 0, 29 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -15, -15, -8 + -16, -16, -9 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 16, 17 + -1, 17, 18 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -581,87 +662,87 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { - 18, 19, 20, 21, 22, 23, 24, 25, 37, 38, - 39, 40, 41, 42, 43, 44, 26, 45, 45, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 1, 2, - 3, 4, 5, 6, 7, 8, 0, 9, 0, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 10, 11, - 45, 0, 0, 0, 0, 0, 0, 12, 13, 14, - 15, 27, 28, 29, 30, 31, 32, 33, 0, 34, + 19, 20, 21, 22, 23, 24, 25, 26, 38, 39, + 40, 41, 42, 43, 44, 45, 27, 46, 46, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 0, 10, 0, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 11, + 12, 46, 0, 0, 0, 0, 0, 0, 13, 14, + 15, 16, 28, 29, 30, 31, 32, 33, 34, 0, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 0, 0, 45, 0, 0, 0, 0, 0, 66, 27, - 28, 29, 30, 31, 32, 33, 0, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 0, 0, - 45, 0, 0, 0, 0, 46, 27, 28, 29, 30, - 31, 32, 33, 0, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 0, 0, 45, 29, 30, - 31, 32, 33, 0, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 32, 33, 45, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 0, - 33, 45, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 0, 0, 45, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 0, 0, 45, - -1, -1, -1, -1, -1, -1, 0, 0, 45, 39, - 40, 41, 42, 43, 44, 0, 0, 45 + 45, 0, 0, 46, 0, 0, 0, 0, 0, 67, + 28, 29, 30, 31, 32, 33, 34, 0, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, + 0, 46, 0, 0, 0, 0, 47, 28, 29, 30, + 31, 32, 33, 34, 0, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 0, 0, 46, 30, + 31, 32, 33, 34, 0, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 33, 34, 46, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 0, 34, 46, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 0, 0, 46, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, + 46, -1, -1, -1, -1, -1, -1, 0, 0, 46, + 40, 41, 42, 43, 44, 45, 0, 0, 46 }; static const yytype_int8 yycheck[] = { - 8, 9, 10, 11, 12, 13, 14, 15, 21, 22, - 23, 24, 25, 26, 27, 28, 0, 31, 31, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 3, 4, - 5, 6, 7, 8, 9, 10, -1, 12, -1, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 23, 24, - 31, -1, -1, -1, -1, -1, -1, 32, 33, 34, - 35, 10, 11, 12, 13, 14, 15, 16, -1, 18, + 9, 10, 11, 12, 13, 14, 15, 16, 22, 23, + 24, 25, 26, 27, 28, 29, 0, 32, 32, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 3, 4, + 5, 6, 7, 8, 9, 10, 11, -1, 13, -1, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 24, + 25, 32, -1, -1, -1, -1, -1, -1, 33, 34, + 35, 36, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - -1, -1, 31, -1, -1, -1, -1, -1, 37, 10, - 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, -1, -1, - 31, -1, -1, -1, -1, 36, 10, 11, 12, 13, - 14, 15, 16, -1, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, -1, -1, 31, 12, 13, - 14, 15, 16, -1, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 15, 16, 31, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, -1, - 16, 31, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, -1, -1, 31, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, -1, -1, 31, - 23, 24, 25, 26, 27, 28, -1, -1, 31, 23, - 24, 25, 26, 27, 28, -1, -1, 31 + 29, -1, -1, 32, -1, -1, -1, -1, -1, 38, + 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, -1, + -1, 32, -1, -1, -1, -1, 37, 11, 12, 13, + 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, -1, -1, 32, 13, + 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 16, 17, 32, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + -1, 17, 32, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, -1, -1, 32, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, -1, -1, + 32, 24, 25, 26, 27, 28, 29, -1, -1, 32, + 24, 25, 26, 27, 28, 29, -1, -1, 32 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = +static const yytype_int8 yystos[] = { - 0, 3, 4, 5, 6, 7, 8, 9, 10, 12, - 23, 24, 32, 33, 34, 35, 39, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 0, 10, 11, 12, - 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 31, 36, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 37 + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 13, 24, 25, 33, 34, 35, 36, 40, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 0, 11, 12, + 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 32, 37, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 38 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = +static const yytype_int8 yyr1[] = { - 0, 38, 39, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40 + 0, 39, 40, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = +static const yytype_int8 yyr2[] = { 0, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 4, - 1, 1, 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1 }; @@ -677,22 +758,22 @@ static const yytype_uint8 yyr2[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) /* Error token number */ #define YYTERROR 1 @@ -732,37 +813,39 @@ do { \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -771,7 +854,7 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) `------------------------------------------------------------------*/ static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -794,20 +877,20 @@ do { \ `------------------------------------------------*/ static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule) { - unsigned long int yylno = yyrline[yyrule]; + int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) + yystos[+yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] ); YYFPRINTF (stderr, "\n"); } @@ -851,13 +934,13 @@ int yydebug; # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ -static YYSIZE_T +static YYPTRDIFF_T yystrlen (const char *yystr) { - YYSIZE_T yylen; + YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; @@ -893,12 +976,12 @@ yystpcpy (char *yydest, const char *yysrc) backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ -static YYSIZE_T +static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { - YYSIZE_T yyn = 0; + YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) @@ -911,7 +994,10 @@ yytnamerr (char *yyres, const char *yystr) case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -926,10 +1012,10 @@ yytnamerr (char *yyres, const char *yystr) do_not_strip_quotes: ; } - if (! yyres) + if (yyres) + return yystpcpy (yyres, yystr) - yyres; + else return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; } # endif @@ -942,19 +1028,19 @@ yytnamerr (char *yyres, const char *yystr) *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + yy_state_t *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ + /* Actual size of YYARG. */ int yycount = 0; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then @@ -981,7 +1067,9 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, */ if (yytoken != YYEMPTY) { - int yyn = yypact[*yyssp]; + int yyn = yypact[+*yyssp]; + YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + yysize = yysize0; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { @@ -1006,11 +1094,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } yyarg[yycount++] = yytname[yyx]; { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + YYPTRDIFF_T yysize1 + = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } } } @@ -1022,6 +1111,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -1032,10 +1122,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + /* Don't count the "%s"s in the final size, but reserve room for + the terminator. */ + YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } if (*yymsg_alloc < yysize) @@ -1061,8 +1154,8 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } else { - yyp++; - yyformat++; + ++yyp; + ++yyformat; } } return 0; @@ -1105,7 +1198,7 @@ int yynerrs; int yyparse (void) { - int yystate; + yy_state_fast_t yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; @@ -1117,16 +1210,16 @@ yyparse (void) to reallocate them elsewhere. */ /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss; + yy_state_t *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; - YYSIZE_T yystacksize; + YYPTRDIFF_T yystacksize; int yyn; int yyresult; @@ -1140,7 +1233,7 @@ yyparse (void) /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; + YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) @@ -1161,46 +1254,54 @@ yyparse (void) yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; + /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; - yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYPTRDIFF_T yysize = yyssp - yyss + 1; -#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ + yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -1209,42 +1310,43 @@ yyparse (void) yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; + yy_state_t *yyss1 = yyss; union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; + /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ @@ -1294,15 +1396,13 @@ yybackup: /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END + /* Discard the shifted token. */ + yychar = YYEMPTY; goto yynewstate; @@ -1317,7 +1417,7 @@ yydefault: /*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -1337,218 +1437,225 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 2: -#line 66 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, "\ndone\n"); result.exp = (yyvsp[0].exp); } -#line 1344 "y.tab.c" /* yacc.c:1646 */ + case 2: +#line 68 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, "\ndone\n"); result.exp = (yyvsp[0].exp); } +#line 1444 "y.tab.c" break; case 3: -#line 69 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " +"); (yyval.exp) = new PlusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1350 "y.tab.c" /* yacc.c:1646 */ +#line 71 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " +"); (yyval.exp) = new PlusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1450 "y.tab.c" break; case 4: -#line 70 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " -"); (yyval.exp) = new MinusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1356 "y.tab.c" /* yacc.c:1646 */ +#line 72 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " -"); (yyval.exp) = new MinusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1456 "y.tab.c" break; case 5: -#line 71 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " *"); (yyval.exp) = new MultExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1362 "y.tab.c" /* yacc.c:1646 */ +#line 73 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " *"); (yyval.exp) = new MultExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1462 "y.tab.c" break; case 6: -#line 72 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " /"); (yyval.exp) = new DivExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1368 "y.tab.c" /* yacc.c:1646 */ +#line 74 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " /"); (yyval.exp) = new DivExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1468 "y.tab.c" break; case 7: -#line 73 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " %%"); (yyval.exp) = new ModExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1374 "y.tab.c" /* yacc.c:1646 */ +#line 75 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " %%"); (yyval.exp) = new ModExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1474 "y.tab.c" break; case 8: -#line 74 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " &"); (yyval.exp) = new BinAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1380 "y.tab.c" /* yacc.c:1646 */ +#line 76 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " &"); (yyval.exp) = new BinAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1480 "y.tab.c" break; case 9: -#line 75 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " |"); (yyval.exp) = new BinOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1386 "y.tab.c" /* yacc.c:1646 */ +#line 77 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " |"); (yyval.exp) = new BinOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1486 "y.tab.c" break; case 10: -#line 76 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " ^"); (yyval.exp) = new BinXorExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1392 "y.tab.c" /* yacc.c:1646 */ +#line 78 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " ^"); (yyval.exp) = new BinXorExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1492 "y.tab.c" break; case 11: -#line 77 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " <"); (yyval.exp) = new LessExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1398 "y.tab.c" /* yacc.c:1646 */ +#line 79 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " <"); (yyval.exp) = new LessExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1498 "y.tab.c" break; case 12: -#line 78 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " >"); (yyval.exp) = new GreaterExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1404 "y.tab.c" /* yacc.c:1646 */ +#line 80 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " >"); (yyval.exp) = new GreaterExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1504 "y.tab.c" break; case 13: -#line 79 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " >="); (yyval.exp) = new GreaterEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1410 "y.tab.c" /* yacc.c:1646 */ +#line 81 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " >="); (yyval.exp) = new GreaterEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1510 "y.tab.c" break; case 14: -#line 80 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " <="); (yyval.exp) = new LessEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1416 "y.tab.c" /* yacc.c:1646 */ +#line 82 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " <="); (yyval.exp) = new LessEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1516 "y.tab.c" break; case 15: -#line 81 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " !="); (yyval.exp) = new NotEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1422 "y.tab.c" /* yacc.c:1646 */ +#line 83 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " !="); (yyval.exp) = new NotEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1522 "y.tab.c" break; case 16: -#line 82 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " =="); (yyval.exp) = new EqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1428 "y.tab.c" /* yacc.c:1646 */ +#line 84 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " =="); (yyval.exp) = new EqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1528 "y.tab.c" break; case 17: -#line 83 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " >>"); (yyval.exp) = new ShiftRightExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1434 "y.tab.c" /* yacc.c:1646 */ +#line 85 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " >>"); (yyval.exp) = new ShiftRightExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1534 "y.tab.c" break; case 18: -#line 84 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " <<"); (yyval.exp) = new ShiftLeftExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1440 "y.tab.c" /* yacc.c:1646 */ +#line 86 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " <<"); (yyval.exp) = new ShiftLeftExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1540 "y.tab.c" break; case 19: -#line 85 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " ||"); (yyval.exp) = new LogOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1446 "y.tab.c" /* yacc.c:1646 */ +#line 87 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " ||"); (yyval.exp) = new LogOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1546 "y.tab.c" break; case 20: -#line 86 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " &&"); (yyval.exp) = new LogAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1452 "y.tab.c" /* yacc.c:1646 */ +#line 88 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " &&"); (yyval.exp) = new LogAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1552 "y.tab.c" break; case 21: -#line 87 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " U-"); (yyval.exp) = new UnaryMinusExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1458 "y.tab.c" /* yacc.c:1646 */ +#line 89 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " U-"); (yyval.exp) = new UnaryMinusExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1558 "y.tab.c" break; case 22: -#line 88 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " ~"); (yyval.exp) = new BinNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1464 "y.tab.c" /* yacc.c:1646 */ +#line 90 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " ~"); (yyval.exp) = new BinNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1564 "y.tab.c" break; case 23: -#line 89 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " !"); (yyval.exp) = new LogNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1470 "y.tab.c" /* yacc.c:1646 */ +#line 91 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " !"); (yyval.exp) = new LogNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1570 "y.tab.c" break; case 24: -#line 90 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " U*"); (yyval.exp) = new ByteDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1476 "y.tab.c" /* yacc.c:1646 */ +#line 92 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " U*"); (yyval.exp) = new ByteDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1576 "y.tab.c" break; case 25: -#line 91 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " U@"); (yyval.exp) = new WordDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1482 "y.tab.c" /* yacc.c:1646 */ +#line 93 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " U@"); (yyval.exp) = new WordDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1582 "y.tab.c" break; case 26: -#line 92 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " U<"); (yyval.exp) = new LoByteExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1488 "y.tab.c" /* yacc.c:1646 */ +#line 94 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " U<"); (yyval.exp) = new LoByteExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1588 "y.tab.c" break; case 27: -#line 93 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " U>"); (yyval.exp) = new HiByteExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } -#line 1494 "y.tab.c" /* yacc.c:1646 */ +#line 95 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " U>"); (yyval.exp) = new HiByteExpression((yyvsp[0].exp)); lastExp = (yyval.exp); } +#line 1594 "y.tab.c" break; case 28: -#line 94 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " ()"); (yyval.exp) = (yyvsp[-1].exp); lastExp = (yyval.exp); } -#line 1500 "y.tab.c" /* yacc.c:1646 */ +#line 96 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " ()"); (yyval.exp) = (yyvsp[-1].exp); lastExp = (yyval.exp); } +#line 1600 "y.tab.c" break; case 29: -#line 95 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " []"); (yyval.exp) = new ByteDerefOffsetExpression((yyvsp[-3].exp), (yyvsp[-1].exp)); lastExp = (yyval.exp); } -#line 1506 "y.tab.c" /* yacc.c:1646 */ +#line 97 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " []"); (yyval.exp) = new ByteDerefOffsetExpression((yyvsp[-3].exp), (yyvsp[-1].exp)); lastExp = (yyval.exp); } +#line 1606 "y.tab.c" break; case 30: -#line 96 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, "const %d", (yyvsp[0].val)); (yyval.exp) = new ConstExpression((yyvsp[0].val)); lastExp = (yyval.exp); } -#line 1512 "y.tab.c" /* yacc.c:1646 */ +#line 98 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, "const %d", (yyvsp[0].val)); (yyval.exp) = new ConstExpression((yyvsp[0].val)); lastExp = (yyval.exp); } +#line 1612 "y.tab.c" break; case 31: -#line 97 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, "equate %s", (yyvsp[0].Equate)); (yyval.exp) = new EquateExpression((yyvsp[0].Equate)); lastExp = (yyval.exp); } -#line 1518 "y.tab.c" /* yacc.c:1646 */ +#line 99 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, "equate %s", (yyvsp[0].Equate)); (yyval.exp) = new EquateExpression((yyvsp[0].Equate)); lastExp = (yyval.exp); } +#line 1618 "y.tab.c" break; case 32: -#line 98 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " (CpuMethod)"); (yyval.exp) = new CpuMethodExpression((yyvsp[0].cpuMethod)); lastExp = (yyval.exp); } -#line 1524 "y.tab.c" /* yacc.c:1646 */ +#line 100 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " (CpuMethod)"); (yyval.exp) = new CpuMethodExpression((yyvsp[0].cpuMethod)); lastExp = (yyval.exp); } +#line 1624 "y.tab.c" break; case 33: -#line 99 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " (CartMethod)"); (yyval.exp) = new CartMethodExpression((yyvsp[0].cartMethod)); lastExp = (yyval.exp); } -#line 1530 "y.tab.c" /* yacc.c:1646 */ +#line 101 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " (CartMethod)"); (yyval.exp) = new CartMethodExpression((yyvsp[0].cartMethod)); lastExp = (yyval.exp); } +#line 1630 "y.tab.c" break; case 34: -#line 100 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " (TiaMethod)"); (yyval.exp) = new TiaMethodExpression((yyvsp[0].tiaMethod)); lastExp = (yyval.exp); } -#line 1536 "y.tab.c" /* yacc.c:1646 */ +#line 102 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " (RiotMethod)"); (yyval.exp) = new RiotMethodExpression((yyvsp[0].riotMethod)); lastExp = (yyval.exp); } +#line 1636 "y.tab.c" break; case 35: -#line 101 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " (DefinedFunction)"); (yyval.exp) = new FunctionExpression((yyvsp[0].DefinedFunction)); lastExp = (yyval.exp); } -#line 1542 "y.tab.c" /* yacc.c:1646 */ +#line 103 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " (TiaMethod)"); (yyval.exp) = new TiaMethodExpression((yyvsp[0].tiaMethod)); lastExp = (yyval.exp); } +#line 1642 "y.tab.c" break; case 36: -#line 102 "stella.y" /* yacc.c:1646 */ - { if(DEBUG_EXP) fprintf(stderr, " ERR: "); yyerror((const char*)"Invalid label or constant"); return 1; } -#line 1548 "y.tab.c" /* yacc.c:1646 */ +#line 104 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " (DefinedFunction)"); (yyval.exp) = new FunctionExpression((yyvsp[0].DefinedFunction)); lastExp = (yyval.exp); } +#line 1648 "y.tab.c" + break; + + case 37: +#line 105 "stella.y" + { if(DEBUG_EXP) fprintf(stderr, " ERR: "); yyerror((const char*)"Invalid label or constant"); return 1; } +#line 1654 "y.tab.c" break; -#line 1552 "y.tab.c" /* yacc.c:1646 */ +#line 1658 "y.tab.c" + default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1573,14 +1680,13 @@ yyreduce: /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -1612,7 +1718,7 @@ yyerrlab: { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (!yymsg) { yymsg = yymsgbuf; @@ -1663,20 +1769,18 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ - /*YYPOPSTACK (yylen); + YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; - goto yyerrlab1;*/ + goto yyerrlab1; /*-------------------------------------------------------------. @@ -1730,6 +1834,7 @@ yyacceptlab: yyresult = 0; goto yyreturn; + /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ @@ -1737,6 +1842,7 @@ yyabortlab: yyresult = 1; goto yyreturn; + #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | @@ -1747,6 +1853,10 @@ yyexhaustedlab: /* Fall through. */ #endif + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -1763,7 +1873,7 @@ yyreturn: while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + yystos[+*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow @@ -1776,5 +1886,5 @@ yyreturn: #endif return yyresult; } -#line 104 "stella.y" /* yacc.c:1906 */ +#line 107 "stella.y" diff --git a/src/yacc/y.tab.h b/src/yacc/y.tab.h index d06bfd3eb..0356314bd 100644 --- a/src/yacc/y.tab.h +++ b/src/yacc/y.tab.h @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.5.1. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_YY_Y_TAB_H_INCLUDED # define YY_YY_Y_TAB_H_INCLUDED /* Debug traces. */ @@ -50,19 +54,20 @@ extern int yydebug; EQUATE = 260, CART_METHOD = 261, CPU_METHOD = 262, - TIA_METHOD = 263, - FUNCTION = 264, - LOG_OR = 265, - LOG_AND = 266, - LOG_NOT = 267, - SHR = 268, - SHL = 269, - GTE = 270, - LTE = 271, - NE = 272, - EQ = 273, - DEREF = 274, - UMINUS = 275 + RIOT_METHOD = 263, + TIA_METHOD = 264, + FUNCTION = 265, + LOG_OR = 266, + LOG_AND = 267, + LOG_NOT = 268, + SHR = 269, + SHL = 270, + GTE = 271, + LTE = 272, + NE = 273, + EQ = 274, + DEREF = 275, + UMINUS = 276 }; #endif /* Tokens. */ @@ -71,38 +76,39 @@ extern int yydebug; #define EQUATE 260 #define CART_METHOD 261 #define CPU_METHOD 262 -#define TIA_METHOD 263 -#define FUNCTION 264 -#define LOG_OR 265 -#define LOG_AND 266 -#define LOG_NOT 267 -#define SHR 268 -#define SHL 269 -#define GTE 270 -#define LTE 271 -#define NE 272 -#define EQ 273 -#define DEREF 274 -#define UMINUS 275 +#define RIOT_METHOD 263 +#define TIA_METHOD 264 +#define FUNCTION 265 +#define LOG_OR 266 +#define LOG_AND 267 +#define LOG_NOT 268 +#define SHR 269 +#define SHL 270 +#define GTE 271 +#define LTE 272 +#define NE 273 +#define EQ 274 +#define DEREF 275 +#define UMINUS 276 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - union YYSTYPE { -#line 28 "stella.y" /* yacc.c:1909 */ +#line 28 "stella.y" int val; char* Equate; CartMethod cartMethod; CpuMethod cpuMethod; + RiotMethod riotMethod; TiaMethod tiaMethod; Expression* exp; char* DefinedFunction; -#line 104 "y.tab.h" /* yacc.c:1909 */ -}; +#line 110 "y.tab.h" +}; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 From 90375c82f9afdc3955f4969219a9d2f80fe24d40 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 5 Oct 2020 23:05:33 +0200 Subject: [PATCH 064/263] made correct aspect ratio a permanent setting added hotkey for correct aspect ratio updated docs --- Changes.txt | 2 +- docs/graphics/options_video.png | Bin 3001 -> 3204 bytes docs/index.html | 19 +++++++++++++------ src/common/PKeyboardHandler.cxx | 1 + src/emucore/Console.cxx | 18 +++++++++++++++++- src/emucore/Console.hxx | 5 +++++ src/emucore/Event.hxx | 2 ++ src/emucore/EventHandler.cxx | 16 +++++++++++++--- src/emucore/EventHandler.hxx | 3 ++- src/emucore/Settings.cxx | 4 ++-- src/gui/VideoAudioDialog.cxx | 16 ++++++++++++++-- src/gui/VideoAudioDialog.hxx | 1 + 12 files changed, 71 insertions(+), 16 deletions(-) diff --git a/Changes.txt b/Changes.txt index 0276a60e7..7f93eb13d 100644 --- a/Changes.txt +++ b/Changes.txt @@ -51,7 +51,7 @@ * Added another oddball TIA glitch option for delayed background color. - * Added option to disable aspect correct scaling. + * Added option to disable aspect ratio correct scaling. * Replaced "Re-disassemble" with "Disassemble @ current line" in debugger. diff --git a/docs/graphics/options_video.png b/docs/graphics/options_video.png index 58654148ab3e6db654681c658c828eade4523b08..81db47827eeb61022d3813d39e896ea221c50f89 100644 GIT binary patch literal 3204 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 literal 3001 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 diff --git a/docs/index.html b/docs/index.html index a74fdc3a6..2fb930e39 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1394,6 +1394,11 @@ + + + + + @@ -2286,7 +2291,7 @@ - + @@ -3048,16 +3053,18 @@ diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index ab4f69906..5a1be8804 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -470,6 +470,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo {Event::VCenterIncrease, KBDK_PAGEDOWN, MOD3}, {Event::VSizeAdjustDecrease, KBDK_PAGEDOWN, KBDM_SHIFT | MOD3}, {Event::VSizeAdjustIncrease, KBDK_PAGEUP, KBDM_SHIFT | MOD3}, + {Event::ToggleCorrectAspectRatio, KBDK_C, KBDM_CTRL}, {Event::VolumeDecrease, KBDK_LEFTBRACKET, MOD3}, {Event::VolumeIncrease, KBDK_RIGHTBRACKET, MOD3}, {Event::SoundToggle, KBDK_RIGHTBRACKET, KBDM_CTRL}, diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 04eafc58a..a0bd2a25a 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -623,7 +623,7 @@ FBInitStatus Console::initializeVideo(bool full) if(full) { uInt32 width, height; - if (myOSystem.settings().getBool("tia.correct_aspect")) { + if (!myOSystem.settings().getBool("tia.correct_aspect")) { width = 2 * myTIA->width(); height = myTIA->height(); } else { @@ -737,6 +737,22 @@ void Console::changeVSizeAdjust(int direction) myOSystem.frameBuffer().showMessage("V-Size", val.str(), newAdjustVSize, -5, 5); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Console::toggleCorrectAspectRatio(bool toggle) +{ + bool enabled = myOSystem.settings().getBool("tia.correct_aspect"); + + if(toggle) + { + enabled = !enabled; + myOSystem.settings().setValue("tia.correct_aspect", enabled); + initializeVideo(); + } + const string message = string("Correct aspect ratio ") + (enabled ? "enabled" : "disabled"); + + myOSystem.frameBuffer().showMessage(message); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Console::setTIAProperties() { diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index 78f14ba20..b16d9c2c8 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -276,6 +276,11 @@ class Console : public Serializable, public ConsoleIO */ void changeVSizeAdjust(int direction = +1); + /** + Toggle the aspect ratio correction. + */ + void toggleCorrectAspectRatio(bool toggle = true); + /** Returns the current framerate. */ diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index bd4a7dae7..d71f9a2e6 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -134,6 +134,8 @@ class Event JoystickThreeUp, JoystickThreeDown, JoystickThreeLeft, JoystickThreeRight, JoystickThreeFire, + ToggleCorrectAspectRatio, + LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 5e3522624..2ceefbd1a 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -419,6 +419,7 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) std::bind(&FrameBuffer::changeOverscan, &myOSystem.frameBuffer(), _1), std::bind(&Console::selectFormat, &myOSystem.console(), _1), std::bind(&Console::changeVerticalCenter, &myOSystem.console(), _1), + std::bind(&Console::toggleCorrectAspectRatio, &myOSystem.console(), _1), std::bind(&Console::changeVSizeAdjust, &myOSystem.console(), _1), // Palette adjustables std::bind(&PaletteHandler::cyclePalette, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), _1), @@ -780,7 +781,6 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) myAdjustActive = true; } return; - case Event::VSizeAdjustDecrease: if(pressed) { @@ -799,6 +799,15 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) } return; + case Event::ToggleCorrectAspectRatio: + if(pressed && !repeated) + { + myOSystem.console().toggleCorrectAspectRatio(); + myAdjustSetting = AdjustSetting::ASPECT_RATIO; + myAdjustActive = true; + } + break; + case Event::PaletteDecrease: if (pressed && !repeated) { @@ -2512,7 +2521,7 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::JoystickTwoLeft, "P2 Joystick Left", "" }, { Event::JoystickTwoRight, "P2 Joystick Right", "" }, { Event::JoystickTwoFire, "P2 Joystick Fire", "" }, - + { Event::JoystickThreeUp, "P3 Joystick Up", "" }, { Event::JoystickThreeDown, "P3 Joystick Down", "" }, { Event::JoystickThreeLeft, "P3 Joystick Left", "" }, @@ -2573,6 +2582,7 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::OverscanIncrease, "Increase overscan in fullscreen mode", "" }, { Event::VidmodeDecrease, "Previous zoom level", "" }, { Event::VidmodeIncrease, "Next zoom level", "" }, + { Event::ToggleCorrectAspectRatio,"Toggle correct aspect ratio", "" }, { Event::VSizeAdjustDecrease, "Decrease vertical display size", "" }, { Event::VSizeAdjustIncrease, "Increase vertical display size", "" }, { Event::VCenterDecrease, "Move display up", "" }, @@ -2725,7 +2735,7 @@ const Event::EventSet EventHandler::AudioVideoEvents = { Event::OverscanDecrease, Event::OverscanIncrease, Event::FormatDecrease, Event::FormatIncrease, Event::VCenterDecrease, Event::VCenterIncrease, - Event::VSizeAdjustDecrease, Event::VSizeAdjustIncrease, + Event::VSizeAdjustDecrease, Event::VSizeAdjustIncrease, Event::ToggleCorrectAspectRatio, Event::PaletteDecrease, Event::PaletteIncrease, Event::PreviousPaletteAttribute, Event::NextPaletteAttribute, Event::PaletteAttributeDecrease, Event::PaletteAttributeIncrease, diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index e1990a440..35337b381 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -406,6 +406,7 @@ class EventHandler OVERSCAN, TVFORMAT, VCENTER, + ASPECT_RATIO, VSIZE, // Palette adjustables PALETTE, @@ -559,7 +560,7 @@ class EventHandler #else REFRESH_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 174 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, + EMUL_ACTIONLIST_SIZE = 175 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE, MENU_ACTIONLIST_SIZE = 18 ; diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 083b97467..08898c428 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -57,7 +57,7 @@ Settings::Settings() setPermanent("tia.fs_overscan", "0"); setPermanent("tia.vsizeadjust", 0); setPermanent("tia.dbgcolors", "roygpb"); - setTemporary("tia.correct_aspect", "true"); + setPermanent("tia.correct_aspect", "true"); // Palette options setPermanent("palette", PaletteHandler::SETTING_STANDARD); setPermanent("pal.phase_ntsc", "26.2"); @@ -454,7 +454,7 @@ void Settings::usage() const << " -tia.fs_overscan <0-10> Add overscan to TIA image in fullscreen mode\n" << " -tia.dbgcolors Debug colors to use for each object (see manual\n" << " for description)\n" - << " -tia.correct_aspect <1|0> Enable aspect correct scaling\n" + << " -tia.correct_aspect <1|0> Enable aspect ratio correct scaling\n" << endl << " -tv.filter <0-5> Set TV effects off (0) or to specified mode\n" << " (1-5)\n" diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index edb40c7bb..6aec6194d 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -127,8 +127,9 @@ void VideoAudioDialog::addDisplayTab() // TIA interpolation myTIAInterpolate = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Interpolation "); - wid.push_back(myTIAInterpolate); ypos += lineHeight + VGAP * 4; + wid.push_back(myTIAInterpolate); + ypos += lineHeight + VGAP * 4; // TIA zoom levels (will be dynamically filled later) myTIAZoom = new SliderWidget(myTab, _font, xpos, ypos - 1, swidth, lineHeight, "Zoom ", lwidth, 0, fontWidth * 4, "%"); @@ -162,6 +163,11 @@ void VideoAudioDialog::addDisplayTab() myTVOverscan->setTickmarkIntervals(2); wid.push_back(myTVOverscan); + // Aspect ratio correction + ypos += lineHeight + VGAP * 4; + myCorrectAspect = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Correct aspect ratio"); + wid.push_back(myUseStretch); + // Vertical size ypos += lineHeight + VGAP; myVSizeAdjust = @@ -171,7 +177,6 @@ void VideoAudioDialog::addDisplayTab() myVSizeAdjust->setTickmarkIntervals(2); wid.push_back(myVSizeAdjust); - // Add items for tab 0 addToFocusList(wid, myTab, tabID); } @@ -494,6 +499,9 @@ void VideoAudioDialog::loadConfig() myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan")); handleFullScreenChange(); + // Aspect ratio correction + myCorrectAspect->setState(instance().settings().getBool("tia.correct_aspect")); + // Aspect ratio setting (NTSC and PAL) myVSizeAdjust->setValue(instance().settings().getInt("tia.vsizeadjust")); @@ -616,6 +624,9 @@ void VideoAudioDialog::saveConfig() // TIA zoom levels instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0); + // Aspect ratio correction + instance().settings().setValue("tia.correct_aspect", myCorrectAspect->getState()); + // Aspect ratio setting (NTSC and PAL) const int oldAdjust = instance().settings().getInt("tia.vsizeadjust"); const int newAdjust = myVSizeAdjust->getValue(); @@ -729,6 +740,7 @@ void VideoAudioDialog::setDefaults() #endif myTVOverscan->setValue(0); myTIAZoom->setValue(300); + myCorrectAspect->setState(true); myVSizeAdjust->setValue(0); handleFullScreenChange(); diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index 7f0fd817e..3581635b4 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -75,6 +75,7 @@ class VideoAudioDialog : public Dialog SliderWidget* myTVOverscan{nullptr}; CheckboxWidget* myRefreshAdapt{nullptr}; SliderWidget* myTIAZoom{nullptr}; + CheckboxWidget* myCorrectAspect{nullptr}; SliderWidget* myVSizeAdjust{nullptr}; // TV effects adjustables (custom mode) From 80b87bd0b94b733d562f2a6247466618ac6154bb Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 5 Oct 2020 23:07:52 +0200 Subject: [PATCH 065/263] fixed wording --- src/emucore/EventHandler.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 2ceefbd1a..788cb73b9 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -2582,7 +2582,7 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::OverscanIncrease, "Increase overscan in fullscreen mode", "" }, { Event::VidmodeDecrease, "Previous zoom level", "" }, { Event::VidmodeIncrease, "Next zoom level", "" }, - { Event::ToggleCorrectAspectRatio,"Toggle correct aspect ratio", "" }, + { Event::ToggleCorrectAspectRatio,"Toggle aspect ratio correct scaling", "" }, { Event::VSizeAdjustDecrease, "Decrease vertical display size", "" }, { Event::VSizeAdjustIncrease, "Increase vertical display size", "" }, { Event::VCenterDecrease, "Move display up", "" }, From bd89f3c8108d460d34a56bb1ea1d584168ba296c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 6 Oct 2020 15:30:07 +0200 Subject: [PATCH 066/263] added info to "Correct aspect ratio" UI setting --- docs/graphics/options_video.png | Bin 3204 -> 3572 bytes src/gui/VideoAudioDialog.cxx | 11 ++++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/graphics/options_video.png b/docs/graphics/options_video.png index 81db47827eeb61022d3813d39e896ea221c50f89..745a47d83b5edce610352e84d8392f008c325151 100644 GIT binary patch delta 3482 zcmZ9Oc|6qJ9>+-$g*=LEqea7@n#nSDS|}MLTh=i%nanc@@n9_dvShC*!p}CcOSYH@ zlNe?sgEW>HOSX_bSt7c1d+u}Z>z>#9bG3bWW* zo1!1-RfOp5ji)h>t-2?D4s84A-MwRjI(rpmtaTXgRqr_aBXLQk@Z*R$g_%-kosP`C z!)i-ZlIHfqiq(hDW3zd&fN!C{hTlmNOY+lIoMX)A%AJ)fFudWFmpZ3Z!fY)&Za7vf z8NM_uvj|aAWct_?w#O(#%J$+<9Z1mCnOHVCVHODMxYt=n@3CA}$tHLxnM@JOKI0w;C9=UMbTeK3xl4_-4R&$vI51hg9W_uGRXqL5=$ zQ`S56Ff|TXQ#FG>^jxizLr7aK9a)Vop{P?$efsI^R4>Q^VfI#w>8YUeLX|e%-}wR= zV!k;s-;O!O2uiQbM1yj$d^s83m3CwO0@GljI!G{L6{;x$=@{}lr0;yT$`16q>e zRg+<0>HTvJ)I7hD2zLArF70@v#FBa^Zc{Ma^0~&PlN4-kzVL}U_rS;kcn13n)IdzM zWR+_rr!Q6L&_Y~mEHDAjisp}Af6$`ZLEvX6$@Df`vn7M+J)&H->1!&t-ZiGakR2vj zUeBmUrY<=yH-K%k92J2`)^qd17u!M9&iCJ6C{E5;Kwgz&^Jz-Q>eRry={I z{S@j}njV778_Pj;f4KKWh&oBl%tEgQZt>~PM~?KrZ#q~x$dV9{Vh7mzF4vGCc&GPRN!qi@Q4vb>ZTEd?eDvcSRf;EVBk zzPawfy&kP(2J$j>B>i#KEpJ7POh0kMSj*%v&?B5PO4$o zeLL;t&+gtu>`j@=6I3;SAfsUiHg~1IcgW+*>cNIEfEj+F`p!muqPEOu!tydAb#`-ucgVMCt*#{yepoNSe*_PhYrM`h5)tPyHPssVQ>7*cFc&^po8y`f=1a z`JVi-yF}Ox(^3*7geT+R%@1J|=3t~2-051n|16^ikavCES&cFlzI=~7x zL7XuD1@L?M|Cw-$wfGu5Iqe26tcAC34u30L_7H}Yach`i+}>fC+&gbleZ5f9@!4nP z%i-weKv&kZSY{ra;1{SRS@MHQq?NF;kb`|uBJg~&!S(TAxHWFzfVY*!_+x&xm1$r z9E%i8plr_e)v$zI#byxm@$W?u#y@5I5AOq;cS3IN8|~K$3T*PEw_cP$9WQU_a*BK29c=?v%WzW+$zgJbd2d_HAjNmbWG_rm z3z)?UsODc=Xc-FLDrAS4;|-OCNU?*MtFGzCSPJ1LDl|s$6XnBFZPB~JhL@gU1BhDU z?YIcj5Hn75Gc4l9>%0f1jjHr?_cuT`@@}hMZ%E4FR7cep`O)xgIzL{rGt&?U&mdPM zPYyt>!IqIqu^ryCuTDv5VZKMfYYJAIi1}>Cl}vO(lIp*3qIYFq`y`7D<)}c78BX)h427G%|<4F`FBK`9V3@0L?dPYRQFSQkmRO}e zN=L_k#ljjF4^Y+;LChW{7c)g8GNJm2u1LcF9P{65{@=^}SqD$i9YdMxe_&a}?flx< zE$*^XgR2nzHK29s#|`+*(-FJXn|IejzYi|?QW6oeS*WI);@ms}fqAv?p|(THudW@X zc{gr(tLDW~1Q*Z%f^K5RI=@G&rn)K=*!XeoGu_97QLO*D8XHmYGBS0!O}t_;nBhm* zgc}I)=gO@_H5B`UL%#GV2>(1i=CS0mNtFQxK6-5!2o#j%$*4xhZ%F?(5BD9S|MTO z=0jh$71xs+3FDOBrCIlW!u`d}ngS=k*P6>N9--qU0p-Z$cfsA7L-Y z|A+U3;0SP zF)7Sd>MQ}Zbb5GFO*uB@Ythk5DFD+GjcI2}Jx*@i|LSgZ_8WJWoTqkhB-UYZ@B}NF ziR8&&9l;z?nkQ^WC7(PG_C}&JHFTl^>>a~QkI~DR(nVfrr0NzbUn5nUza9F1#q_^6 z{6~vFix@bp!~FH#8T zP+}*}XYgzkqZc_-AZ5QhJ19!RXfd9aewvx9;2++v%(jWpY>tUzs_2`XuN$|$fA1eZERhNQGXKeTPNFV zo#2N(tA(tauhvwx%ZvB;+C=l>KApl5%sINB>hr+(Trl28nl&PPr?+r|~w71P;?rT?aKDXILC|y z)lg!&!IUD+I0y>8HYqtpa~z`O!HI7+N4QwW>JS~TK&uU2c;%{x3m(ZZU=4VS6u%sM zylHC@xJ!HWJ80*@!e*2E57r;@G6f(&gD#Qpg)@*evEf`xv8bfAjhRK#JMHt(JEGgt?WJwvul4L9m zNk&A&#n`20qRG+_8bb8C?|tvRpU?g4eLmmkdCvL&e9t-G72@R5!ii#wR+cB7ZjSPD zkxwU#q;5;!+%IW1wF3|oUz`&5jEhu6J&$en6g&qpPK!UPBBB3I>E6-(R*C%s^vs$0 z<3<$7(l6bjlNX!uYsY?UpS`MV_L+l>E z5=qvjlQ{#=kC}72jviGHtM_QDkT&7jx{;9KNab#9p+b_GDy;(pdzCz5DYi5Rt&>)A zNM@MAcws_FRlx^dNRXi4pi3ao5HKps+Rs9pB3o~#LN+`yY`?N; zcXeAe5}}&Y27pYckcDh|T6e7G*(sM$SPG4MA|K1I{Nl6$y^3zT0&7z|()LwrwS*Lp z0Xtg}5f@*Z7inMye_>$R?LVD5)h>^(n!%ha7goc-bz!+ZWs#-PK>l%l->+h9Tk<%d zn+4)}Nr987o}tXF)t(Z^L}w+|eD^9)6!3l&VKecJTbVbx64f4bW^{XXMZjSHvDfCj8c>V7zz)xg^8WISuy_rn4ov-s*=Gk<$7}zBN)@sm-8dFIA%Rz&Z84^&x zrca`h0r2971)%SkHtK4B=dqv@y2c~S{-GXAv1U939GikL=GfQ)NmZ% z{sByqo0QEkH5mR4=H_Ox;hCJ6YN1e#*W@s2X`RIHXmXtIv4$DEIB1q)v%C4>CF8?} z;*V|$_?qyF{awa;n;sWM&||e99yM@vb+brWjhjK~=MMLUpe|}NIiq~)t>kIqg0%J7 z#D}DewkVG7Gq|wExhVoLq64@aT~jS%0@of+ynWg z<09g9?6FUfxTQ6xZj` zluNlEI>|)~-IA;jC!74YWh8`|Pn4!p0--Uqnl75+fU*^Jf2ecMWsH1k5?TZDzieD= zT47eO-LC9)a7!)Gelu#Zh8F;uFLoGSJyK*p$!FA53{U-LH6m%D?j~T_TBtkN08mGVm$vfE> ztq~xbytB=}9oepsS}+2%I|#GlaGYAS0-bcuh~06RSYK2B++HdBt=|jJ1}?-osInnu ztfk9#elGInJgu`eV8!Qsx#0wIt>`YN7P?VBUMd4>>E8pp1vftkb6+;19KzWq47)O) z`3X^W&2W1mRmN{>3p!7DUvV9k%AZVoYH0NCKsVXyz?4dM4;y|%9(ZXg%B^|>WNfvm zEr@@9|9WW#+!c>Wr642N(#@7D5x+NG{fTU!HO$}@r}Yr3P$EQB*Y#l7nA(n9yHclj zXBv&$b}KC)#6a}gf_!hc2Oy~L5$Y|CE3b28%qi2gmLl@mUo2tHHKyxXjz98V_C(`R zk?$~(v)4z1iIB&sD+7?nB0#6~jCvD0P>XrNSxeF3>yqDmNe%-l{hp0lbQ9G#cPgt| z`DDw8tJ|cT51AAkJ#@U-9Ugx0tW~nrKm1IVRV(rrs&lbi-kdxA@!V`iOKY~Iqe?*_ z_EVt7CY8jt@QA%UU!$cqiyvrib=jFo1mAHyFiAaY(nFqVbj+w;aknz-LlyG@F3H2X zml1ap?5gj^m6e~O^)fI)4==`euAw8I5Ht27M^9rf^mo{eCniBPw>saSOw#~W`*kT` zdDarBK?lxCFFMS$9-W*h{3QaG|0v=pLD`Jh#f-O!2ISZ0P4#lk{^Jxs6@sOnJrOmhkv zh2OZ3fm#2}r(@b`0T1`Hrr8(uYe%HFdE=gkG?pt=U)#Ga!`}0BeIiV!D>M-&qn1yS zn;iyBiGBR26Uuo5oU!;lNA~G-swhP7NS+&&O|ql4H1c+SJ2WGHe;AUMXzc-$)JUMm zvi7GSP69h0HyE{D*FIX)7 zdAcXDgW?U_d*;e4K{-;y&4s%k+hOve7&FS=*M`AKR{Hwk^|-Zz;q^fInO!lTw?lggNc1!p zpBhiFm(bBE1>^ernus8l=QBa>ldf+jJf&6{%>T6fmyiFXSRDr`%m@DYVB@9JFW22W z#$Meri5B(Wuq!QY=1DKSl|K%go^sn z*s@QUNNq&mw!wL0Nyr zkW!`J5A&Ber=VYwv%pRVD@IlCtl(W1y1~{@q)&z@uQeKDw z{wcFz%)W^A)bjeGV2jJR&kUN*Pon9>cNH&!uQ+bs-biDvL&{iJyhX8vC_WT$e7J3a z|98>;e?hLu(h4Xc_rV_{=})>zqV{PL1M4AO_2EfWTre=?7^cj%f4sO6dKDp8P4svE zV<-DMbPGbNXPCqK>7)}e&RH#uqFW1WB}M>W=q3DEgyp*)B9YZN-qlzGF?_OVEC5%% z(N-e^GHTk!yt1kQbhtw$;kTad0NpS<^Gj+J)I-f`hlOFKSZnn<2Kxg9xV*U(usP-O zfD0fEsXPs>3<==aoR9^91BePsba`&XKJJ0i>1(iqae<@4T(X^6qu<~Taft6{`KZu% zK6*fMiJr$2ze;$7sxqwH2H_-RwgjcVlHwLj;GNVq!Xf}l_M&#hGbOb8$BW*Cb9qVy zER2m-;nKF_#Rq6$te!e{ISJbEE=-RpTJ?LKms?Zd1g-zSGf?FZ;ezCu`Xw5h5;-n1 UdQL=+j=setTickmarkIntervals(2); wid.push_back(myVSizeAdjust); + + // Add message concerning usage + ypos = myTab->getHeight() - fontHeight - ifont.getFontHeight() - VGAP - VBORDER; + int iwidth = ifont.getStringWidth("(*) Change may require an application restart"); + new StaticTextWidget(myTab, ifont, xpos, ypos, + std::min(iwidth, _w - HBORDER * 2), ifont.getFontHeight(), + "(*) Change may require an application restart"); + // Add items for tab 0 addToFocusList(wid, myTab, tabID); } From d3dd0566a487d8ea3f7343d7d9a472d9bd95cf10 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 6 Oct 2020 15:57:49 -0230 Subject: [PATCH 067/263] Final updates for 6.3 release. --- Announce.txt | 24 +++++++++++------------- Changes.txt | 2 +- debian/changelog | 7 +++++++ docs/debugger.html | 4 +++- docs/index.html | 2 +- docs/index_r77.html | 2 +- src/common/Version.hxx | 4 ++-- src/macos/Info-Stella.plist | 4 ++-- src/unix/stella.spec | 5 ++++- src/windows/stella.rc | 8 ++++---- 10 files changed, 36 insertions(+), 26 deletions(-) diff --git a/Announce.txt b/Announce.txt index 2262f7975..525c19736 100644 --- a/Announce.txt +++ b/Announce.txt @@ -9,7 +9,7 @@ SSSS ttt eeeee llll llll aaaaa =========================================================================== - Release 6.2.1 for Linux, macOS and Windows + Release 6.3 for Linux, macOS and Windows =========================================================================== The Atari 2600 Video Computer System (VCS), introduced in 1977, was the @@ -21,27 +21,25 @@ all of your favourite Atari 2600 games again! Stella was originally developed for Linux by Bradford W. Mott, however, it has been ported to a number of other platforms and is currently maintained by Stephen Anthony. -This is the 6.2.1 release of Stella for Linux, macOS and Windows. The +This is the 6.3 release of Stella for Linux, macOS and Windows. The distributions currently available are: * Binaries for Windows Vista/7/8/10 : - Stella-6.2.1-win32.exe (32-bit EXE installer) - Stella-6.2.1-x64.exe (64-bit EXE installer) - Stella-6.2.1-windows.zip (32/64 bit versions) + Stella-6.3-win32.exe (32-bit EXE installer) + Stella-6.3-x64.exe (64-bit EXE installer) + Stella-6.3-windows.zip (32/64 bit versions) * Binary distribution for macOS 10.7 and above : - Stella-6.2.1-macos.dmg (64-bit Intel) + Stella-6.3-macos.dmg (64-bit Intel) - * Binary distribution in 32-bit & 64-bit Ubuntu DEB format : - stella_6.2.1-1_i386.deb - stella_6.2.1-1_amd64.deb + * Binary distribution for 64-bit Ubuntu : + stella_6.3-1_amd64.deb - * Binary distribution in 32-bit & 64-bit RPM format : - stella-6.2.1-2.i386.rpm - stella-6.2.1-2.x86_64.rpm + * Binary distribution for 64-bit Redhat : + stella-6.3-2.x86_64.rpm * Source code distribution for all platforms : - stella-6.2.1-src.tar.xz + stella-6.3-src.tar.xz Distribution Site diff --git a/Changes.txt b/Changes.txt index c424dd683..18444bb10 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,7 +12,7 @@ Release History =========================================================================== -6.2.1 to 6.3 (XXXX XX, 2020) +6.2.1 to 6.3 (October 7, 2020) * Added adjustable autofire. diff --git a/debian/changelog b/debian/changelog index 75c7267b6..099657a51 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +stella (6.3-1) stable; urgency=high + + * Version 6.3 release + + -- Stephen Anthony Wed, 7 Oct 2020 17:09:59 -0230 + + stella (6.2.1-1) stable; urgency=high * Version 6.2.1 release diff --git a/docs/debugger.html b/docs/debugger.html index 781d05bf5..9ce69b949 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -15,7 +15,7 @@
    Stella
    -

    Release 6.2.1

    +

    Release 6.3

    Integrated Debugger

    (a work in progress)


    @@ -757,6 +757,8 @@ that holds 'number of scanlines' on an actual console).

    + +
    ItemBrief descriptionFor more information,
    see CommandLine
    ItemBrief descriptionFor more information,
    see Command Line
    Font sizeSelf-explanatory-dbg.fontsize
    Font styleSelf-explanatory-dbg.fontstyle
    Debugger width/heightSelf-explanatory-dbg.res
    BF CPUWIZ 256K .BF
    BFSC CPUWIZ 256K + RAM.BFS, .BFSC
    BUS Experimental.BUS
    CDF Chris, Darrell, Fred (includes CDFJ).CDF
    CDF Chris, Darrell, Fred (includes CDFJ/CDFJ+).CDF
    CM ¹Spectravideo CompuMate .CM
    CTY ²CDW - Chetiry .CTY
    CV CommaVid extra RAM .CV
    -audio.enabled <1|0>
    Enable or disable sound generation.
    -audio.enabled <1|0>
    Enable or disable sound generation.
    -audio.volume <0 - 100>
    Set the volume.
    -audio.volume <0 - 100>
    Set the volume.
    -audio.device <number>
    Set the audio device (0 = default).
    -audio.device <number>
    Set the audio device (0 = default).
    -audio.preset <1 - 5>
    Set an audio preset. Numbers in sequence represent presets for - 'custom', 'low quality, medium lag', 'high quality, medium lag', - 'high quality, low lag' and 'ultra quality, minimal lag'.
    -audio.preset <1 - 5>
    Set an audio preset. Numbers in sequence represent presets for + 'custom', 'low quality, medium lag', 'high quality, medium lag', + 'high quality, low lag' and 'ultra quality, minimal lag'.
    -audio.fragment_size <128|256|512|1024|2048|4096>
    Set the number of samples in a single fragment processed by the audio driver.
    -audio.fragment_size <128|256|512|1024|2048|4096>
    Set the number of samples in a single fragment processed by the audio driver.
    -audio.sample_rate <44100|48000|96000>
    Set sound sample output frequency.
    -audio.sample_rate <44100|48000|96000>
    Set sound sample output frequency.
    -audio.resampling_quality <1|2|3>
    Set resampling quality to low (1), high (2) or ultra (3).
    -audio.resampling_quality <1|2|3>
    Set resampling quality to low (1), high (2) or ultra (3).
    -audio.headroom <0 - 20>
    Set number of additional half-frames to prebuffer.
    -audio.headroom <0 - 20>
    Set number of additional half-frames to prebuffer.
    -audio.buffer_size <0 - 20>
    Set maximum number of additional half-frames to buffer.
    -audio.buffer_size <0 - 20>
    Set maximum number of additional half-frames to buffer.
    -audio.stereo <1|0>
    Enable or disable stereo mode for all ROMs.
    -audio.stereo <1|0>
    Enable or disable stereo mode for all ROMs.
    -audio.dpc_pitch <10000 - 30000>
    Set the pitch of Pitfall II music.
    -audio.dpc_pitch <10000 - 30000>
    Set the pitch of Pitfall II music.
    -tia.zoom <zoom>
    Use the specified zoom level (integer) while in TIA/emulation mode. -
    -tia.zoom <zoom>
    Use the specified zoom level (integer) while in TIA/emulation mode. +
    -tia.vsizeadjust <-5 - 5>
    Adjust the display height of the TIA image -
    -tia.vsizeadjust <-5 - 5>
    Adjust the display height of the TIA image +
    -tia.inter <1|0>
    Use interpolation for the TIA image (results in blending/smoothing - of the image).
    -tia.inter <1|0>
    Use interpolation for the TIA image (results in blending/smoothing + of the image).
    -tia.fs_stretch <1|0>
    Stretch TIA image completely while in fullscreen mode, vs. keeping the correct - aspect ratio.
    -tia.fs_stretch <1|0>
    Stretch TIA image completely while in fullscreen mode, vs. keeping the correct + aspect ratio.
    -tia.fs_refresh <1|0>
    While in fullscreen mode, adapt the display's refresh rate to the game's frame rate - to minimize judder.
    - Note: Not available for macOS.
    -tia.fs_refresh <1|0>
    While in fullscreen mode, adapt the display's refresh rate to the game's frame rate + to minimize judder.
    + Note: Not available for macOS.
    -tia.fs_overscan <0 - 10>
    Add overscan to TIA image while in fullscreen mode
    -tia.fs_overscan <0 - 10>
    Add overscan to TIA image while in fullscreen mode
    -tia.plain_video <1|0>
    Disable all scaling and postprocessing.
    -tv.filter <0 - 5>
    Blargg TV effects, 0 is disabled, next numbers in diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 04040c597..3ae8c203e 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -623,7 +623,7 @@ FBInitStatus Console::initializeVideo(bool full) if(full) { uInt32 width, height; - if (myOSystem.settings().getBool("plain-video")) { + if (myOSystem.settings().getBool("tia.plain_video")) { width = 2 * myTIA->width(); height = myTIA->height(); } else { diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 595ab35ec..f3f1ef61b 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -48,7 +48,6 @@ Settings::Settings() setPermanent("windowedpos", Common::Point(50, 50)); setPermanent("display", 0); setPermanent("uimessages", "true"); - setTemporary("plain-video", "false"); // TIA specific options setPermanent("tia.inter", "false"); setPermanent("tia.zoom", "3"); @@ -58,6 +57,7 @@ Settings::Settings() setPermanent("tia.fs_overscan", "0"); setPermanent("tia.vsizeadjust", 0); setPermanent("tia.dbgcolors", "roygpb"); + setTemporary("tia.plain_video", "false"); // Palette options setPermanent("palette", PaletteHandler::SETTING_STANDARD); setPermanent("pal.phase_ntsc", "26.2"); @@ -418,7 +418,6 @@ void Settings::usage() const << " -palette \n" - << " -plain-video <1|0> Disable all scaling and postprocessing\n" << " -pal.phase_ntsc Phase shift for NTSC 'custom' palette\n" << " -pal.phase_pal Phase shift for PAL 'custom' palette\n" << " -pal.hue <-1.0 - 1.0> Adjust hue for current palette\n" @@ -455,6 +454,7 @@ void Settings::usage() const << " -tia.fs_overscan <0-10> Add overscan to TIA image in fullscreen mode\n" << " -tia.dbgcolors Debug colors to use for each object (see manual\n" << " for description)\n" + << " -tia.plain_video <1|0> Disable all scaling and postprocessing\n" << endl << " -tv.filter <0-5> Set TV effects off (0) or to specified mode\n" << " (1-5)\n" diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx index a6f11c956..a9cca5795 100644 --- a/src/emucore/TIASurface.cxx +++ b/src/emucore/TIASurface.cxx @@ -317,7 +317,7 @@ void TIASurface::enableNTSC(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string TIASurface::effectsInfo() const { - if (plainVideoEnabled()) return "plain video mode"; + if (plainVideoEnabled()) return "Plain video mode"; const FBSurface::Attributes& attr = mySLineSurface->attributes(); ostringstream buf; @@ -525,5 +525,5 @@ void TIASurface::updateSurfaceSettings() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TIASurface::plainVideoEnabled() const { - return myOSystem.settings().getBool("plain-video"); + return myOSystem.settings().getBool("tia.plain_video"); } From 1a739162abd6a85b8722d6cb12dc61fcf7c98e74 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 5 Oct 2020 19:25:04 +0200 Subject: [PATCH 061/263] changed plain video mode into no correct aspect ratio mode updated docs --- Changes.txt | 2 +- docs/index.html | 4 ++-- src/emucore/Console.cxx | 2 +- src/emucore/FrameBuffer.cxx | 3 ++- src/emucore/Settings.cxx | 4 ++-- src/emucore/TIASurface.cxx | 19 +++++++------------ src/emucore/TIASurface.hxx | 2 +- 7 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Changes.txt b/Changes.txt index 27ba6e9c1..0276a60e7 100644 --- a/Changes.txt +++ b/Changes.txt @@ -51,7 +51,7 @@ * Added another oddball TIA glitch option for delayed background color. - * Added option to disable all scaling and postprocessing. + * Added option to disable aspect correct scaling. * Replaced "Re-disassemble" with "Disassemble @ current line" in debugger. diff --git a/docs/index.html b/docs/index.html index e5b9be777..a74fdc3a6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2285,8 +2285,8 @@
    -tia.plain_video <1|0>
    Disable all scaling and postprocessing.
    -tia.correct_aspect <1|0>
    Enable aspect correct scaling.
    Alt + PageUp Cmd-Fn + Up arrow
    Toggle aspect ratio correct scalingControl + cControl + c
    Decrease vertical display size Shift-Alt + PageUp
    -tia.correct_aspect <1|0>
    Enable aspect correct scaling.Enable aspect ratio correct scaling.
    - - - + + + - - + + +
    ItemBrief descriptionFor more information,
    see Command Line
    RendererUse specified rendering mode-video
    InterpolationEnable interpolation of the TIA image-tia.inter
    ZoomZoom level of the TIA image-tia.zoom
    RendererUse specified rendering mode.-video
    InterpolationEnable interpolation of the TIA image.-tia.inter
    ZoomAdjust the zoom level of the TIA image-tia.zoom
    FullscreenSelf-explanatory - Note that colors may slightly change. This depends on the OS and renderer used.-fullscreen
    StretchIn fullscreen mode, completely fill screen with the TIA image.-tia.fs_stretch
    Adapt display...In fullscreen mode, adapt the display's refresh rate to the game's frame rate to minimize judder.
    Note: Not available for macOS.
    -tia.fs_refresh
    OverscanIn fullscreen mode, add overscan to the TIA image-tia.fs_overscan
    V-Size adjustAdjust height of the TIA image-tia.vsizeadjust
    OverscanIn fullscreen mode, add overscan to the TIA image.-tia.fs_overscan
    Correct aspect ratioEnable aspect ratio correct scaling. +
    Note: Creates a cleaner looking TIA image when disabled (like z26 and old versions of Stella) vs. a correctly emulated aspect ratio when enabled.
    -tia.correct_aspect
    V-Size adjustAdjust the height of the TIA image.-tia.vsizeadjust
    _scan Current scanline count
    _scanend Scanline count at end of last frame
    _scycles Number of cycles in current scanline
    _timwrapread Timer read wrapped on this cycle
    _timwrapwrite Timer write wrapped on this cycle
    _vblank Whether vertical blank is enabled (1 or 0)
    _vsync Whether vertical sync is enabled (1 or 0)
    diff --git a/docs/index.html b/docs/index.html index 2fb930e39..4e939ebd3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -19,7 +19,7 @@

    A multi-platform Atari 2600 VCS emulator

    -

    Release 6.2.1

    +

    Release 6.3



    User's Guide

    diff --git a/docs/index_r77.html b/docs/index_r77.html index cc15b11ab..6f3fad5e3 100644 --- a/docs/index_r77.html +++ b/docs/index_r77.html @@ -58,7 +58,7 @@

    Stella for RetroN 77

    Atari 2600 VCS emulator

    -
    Release 6.2.1
    +
    Release 6.3

    Quick Navigation Guide


    diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 22801ca3a..e84d6ece3 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.3_pre" -#define STELLA_BUILD "6091" +#define STELLA_VERSION "6.3" +#define STELLA_BUILD "6180" #endif diff --git a/src/macos/Info-Stella.plist b/src/macos/Info-Stella.plist index d9eb7520e..87f4e5681 100644 --- a/src/macos/Info-Stella.plist +++ b/src/macos/Info-Stella.plist @@ -45,7 +45,7 @@ CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion - 6.2.1 + 6.3 CFBundleName Stella CFBundlePackageType @@ -53,7 +53,7 @@ CFBundleSignature StLa CFBundleVersion - 6.2.1 + 6.3 LSApplicationCategoryType public.app-category.games LSMinimumSystemVersionByArchitecture diff --git a/src/unix/stella.spec b/src/unix/stella.spec index ad6819995..2818841ac 100644 --- a/src/unix/stella.spec +++ b/src/unix/stella.spec @@ -1,5 +1,5 @@ %define name stella -%define version 6.2.1 +%define version 6.3 %define rel 1 %define enable_sound 1 @@ -100,6 +100,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version} %_datadir/icons/large/%{name}.png %changelog +* Wed Oct 7 2020 Stephen Anthony 6.3-1 +- Version 6.3 release + * Sat Jun 20 2020 Stephen Anthony 6.2.1-1 - Version 6.2.1 release diff --git a/src/windows/stella.rc b/src/windows/stella.rc index 0958a136d..4640920a0 100755 --- a/src/windows/stella.rc +++ b/src/windows/stella.rc @@ -36,8 +36,8 @@ IDI_ICON ICON "stella.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 6,2,1,0 - PRODUCTVERSION 6,2,1,0 + FILEVERSION 6,3,0,0 + PRODUCTVERSION 6,3,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -55,12 +55,12 @@ BEGIN VALUE "Comments", "The multi-platform Atari 2600 emulator. Stella is released under the GPLv2." VALUE "CompanyName", "The Stella Team (https://stella-emu.github.io)" VALUE "FileDescription", "Stella" - VALUE "FileVersion", "6.2.1" + VALUE "FileVersion", "6.3" VALUE "InternalName", "Stella" VALUE "LegalCopyright", "Copyright (c) 1995-2020 The Stella Team" VALUE "OriginalFilename", "Stella.exe" VALUE "ProductName", "Stella" - VALUE "ProductVersion", "6.2.1" + VALUE "ProductVersion", "6.3" END END BLOCK "VarFileInfo" From e0d92192a90caf1cd0bf8ef121d64d9f122e5de1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 8 Oct 2020 21:34:00 +0200 Subject: [PATCH 068/263] Display zoom factor when switch from/to fullscreen mode --- src/emucore/FrameBuffer.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 6f5dd951a..c3c9bfe02 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -1049,12 +1049,14 @@ void FrameBuffer::toggleFullscreen(bool toggle) if (myBufferType != BufferType::Launcher) { ostringstream msg; + const VideoMode& mode = getSavedVidMode(isFullscreen); msg << "Fullscreen "; - if (isFullscreen) - msg << "enabled (" << refreshRate() << " Hz)"; + if(isFullscreen) + msg << "enabled (" << refreshRate() << " Hz, "; else - msg << "disabled"; + msg << "disabled ("; + msg << "Zoom " << mode.zoom * 100 << "%)"; showMessage(msg.str()); } From 338116018b0e53f2cef9f17bab1c0ae0fbafe804 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 11 Oct 2020 10:12:42 +0200 Subject: [PATCH 069/263] Added basic (entire and single line only) text cut/copy and paste (partially implements #105) --- Changes.txt | 5 ++++ docs/index.html | 5 ++-- src/common/EventHandlerSDL2.cxx | 24 ++++++++++++++++ src/common/EventHandlerSDL2.hxx | 9 +++++- src/debugger/gui/PromptWidget.cxx | 47 +++++++++++++++++++++++++++++++ src/debugger/gui/PromptWidget.hxx | 1 + src/emucore/EventHandler.hxx | 7 +++++ src/gui/EditableWidget.cxx | 39 ++++++++++++++++--------- src/gui/EditableWidget.hxx | 3 +- 9 files changed, 122 insertions(+), 18 deletions(-) diff --git a/Changes.txt b/Changes.txt index 18444bb10..76d711721 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,6 +12,11 @@ Release History =========================================================================== +6.3 to 6.4 (XXXX XX, 202X) + + * Added basic (entire and single line only) text cut/copy and paste + + 6.2.1 to 6.3 (October 7, 2020) * Added adjustable autofire. diff --git a/docs/index.html b/docs/index.html index 4e939ebd3..d2d7b8e6f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1883,8 +1883,9 @@
    Control + wRemove entire word to left of cursor
    Control + LeftMove cursor to beginning of word to the left
    Control + RightMove cursor to beginning of word to the right
    Control + cCopy entire line to clipboard (not complete)
    Control + vPaste clipboard contents (not complete)
    Control + cCopy entire line to clipboard
    Control + vPaste clipboard contents
    Control + xCut entire line to clipboard

    diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index 2e8b60323..fa19303bc 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -58,6 +58,30 @@ void EventHandlerSDL2::enableTextEvents(bool enable) SDL_StopTextInput(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventHandlerSDL2::copyText(const string& text) const +{ + SDL_SetClipboardText(text.c_str()); +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventHandlerSDL2::cutText(string& text) const +{ + copyText(text); + text = ""; +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string EventHandlerSDL2::pasteText(string& text) const +{ + if(SDL_HasClipboardText()) + text = SDL_GetClipboardText(); + else + text = ""; + + return text; +}; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandlerSDL2::pollEvent() { diff --git a/src/common/EventHandlerSDL2.hxx b/src/common/EventHandlerSDL2.hxx index 2fea58371..c7f9c4a2f 100644 --- a/src/common/EventHandlerSDL2.hxx +++ b/src/common/EventHandlerSDL2.hxx @@ -38,12 +38,19 @@ class EventHandlerSDL2 : public EventHandler explicit EventHandlerSDL2(OSystem& osystem); ~EventHandlerSDL2() override; - private: +private: /** Enable/disable text events (distinct from single-key events). */ void enableTextEvents(bool enable) override; + /** + Clipboard methods. + */ + void copyText(const string& text) const override; + void cutText(string& text) const override; + string pasteText(string& text) const override; + /** Collects and dispatches any pending SDL2 events. */ diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 7a1cd56f2..9b3c1bca9 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -24,12 +24,17 @@ #include "Debugger.hxx" #include "DebuggerDialog.hxx" #include "DebuggerParser.hxx" +#include "EventHandler.hxx" #include "PromptWidget.hxx" #include "CartDebug.hxx" #define PROMPT "> " +// Uncomment the following to give full-line cut/copy/paste +// Note that this will be removed eventually, when we implement proper cut/copy/paste +#define PSEUDO_CUT_COPY_PASTE + // TODO: Github issue #361 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font, @@ -673,19 +678,61 @@ void PromptWidget::textSelectAll() { } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string PromptWidget::getLine() +{ +#if defined(PSEUDO_CUT_COPY_PASTE) + assert(_promptEndPos >= _promptStartPos); + int len = _promptEndPos - _promptStartPos; + string text; + + // Copy current line to text + for(int i = 0; i < len; i++) + text += buffer(_promptStartPos + i) & 0x7f; + + return text; +#endif +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PromptWidget::textCut() { +#if defined(PSEUDO_CUT_COPY_PASTE) + string text = getLine(); + + instance().eventHandler().cutText(text); + + // Remove the current line + _currentPos = _promptStartPos; + killLine(1); // to end of line + _promptEndPos = _currentPos; +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PromptWidget::textCopy() { +#if defined(PSEUDO_CUT_COPY_PASTE) + string text = getLine(); + + instance().eventHandler().copyText(text); +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PromptWidget::textPaste() { +#if defined(PSEUDO_CUT_COPY_PASTE) + string text; + + // Remove the current line + _currentPos = _promptStartPos; + killLine(1); // to end of line + + instance().eventHandler().pasteText(text); + print(text); + _promptEndPos = _currentPos; +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/PromptWidget.hxx b/src/debugger/gui/PromptWidget.hxx index 0570f025f..925fee4e7 100644 --- a/src/debugger/gui/PromptWidget.hxx +++ b/src/debugger/gui/PromptWidget.hxx @@ -72,6 +72,7 @@ class PromptWidget : public Widget, public CommandSender // Clipboard void textSelectAll(); + string getLine(); void textCut(); void textCopy(); void textPaste(); diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 35337b381..50d26b0ed 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -326,6 +326,13 @@ class EventHandler */ virtual void enableTextEvents(bool enable) = 0; + /** + Clipboard methods. + */ + virtual void copyText(const string& text) const = 0; + virtual void cutText(string& text) const = 0; + virtual string pasteText(string& text) const = 0; + /** Handle changing mouse modes. */ diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 5218e6fc4..72b88d565 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -19,11 +19,13 @@ #include "StellaKeys.hxx" #include "FBSurface.hxx" #include "Font.hxx" +#include "OSystem.hxx" +#include "EventHandler.hxx" #include "EditableWidget.hxx" -// Uncomment the following to give full-line copy/paste -// Note that this will be removed eventually, when we implement proper copy/paste -//#define PSEUDO_COPY_PASTE +// Uncomment the following to give full-line cut/copy/paste +// Note that this will be removed eventually, when we implement proper cut/copy/paste +#define PSEUDO_CUT_COPY_PASTE // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font, @@ -260,7 +262,7 @@ bool EditableWidget::specialKeys(StellaKey key) { bool handled = true; - switch (key) + switch(key) { case KBDK_A: setCaretPos(0); @@ -268,7 +270,6 @@ bool EditableWidget::specialKeys(StellaKey key) case KBDK_C: copySelectedText(); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_E: @@ -292,7 +293,7 @@ bool EditableWidget::specialKeys(StellaKey key) case KBDK_V: pasteSelectedText(); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_W: @@ -300,6 +301,11 @@ bool EditableWidget::specialKeys(StellaKey key) if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; + case KBDK_X: + cutSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + case KBDK_LEFT: handled = moveWord(-1); break; @@ -445,21 +451,28 @@ bool EditableWidget::moveWord(int direction) return handled; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EditableWidget::cutSelectedText() +{ +#if defined(PSEUDO_CUT_COPY_PASTE) + instance().eventHandler().cutText(_editString); + _caretPos = 0; +#endif +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::copySelectedText() { -#if defined(PSEUDO_COPY_PASTE) - _clippedText = _editString; +#if defined(PSEUDO_CUT_COPY_PASTE) + instance().eventHandler().copyText(_editString); #endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::pasteSelectedText() { -#if defined(PSEUDO_COPY_PASTE) - _editString = _clippedText; +#if defined(PSEUDO_CUT_COPY_PASTE) + instance().eventHandler().pasteText(_editString); + _caretPos = int(_editString.length()); #endif } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string EditableWidget::_clippedText = ""; diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 933d033af..748f6074f 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -87,6 +87,7 @@ class EditableWidget : public Widget, public CommandSender bool moveWord(int direction); // Clipboard + void cutSelectedText(); void copySelectedText(); void pasteSelectedText(); @@ -107,8 +108,6 @@ class EditableWidget : public Widget, public CommandSender int _editScrollOffset{0}; - static string _clippedText; - private: TextFilter _filter; From 23eb13932a62126ca2bfaa98796a431195eefdda Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 11 Oct 2020 10:46:49 +0200 Subject: [PATCH 070/263] added cut/copy/paste text support for Windows keys --- docs/index.html | 6 +++--- src/debugger/gui/PromptWidget.cxx | 20 +++++++++++++++++++- src/gui/EditableWidget.cxx | 23 ++++++++++++++++++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/docs/index.html b/docs/index.html index d2d7b8e6f..e7c7c0889 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1883,9 +1883,9 @@
    Control + wRemove entire word to left of cursor
    Control + LeftMove cursor to beginning of word to the left
    Control + RightMove cursor to beginning of word to the right
    Control + cCopy entire line to clipboard
    Control + vPaste clipboard contents
    Control + xCut entire line to clipboard
    Control + c, Control + InsertCopy entire line to clipboard
    Control + v, Shift + InsertPaste clipboard contents
    Control + x, Shift + DeleteCut entire line to clipboard

    diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 9b3c1bca9..75fede786 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -337,7 +337,10 @@ bool PromptWidget::handleKeyDown(StellaKey key, StellaMod mod) case KBDK_DELETE: case KBDK_KP_PERIOD: // actually the num delete - killChar(+1); + if(StellaModTest::isShift(mod)) + textCut(); + else + killChar(+1); dirty = true; break; @@ -444,6 +447,21 @@ bool PromptWidget::handleKeyDown(StellaKey key, StellaMod mod) dirty = true; break; + case KBDK_INSERT: + if(StellaModTest::isShift(mod)) + { + textPaste(); + dirty = true; + } + else if(StellaModTest::isControl(mod)) + { + textCopy(); + dirty = true; + } + else + handled = false; + break; + default: if (StellaModTest::isControl(mod)) { diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 72b88d565..77bcd58a8 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -138,7 +138,13 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) case KBDK_DELETE: case KBDK_KP_PERIOD: - dirty = killChar(+1); + if(StellaModTest::isShift(mod)) + { + cutSelectedText(); + dirty = true; + } + else + dirty = killChar(+1); if(dirty) sendCommand(EditableWidget::kChangedCmd, key, _id); break; @@ -164,6 +170,21 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) dirty = setCaretPos(int(_editString.size())); break; + case KBDK_INSERT: + if(StellaModTest::isControl(mod)) + { + copySelectedText(); + dirty = true; + } + else if(StellaModTest::isShift(mod)) + { + pasteSelectedText(); + dirty = true; + } + else + handled = false; + break; + default: if (StellaModTest::isControl(mod)) { From a810cd4842b9889630db489f94cd78e82f25c2d2 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 11 Oct 2020 11:04:30 +0200 Subject: [PATCH 071/263] minor UI keys doc update --- docs/index.html | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/index.html b/docs/index.html index e7c7c0889..789ea63c2 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1871,18 +1871,15 @@ - - - + + + - - - - - + + From 580d9a2bd6bd716d3d0b7ef699ad9edafadb37d9 Mon Sep 17 00:00:00 2001 From: Autechre Date: Sun, 11 Oct 2020 19:33:23 +0200 Subject: [PATCH 072/263] Create .gitlab-ci.yml --- .gitlab-ci.yml | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..164c78f75 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,68 @@ +.core-defs: + variables: + JNI_PATH: src/libretro + CORENAME: stella + +include: + - template: Jobs/Code-Quality.gitlab-ci.yml + - project: 'libretro-infrastructure/ci-templates' + file: '/libnx-static.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/linux-x64.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-x64-mingw.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/android-jni.yml' + +stages: + - build-prepare + - build-shared + - build-static + - test + +#Desktop +libretro-build-linux-x64: + extends: + - .core-defs + - .libretro-linux-x64-make-default + variables: + MAKEFILE_PATH: src/libretro + MAKEFILE: Makefile + +libretro-build-windows-x64: + extends: + - .core-defs + - .libretro-windows-x64-mingw-make-default + variables: + MAKEFILE_PATH: src/libretro + MAKEFILE: Makefile + +# Android +android-armeabi-v7a: + extends: + - .core-defs + - .libretro-android-jni-armeabi-v7a + +android-arm64-v8a: + extends: + - .core-defs + - .libretro-android-jni-arm64-v8a + +android-x86_64: + extends: + - .core-defs + - .libretro-android-jni-x86_64 + +android-x86: + extends: + - .core-defs + - .libretro-android-jni-x86 + +# Static +libretro-build-libnx-aarch64: + extends: + - .core-defs + - .libretro-libnx-static-retroarch-master + variables: + MAKEFILE_PATH: src/libretro + MAKEFILE: Makefile From c0b5d48a328377e2c46082e1ee8580eb23c27186 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 11 Oct 2020 19:48:27 +0200 Subject: [PATCH 073/263] fix #710 --- src/emucore/EventHandler.hxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 50d26b0ed..bd379a226 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -326,12 +326,14 @@ class EventHandler */ virtual void enableTextEvents(bool enable) = 0; + #ifdef GUI_SUPPORT /** Clipboard methods. */ virtual void copyText(const string& text) const = 0; virtual void cutText(string& text) const = 0; virtual string pasteText(string& text) const = 0; + #endif /** Handle changing mouse modes. From 598dbdfd7a7f0a309cdbf1c02703d9a1bc15de29 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 12 Oct 2020 14:12:57 +0200 Subject: [PATCH 074/263] added some minor refinements of RamWidget and CpuWidget --- src/debugger/gui/CpuWidget.cxx | 21 +++++++--- src/debugger/gui/DataGridWidget.hxx | 1 + src/debugger/gui/RamWidget.cxx | 59 +++++++++++++++++++++-------- src/debugger/gui/RamWidget.hxx | 4 ++ 4 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/debugger/gui/CpuWidget.cxx b/src/debugger/gui/CpuWidget.cxx index babdb8e08..3493e53f8 100644 --- a/src/debugger/gui/CpuWidget.cxx +++ b/src/debugger/gui/CpuWidget.cxx @@ -43,7 +43,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n // Create a 1x1 grid with label for the PC register xpos = x; ypos = y; lwidth = 4 * fontWidth; - new StaticTextWidget(boss, lfont, xpos, ypos+1, lwidth-2, fontHeight, + new StaticTextWidget(boss, lfont, xpos, ypos + 2, lwidth-2, fontHeight, "PC ", TextAlign::Left); myPCGrid = new DataGridWidget(boss, nfont, xpos + lwidth, ypos, 1, 1, 4, 16, Common::Base::Fmt::_16); @@ -66,14 +66,14 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n addFocusWidget(myCpuGrid); // Create a 1x4 grid with decimal and binary values for the other CPU registers - xpos = x + lwidth + myPCGrid->getWidth() + 10; + xpos = myPCGrid->getRight() + 10; myCpuGridDecValue = new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 3, 8, Common::Base::Fmt::_10); myCpuGridDecValue->setTarget(this); myCpuGridDecValue->setID(kCpuRegDecID); addFocusWidget(myCpuGridDecValue); - xpos += myCpuGridDecValue->getWidth() + 5; + xpos = myCpuGridDecValue->getRight() + fontWidth * 2; myCpuGridBinValue = new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 8, 8, Common::Base::Fmt::_2); myCpuGridBinValue->setTarget(this); @@ -104,14 +104,25 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n const std::array labels = { "SP ", "A ", "X ", "Y " }; for(int row = 0; row < 4; ++row) { - new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 1, + new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 2, lwidth-2, fontHeight, labels[row], TextAlign::Left); } + // Add prefixes for decimal and binary values + for(int row = 0; row < 4; ++row) + { + new StaticTextWidget(boss, lfont, myCpuGridDecValue->getLeft() - fontWidth, + ypos + row * lineHeight + 2, + lwidth - 2, fontHeight, "#"); + new StaticTextWidget(boss, lfont, myCpuGridBinValue->getLeft() - fontWidth, + ypos + row * lineHeight + 2, + lwidth - 2, fontHeight, "%"); + } + // Create a bitfield widget for changing the processor status xpos = x; ypos += 4*lineHeight + 2; - new StaticTextWidget(boss, lfont, xpos, ypos+1, lwidth-2, fontHeight, + new StaticTextWidget(boss, lfont, xpos, ypos + 2, lwidth-2, fontHeight, "PS ", TextAlign::Left); myPSRegister = new ToggleBitWidget(boss, nfont, xpos+lwidth, ypos, 8, 1); myPSRegister->setTarget(this); diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index f7d9988c5..114097b01 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -69,6 +69,7 @@ class DataGridWidget : public EditableWidget int getSelectedAddr() const { return _addrList[_selectedItem]; } int getSelectedValue() const { return _valueList[_selectedItem]; } + bool getSelectedChanged() const { return _changedList[_selectedItem]; } void setRange(int lower, int upper); diff --git a/src/debugger/gui/RamWidget.cxx b/src/debugger/gui/RamWidget.cxx index f7559cd5b..de09949e4 100644 --- a/src/debugger/gui/RamWidget.cxx +++ b/src/debugger/gui/RamWidget.cxx @@ -37,14 +37,16 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n myFontWidth(lfont.getMaxCharWidth()), myFontHeight(lfont.getFontHeight()), myLineHeight(lfont.getLineHeight()), - myButtonHeight(myLineHeight + 4), + myButtonHeight(myLineHeight * 1.25), myRamSize(ramsize), myNumRows(numrows), myPageSize(pagesize) { const int bwidth = lfont.getStringWidth("Compare " + ELLIPSIS), bheight = myLineHeight + 2; - const int VGAP = 4; + //const int VGAP = 4; + const int VGAP = myFontHeight / 4; + StaticTextWidget* s; WidgetArray wid; int ypos = y + myLineHeight; @@ -54,7 +56,7 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n myRamGrid = new DataGridWidget(_boss, _nfont, xpos, ypos, 16, myNumRows, 2, 8, Common::Base::Fmt::_16, true); myRamGrid->setTarget(this); - myRamGrid->setID(kRamHexID); + myRamGrid->setID(kRamGridID); addFocusWidget(myRamGrid); // Create actions buttons to the left of the RAM grid @@ -119,35 +121,44 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n // For smaller grids, make sure RAM cell detail fields are below the RESET button row = myNumRows < 8 ? 9 : myNumRows + 1; - ypos += row * myLineHeight; + ypos += (row - 1) * myLineHeight + VGAP * 2; // We need to define these widgets from right to left since the leftmost // one resizes as much as possible // Add Binary display of selected RAM cell - xpos = x + w - 11*myFontWidth - 22; - new StaticTextWidget(boss, lfont, xpos, ypos, "Bin"); - myBinValue = new DataGridWidget(boss, nfont, xpos + 3*myFontWidth + 5, ypos-2, + xpos = x + w - 9.6 * myFontWidth - 9; + s = new StaticTextWidget(boss, lfont, xpos, ypos, "%"); + myBinValue = new DataGridWidget(boss, nfont, s->getRight() + myFontWidth * 0.1, ypos-2, 1, 1, 8, 8, Common::Base::Fmt::_2); myBinValue->setTarget(this); myBinValue->setID(kRamBinID); // Add Decimal display of selected RAM cell - xpos -= 7*myFontWidth + 5 + 20; - new StaticTextWidget(boss, lfont, xpos, ypos, "Dec"); - myDecValue = new DataGridWidget(boss, nfont, xpos + 3*myFontWidth + 5, ypos-2, + xpos -= 6.5 * myFontWidth; + s = new StaticTextWidget(boss, lfont, xpos, ypos, "#"); + myDecValue = new DataGridWidget(boss, nfont, s->getRight(), ypos-2, 1, 1, 3, 8, Common::Base::Fmt::_10); myDecValue->setTarget(this); myDecValue->setID(kRamDecID); + // Add Hex display of selected RAM cell + xpos -= 4.5 * myFontWidth; + //s = new StaticTextWidget(boss, lfont, xpos, ypos, "$"); + myHexValue = new DataGridWidget(boss, nfont, xpos, ypos - 2, + 1, 1, 2, 8, Common::Base::Fmt::_16); + myHexValue->setTarget(this); + myHexValue->setID(kRamHexID); + + addFocusWidget(myHexValue); addFocusWidget(myDecValue); addFocusWidget(myBinValue); // Add Label of selected RAM cell - int xpos_r = xpos - 20; + int xpos_r = xpos - myFontWidth * 1.5; xpos = x; - new StaticTextWidget(boss, lfont, xpos, ypos, "Label"); - xpos += 5*myFontWidth + 5; + s = new StaticTextWidget(boss, lfont, xpos, ypos, "Label"); + xpos = s->getRight() + myFontWidth / 2; myLabel = new EditTextWidget(boss, nfont, xpos, ypos-2, xpos_r-xpos, myLineHeight); myLabel->setEditable(false, true); @@ -184,11 +195,16 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { switch(id) { - case kRamHexID: + case kRamGridID: addr = myRamGrid->getSelectedAddr(); value = myRamGrid->getSelectedValue(); break; + case kRamHexID: + addr = myRamGrid->getSelectedAddr(); + value = myHexValue->getSelectedValue(); + break; + case kRamDecID: addr = myRamGrid->getSelectedAddr(); value = myDecValue->getSelectedValue(); @@ -210,6 +226,7 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) myUndoValue = oldval; myRamGrid->setValueInternal(addr - myCurrentRamBank*myPageSize, value, true); + myHexValue->setValueInternal(0, value, true); myDecValue->setValueInternal(0, value, true); myBinValue->setValueInternal(0, value, true); @@ -222,10 +239,12 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { addr = myRamGrid->getSelectedAddr(); value = myRamGrid->getSelectedValue(); + bool changed = myRamGrid->getSelectedChanged(); myLabel->setText(getLabel(addr)); - myDecValue->setValueInternal(0, value, false); - myBinValue->setValueInternal(0, value, false); + myHexValue->setValueInternal(0, value, changed); + myDecValue->setValueInternal(0, value, changed); + myBinValue->setValueInternal(0, value, changed); break; } @@ -288,6 +307,7 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) void RamWidget::setOpsWidget(DataGridOpsWidget* w) { myRamGrid->setOpsWidget(w); + myHexValue->setOpsWidget(w); myBinValue->setOpsWidget(w); myDecValue->setOpsWidget(w); } @@ -296,6 +316,13 @@ void RamWidget::setOpsWidget(DataGridOpsWidget* w) void RamWidget::loadConfig() { fillGrid(true); + + int value = myRamGrid->getSelectedValue(); + bool changed = myRamGrid->getSelectedChanged(); + + myHexValue->setValueInternal(0, value, changed); + myDecValue->setValueInternal(0, value, changed); + myBinValue->setValueInternal(0, value, changed); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/RamWidget.hxx b/src/debugger/gui/RamWidget.hxx index 3562187fb..f7391c8e4 100644 --- a/src/debugger/gui/RamWidget.hxx +++ b/src/debugger/gui/RamWidget.hxx @@ -79,8 +79,10 @@ class RamWidget : public Widget, public CommandSender kRestartCmd = 'RWrs', kSValEntered = 'RWsv', kCValEntered = 'RWcv', + kRamGridID, kRamHexID, kRamDecID, + kRamSignID, kRamBinID }; @@ -96,7 +98,9 @@ class RamWidget : public Widget, public CommandSender std::array myRamLabels{nullptr}; DataGridWidget* myRamGrid{nullptr}; + DataGridWidget* myHexValue{nullptr}; DataGridWidget* myDecValue{nullptr}; + DataGridWidget* mySignValue{nullptr}; DataGridWidget* myBinValue{nullptr}; EditTextWidget* myLabel{nullptr}; From 9ffa0aeb3920aa7443e0d9bbf1622fffd148cb16 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 12 Oct 2020 21:30:03 +0200 Subject: [PATCH 075/263] implemented WSYNC part of #165 (TODO: doc) refined TiaInfoWidget, CpuWidget and RamWidget --- src/debugger/Debugger.cxx | 3 +- src/debugger/Debugger.hxx | 2 +- src/debugger/TIADebug.cxx | 8 +++ src/debugger/TIADebug.hxx | 1 + src/debugger/gui/CpuWidget.cxx | 23 ++++--- src/debugger/gui/DebuggerDialog.cxx | 2 +- src/debugger/gui/RamWidget.cxx | 4 +- src/debugger/gui/TiaInfoWidget.cxx | 94 ++++++++++++++--------------- src/debugger/gui/TiaInfoWidget.hxx | 5 +- src/emucore/tia/TIA.cxx | 5 ++ src/emucore/tia/TIA.hxx | 12 ++++ src/yacc/YaccParser.cxx | 2 + 12 files changed, 97 insertions(+), 64 deletions(-) diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index d5e56a98a..78e59aa2a 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -877,7 +877,7 @@ std::array Debugger::ourBuiltinFunctions = { { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Names are defined here, but processed in YaccParser -std::array Debugger::ourPseudoRegisters = { { +std::array Debugger::ourPseudoRegisters = { { // Debugger::PseudoRegister Debugger::ourPseudoRegisters[NUM_PSEUDO_REGS] = { { "_bank", "Currently selected bank" }, { "_cclocks", "Color clocks on current scanline" }, @@ -885,6 +885,7 @@ std::array Debugger::ourPseudoRegisters = { { { "_cycleslo", "Lower 32 bits of number of cycles since emulation started" }, { "_fcount", "Number of frames since emulation started" }, { "_fcycles", "Number of cycles since frame started" }, + { "_fwsynccycles", "Number of cycles skipped by WSYNC since frame started" }, { "_icycles", "Number of cycles of last instruction" }, { "_scan", "Current scanline count" }, { "_scanend", "Scanline count at end of last frame" }, diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index d594820c6..8ba5c626f 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -363,7 +363,7 @@ class Debugger : public DialogContainer string name, help; }; static std::array ourBuiltinFunctions; - static std::array ourPseudoRegisters; + static std::array ourPseudoRegisters; private: // rewind/unwind n states diff --git a/src/debugger/TIADebug.cxx b/src/debugger/TIADebug.cxx index abde49c69..01b870d68 100644 --- a/src/debugger/TIADebug.cxx +++ b/src/debugger/TIADebug.cxx @@ -149,6 +149,7 @@ const DebuggerState& TIADebug::getState() myState.info.push_back(scanlines()); myState.info.push_back(scanlinesLastFrame()); myState.info.push_back(clocksThisLine()); + myState.info.push_back(frameWsyncCycles()); return myState; } @@ -258,6 +259,7 @@ void TIADebug::saveOldState() myOldState.info.push_back(scanlines()); myOldState.info.push_back(scanlinesLastFrame()); myOldState.info.push_back(clocksThisLine()); + myOldState.info.push_back(frameWsyncCycles()); } /* the set methods now use mySystem.poke(). This will save us the @@ -909,6 +911,12 @@ int TIADebug::frameCycles() const return myTIA.frameCycles(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int TIADebug::frameWsyncCycles() const +{ + return myTIA.frameWSyncCycles(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int TIADebug::cyclesLo() const { diff --git a/src/debugger/TIADebug.hxx b/src/debugger/TIADebug.hxx index cf6171d17..0a2e21663 100644 --- a/src/debugger/TIADebug.hxx +++ b/src/debugger/TIADebug.hxx @@ -169,6 +169,7 @@ class TIADebug : public DebuggerSystem int scanlinesLastFrame() const; int frameCount() const; int frameCycles() const; + int frameWsyncCycles() const; int cyclesLo() const; int cyclesHi() const; int clocksThisLine() const; diff --git a/src/debugger/gui/CpuWidget.cxx b/src/debugger/gui/CpuWidget.cxx index 3493e53f8..31f939f01 100644 --- a/src/debugger/gui/CpuWidget.cxx +++ b/src/debugger/gui/CpuWidget.cxx @@ -39,6 +39,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n const int fontWidth = lfont.getMaxCharWidth(), fontHeight = lfont.getFontHeight(), lineHeight = lfont.getLineHeight(); + const int VGAP = 2; int xpos, ypos, lwidth; // Create a 1x1 grid with label for the PC register @@ -58,7 +59,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n myPCLabel->setEditable(false, true); // Create a 1x4 grid with labels for the other CPU registers - xpos = x + lwidth; ypos += myPCGrid->getHeight() + 1; + xpos = x + lwidth; ypos = myPCGrid->getBottom() + VGAP; myCpuGrid = new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 2, 8, Common::Base::Fmt::_16); myCpuGrid->setTarget(this); @@ -88,17 +89,11 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n int src_y = ypos, src_w = (max_w - xpos + x) - 10; for(int i = 0; i < 4; ++i) { - myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w, - fontHeight+1, ""); + myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w, fontHeight + 1); myCpuDataSrc[i]->setEditable(false, true); - src_y += fontHeight+2; + src_y += fontHeight + 2; } - // Last write destination address - new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, src_y + 4, "Dest"); - myCpuDataDest = new EditTextWidget(boss, nfont, xpos, src_y + 2, src_w, fontHeight+1); - myCpuDataDest->setEditable(false, true); - // Add labels for other CPU registers xpos = x; const std::array labels = { "SP ", "A ", "X ", "Y " }; @@ -121,7 +116,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n } // Create a bitfield widget for changing the processor status - xpos = x; ypos += 4*lineHeight + 2; + xpos = x; ypos = myCpuGrid->getBottom() + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 2, lwidth-2, fontHeight, "PS ", TextAlign::Left); myPSRegister = new ToggleBitWidget(boss, nfont, xpos+lwidth, ypos, 8, 1); @@ -140,6 +135,14 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n } myPSRegister->setList(off, on); + // Last write destination address + xpos = myCpuDataSrc[0]->getLeft(); + new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, ypos + 2, "Dest"); + myCpuDataDest = new EditTextWidget(boss, nfont, xpos, ypos, src_w, fontHeight + 1); + myCpuDataDest->setEditable(false, true); + + + _h = ypos + myPSRegister->getHeight() - y; } diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index be9ad7515..d7855e2f5 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -589,7 +589,7 @@ void DebuggerDialog::addRomArea() DataGridOpsWidget* ops = new DataGridOpsWidget(this, *myLFont, xpos, ypos); int max_w = xpos - r.x() - 10; - xpos = r.x() + 10; ypos = 10; + xpos = r.x() + 10; ypos = 5; myCpu = new CpuWidget(this, *myLFont, *myNFont, xpos, ypos, max_w); addToFocusList(myCpu->getFocusList()); diff --git a/src/debugger/gui/RamWidget.cxx b/src/debugger/gui/RamWidget.cxx index de09949e4..28a3d3ce8 100644 --- a/src/debugger/gui/RamWidget.cxx +++ b/src/debugger/gui/RamWidget.cxx @@ -53,8 +53,9 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n // Add RAM grid (with scrollbar) int xpos = x + _font.getStringWidth("xxxx"); + bool useScrollbar = ramsize / numrows > 16; myRamGrid = new DataGridWidget(_boss, _nfont, xpos, ypos, - 16, myNumRows, 2, 8, Common::Base::Fmt::_16, true); + 16, myNumRows, 2, 8, Common::Base::Fmt::_16, useScrollbar); myRamGrid->setTarget(this); myRamGrid->setID(kRamGridID); addFocusWidget(myRamGrid); @@ -144,7 +145,6 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n // Add Hex display of selected RAM cell xpos -= 4.5 * myFontWidth; - //s = new StaticTextWidget(boss, lfont, xpos, ypos, "$"); myHexValue = new DataGridWidget(boss, nfont, xpos, ypos - 2, 1, 1, 2, 8, Common::Base::Fmt::_16); myHexValue->setTarget(this); diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index 21681d2c0..35998d498 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -36,85 +36,82 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, { bool longstr = 11 + 32 * lfont.getMaxCharWidth() + 9 + EditTextWidget::calcWidth(lfont) * 3 <= max_w; - const int VGAP = 5; + const int VGAP = lfont.getLineHeight() / 4; + const int VBORDER = 5 + 1; x += 11; const int lineHeight = lfont.getLineHeight(); - int xpos = x, ypos = y + 10; - int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle " : "F. Cycle "); + int xpos = x, ypos = y + VBORDER; + int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle" : "F. Cycle") + _fontWidth * 0.5; + int l2width = lwidth - lfont.getMaxCharWidth() * 3; int fwidth = EditTextWidget::calcWidth(lfont, 5); int twidth = EditTextWidget::calcWidth(lfont, 8); - // Add frame info - // 1st column - new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, - longstr ? "Frame Count " : "Frame ", - TextAlign::Left); - xpos += lwidth; - myFrameCount = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, ""); + // Left column + // Left: Frame Count + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Count " : "Frame "); + myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myFrameCount->setEditable(false, true); + // Left: Frame Cycle xpos = x; ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, - longstr ? "Frame Cycle " : "F. Cycle ", - TextAlign::Left); - xpos += lwidth; - myFrameCycles = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, ""); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycle " : "F. Cycle "); + myFrameCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myFrameCycles->setEditable(false, true); - xpos = x; ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, - "Total ", TextAlign::Left); - xpos += lfont.getStringWidth("Total "); - myTotalCycles = new EditTextWidget(boss, nfont, xpos, ypos - 1, twidth, lineHeight, ""); + // Left: WSync Cycles + ypos += lineHeight + VGAP; + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycl. " : "WSync C. "); + myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myWSyncCylces->setEditable(false, true); + + // Left: Total Cycles + ypos += lineHeight + VGAP; + new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total "); + myTotalCycles = new EditTextWidget(boss, nfont, xpos + l2width, ypos - 1, twidth, lineHeight); myTotalCycles->setEditable(false, true); - xpos = x; ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, - "Delta ", TextAlign::Left); - xpos = x + lfont.getStringWidth("Delta "); - myDeltaCycles = new EditTextWidget(boss, nfont, xpos, ypos - 1, twidth, lineHeight, ""); + // Left: Delta Cycles + ypos += lineHeight + VGAP; + new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta "); + myDeltaCycles = new EditTextWidget(boss, nfont, xpos + l2width, ypos - 1, twidth, lineHeight); myDeltaCycles->setEditable(false, true); - // 2nd column - xpos = x + lwidth + myFrameCycles->getWidth() + 9; ypos = y + 10; + // Right column + xpos = myFrameCycles->getRight() + _fontWidth * 1.25; ypos = y + VBORDER; lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos "); fwidth = EditTextWidget::calcWidth(lfont, 3); - new StaticTextWidget(boss, lfont, xpos, ypos, longstr ? "Scanline" : "Scn Ln"); - myScanlineCountLast = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, - lineHeight, ""); + // Right: Scanline + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scanline" : "Scn Ln"); + myScanlineCountLast = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myScanlineCountLast->setEditable(false, true); myScanlineCount = new EditTextWidget(boss, nfont, - xpos+lwidth - myScanlineCountLast->getWidth() - 2, ypos-1, fwidth, - lineHeight, ""); + xpos + lwidth - myScanlineCountLast->getWidth() - 2, ypos - 1, + fwidth, lineHeight); myScanlineCount->setEditable(false, true); + // Right: Scan Cycle ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, - longstr ? "Scan Cycle " : "Scn Cycle", TextAlign::Left); - myScanlineCycles = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, - lineHeight, ""); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle " : "Scn Cycle"); + myScanlineCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myScanlineCycles->setEditable(false, true); + // Right: Pixel Pos ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, - "Pixel Pos ", TextAlign::Left); - myPixelPosition = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, - lineHeight, ""); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Pixel Pos "); + myPixelPosition = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myPixelPosition->setEditable(false, true); + // Right: Color Clock ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, - longstr ? "Color Clock " : "Color Clk ", TextAlign::Left); - - myColorClocks = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, - lineHeight, ""); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Color Clock " : "Color Clk "); + myColorClocks = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myColorClocks->setEditable(false, true); // Calculate actual dimensions - _w = myColorClocks->getAbsX() + myColorClocks->getWidth() - x; - _h = ypos + lineHeight; + _w = myColorClocks->getRight() - x; + _h = myDeltaCycles->getBottom(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -159,4 +156,7 @@ void TiaInfoWidget::loadConfig() clk != oldTia.info[6]); myColorClocks->setText(Common::Base::toString(clk, Common::Base::Fmt::_10), clk != oldTia.info[6]); + + myWSyncCylces->setText(Common::Base::toString(tia.frameWsyncCycles(), Common::Base::Fmt::_10_5), + tia.frameWsyncCycles() != oldTia.info[7]); } diff --git a/src/debugger/gui/TiaInfoWidget.hxx b/src/debugger/gui/TiaInfoWidget.hxx index 2f7796162..c0e029879 100644 --- a/src/debugger/gui/TiaInfoWidget.hxx +++ b/src/debugger/gui/TiaInfoWidget.hxx @@ -38,12 +38,13 @@ class TiaInfoWidget : public Widget, public CommandSender private: EditTextWidget* myFrameCount{nullptr}; EditTextWidget* myFrameCycles{nullptr}; - EditTextWidget* myTotalCycles{ nullptr }; + EditTextWidget* myTotalCycles{nullptr}; + EditTextWidget* myDeltaCycles{nullptr}; + EditTextWidget* myWSyncCylces{nullptr}; EditTextWidget* myScanlineCount{nullptr}; EditTextWidget* myScanlineCountLast{nullptr}; EditTextWidget* myScanlineCycles{nullptr}; - EditTextWidget* myDeltaCycles{ nullptr }; EditTextWidget* myPixelPosition{nullptr}; EditTextWidget* myColorClocks{nullptr}; diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index 78a44fc55..e0f6e2dda 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -163,6 +163,7 @@ void TIA::initialize() myDelayQueue.reset(); myCyclesAtFrameStart = 0; + myFrameWsyncCycles = 0; if (myFrameManager) myFrameManager->reset(); @@ -279,6 +280,7 @@ bool TIA::save(Serializer& out) const out.putByteArray(myShadowRegisters.data(), myShadowRegisters.size()); out.putLong(myCyclesAtFrameStart); + out.putLong(myFrameWsyncCycles); out.putInt(myFrameBufferScanlines); out.putInt(myFrontBufferScanlines); @@ -351,6 +353,7 @@ bool TIA::load(Serializer& in) in.getByteArray(myShadowRegisters.data(), myShadowRegisters.size()); myCyclesAtFrameStart = in.getLong(); + myFrameWsyncCycles = in.getLong(); myFrameBufferScanlines = in.getInt(); myFrontBufferScanlines = in.getInt(); @@ -1304,6 +1307,7 @@ void TIA::updateEmulation() void TIA::onFrameStart() { myXAtRenderingStart = 0; + myFrameWsyncCycles = 0; // Check for colour-loss emulation if (myColorLossEnabled) @@ -1351,6 +1355,7 @@ void TIA::onHalt() { mySubClock += (TIAConstants::H_CLOCKS - myHctr) % TIAConstants::H_CLOCKS; mySystem->incrementCycles(mySubClock / TIAConstants::CYCLE_CLOCKS); + myFrameWsyncCycles += mySubClock / TIAConstants::CYCLE_CLOCKS; mySubClock %= TIAConstants::CYCLE_CLOCKS; } diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index 18609f087..a7c262117 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -334,6 +334,13 @@ class TIA : public Device return uInt32(mySystem->cycles() - myCyclesAtFrameStart); } + /** + Answers the system cycles used by WSYNC from the start of the current frame. + */ + uInt32 frameWSyncCycles() const { + return uInt32(myFrameWsyncCycles); + } + /** * Get the CPU cycles since the last dump ports change. * @@ -939,6 +946,11 @@ class TIA : public Device */ uInt64 myCyclesAtFrameStart{0}; + /** + * System cycles used by WSYNC during current frame. + */ + uInt64 myFrameWsyncCycles{0}; + /** * The frame manager can change during our lifetime, so we buffer those two. */ diff --git a/src/yacc/YaccParser.cxx b/src/yacc/YaccParser.cxx index 4de3c965f..f55450ad1 100644 --- a/src/yacc/YaccParser.cxx +++ b/src/yacc/YaccParser.cxx @@ -254,6 +254,8 @@ TiaMethod getTiaSpecial(char* ch) return &TIADebug::frameCount; else if(BSPF::equalsIgnoreCase(ch, "_fcycles")) return &TIADebug::frameCycles; + else if(BSPF::equalsIgnoreCase(ch, "_fwsynccycles")) + return &TIADebug::frameWsyncCycles; else if(BSPF::equalsIgnoreCase(ch, "_cyclesLo")) return &TIADebug::cyclesLo; else if(BSPF::equalsIgnoreCase(ch, "_cyclesHi")) From 9bcbf33d136661b8d576423df8849d6bae5fca7d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 13 Oct 2020 09:30:04 +0200 Subject: [PATCH 076/263] fixed "no debugger" project files --- src/windows/Stella.vcxproj | 16 ++++++++++++---- src/windows/Stella.vcxproj.filters | 12 ++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index bf2c1c37d..5d3085e71 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -620,7 +620,9 @@ true - + + true + true @@ -702,7 +704,9 @@ true - + + true + true @@ -1635,7 +1639,9 @@ true - + + true + true @@ -1723,7 +1729,9 @@ true - + + true + true diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index ce790b6e7..2431ba04f 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1008,9 +1008,6 @@ Source Files\emucore - - Source Files - Source Files\emucore @@ -1026,6 +1023,9 @@ Source Files\gui + + Source Files\debugger + @@ -2084,9 +2084,6 @@ Header Files\emucore - - Header Files - Header Files\emucore @@ -2108,6 +2105,9 @@ Header Files + + Header Files\debugger + From f48aa3a43de812fda5349ce745dc3f4a9e1fb195 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 13 Oct 2020 15:11:35 +0200 Subject: [PATCH 077/263] fully resolved #165 (added timer read cycles count) refined TiaInfoWidget again added doc --- docs/debugger.html | 18 ++++-- docs/graphics/debugger_cpuregs.png | Bin 1795 -> 1548 bytes docs/graphics/debugger_main.png | Bin 63710 -> 78817 bytes docs/graphics/debugger_ram.png | Bin 5185 -> 3163 bytes docs/graphics/debugger_tiainfo.png | Bin 1323 -> 1394 bytes docs/graphics/resources/debugger_main.pdn | Bin 205235 -> 274816 bytes src/debugger/Debugger.cxx | 3 +- src/debugger/Debugger.hxx | 2 +- src/debugger/RiotDebug.cxx | 10 +++ src/debugger/RiotDebug.hxx | 3 + src/debugger/gui/DebuggerDialog.cxx | 19 +++--- src/debugger/gui/TiaInfoWidget.cxx | 72 ++++++++++++++-------- src/debugger/gui/TiaInfoWidget.hxx | 1 + src/emucore/M6532.cxx | 10 +++ src/emucore/M6532.hxx | 7 +++ src/emucore/tia/TIA.cxx | 16 ++++- src/emucore/tia/TIA.hxx | 6 +- src/yacc/YaccParser.cxx | 2 + 18 files changed, 125 insertions(+), 44 deletions(-) diff --git a/docs/debugger.html b/docs/debugger.html index 9ce69b949..4c0360a95 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -753,6 +753,8 @@ that holds 'number of scanlines' on an actual console).

    + + @@ -1137,12 +1139,16 @@ as illustrated:

    The indicators are as follows (note that all these are read-only):

      -
    • Frame Count: The number of frames since this ROM was loaded or reset.
    • Frame Cycle: The number of CPU cycles that have been executed this frame since VSYNC was cleared at scanline 0.
    • +
    • WSync Cycl.: The number of CPU cycles that have been skipped by WSYNC this frame since +VSYNC was cleared at scanline 0.
    • +
    • Timer Cycl.: The number of CPU cycles (approximately) that have been used by timer read loops since +VSYNC was cleared at scanline 0.
    • Total: The total number of CPU cycles since this ROM was loaded or reset.
    • Delta: The number of CPU cycles that have been executed since the last debugger interrupt.
    • +
    • Frame Cnt.: The number of frames since this ROM was loaded or reset.
    • Scanline: The scanline that's currently being drawn, and the count from the previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for 3 scanlines, as per the Stella Programmer's Guide).
    • @@ -1275,10 +1281,9 @@ are lost (they will NOT end up in the Carry flag).

      This is a spreadsheet-like GUI for inspecting and changing the contents of the 2600's zero-page RAM.

      You can navigate with either the mouse or the keyboard arrow keys. -To change a RAM location, either double-click on it or press Enter while -it's highlighted. Enter the new value (hex only for now, sorry), then -press Enter to make the change. If you change your mind, press Escape -and the original value will be restored. The currently selected RAM cell +To change a RAM location, either double-click on it or press 'Enter' while +it's highlighted. Enter the new value (hex, other formats using the bottom textboxes), then +press 'Enter' to make the change. The currently selected RAM cell can also be changed by using the Data Operations Buttons or the associated shortcut keys.

      @@ -1289,7 +1294,8 @@ more comprehensive. It will undo all operations on all cells since you first made a change.

      The UI objects at the bottom refer to the currently selected RAM cell. The 'Label' textbox shows the label attached to this RAM location (if any), -and the other two textboxes show the decimal and binary equivalent value.

      +and the other three textboxes show the hex, decimal and binary equivalent value. +The values can be edited here too.

      The remaining buttons to the right are further explained in the next section.

      diff --git a/docs/graphics/debugger_cpuregs.png b/docs/graphics/debugger_cpuregs.png index feb238c1b698502214f98abc61790c71f023076f..4d868df9230cf6fe56ada9c77a3333ef056ab8d5 100644 GIT binary patch delta 1536 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 Hu0mjf={F~# diff --git a/docs/graphics/debugger_main.png b/docs/graphics/debugger_main.png index c59f1a345eb08d8f3c1ec6394ba8aac369391964..2064cd85a26a1ed33153a40cdcc8414b19038c2a 100644 GIT binary patch literal 78817 zcmb5W1z1$kw>~@=v>+f|BHc(g2r_gt4$`BfNDbYn3?(HkDGuczp>*R=(j_7-4bt84 zKZC!z_qq3e&v%|j8P3_~%sy+cc;B_wCR|5L`3^n}J_rQ5qpI>)4+OgP6$HBZ7WW2l zru(yu67U1dRZm#~RNP0m3jA`*=8@(j5a>$`!8z*$iT~N{Q~dY31Z5B8Au%yHm6HXM?xeXlp4pu%0}8z8izlm(Ce57)yn%hgRR}= z&LKRPbmxh}r;e;?!qDGIBL^$GI*KyE?`S>n)GC88J!psynx)-L2C!K7P z|Na`38(ez#`n<&_CZ1c@pA28%5@20_N}@q4Tz?44eR86jvm9_nq~`d%&PLi+OwIA; z^%W4?Ch)v|e1fbmvlYNKSM5N3O~d1!qx#EoGK!iqS?6B_{ALTNjO|GRbJt#1BDo`Y zXLSTuXr{-WYnJL&(*l{4u$D`&tE(7-F9^+j&L=$^a37LDj{?K``2t7Wp_6HXBG0)I8CN9T+eusL)`kA0v z-=zHaWb-fX9}?&Y)Yy9bA}EnqeZ4Wuef_%fcOou6c0z~|z)e>rO*!`m9QX&=$n_E@ z9E*obou{53)|{)4I$!RJWzaU+CvOCI6#MSs%vBxt)utS|pRhV^iS(T|yH5M{3dNKV z-Ty1*h&@E$$ywm#o8-0cvCkE_2%VVn)`WS^SH>tA_fwZ0#akU}M;#d8KX9Bps+Nd+ zHoE!hPYwz{?PgAA=exYwFukSZ0+n8(HaYkMu$5VH z3hp9*QJOlloHJT&0YCfw7TN>vdEcmfy-X?6;e=A*c&aQs3%|DRIC-_KnP2%p%jMGy z3@NG2;CzS&g(PolliP?SEg2hKRdy!q*w@R7ALw{5`Eofq`|tOjC!ycU`6P{Aqz+SV zNu00jlq}b|GWyTbX6@zGQYM(ed&wbXwF_h=W^U&Goa;Dk6p$evD5hsutMuhsmdfRXA%bEe$e|Kh0HKxzCb>C@%@p z2QC5BiS%-r*H1{NBRG;-v1`Rz%4^BKs%d&Rwxd{XA(h*sp1ktZTY&vXeX6c(xwXj4 z`Hvg2K8J_Ni441u@mkf#$a~8#17l`{v}2)KvWM^A`UZ(?@h(73`OF%qvqqRgWnFc@ zO5SOd^6V5zb|MyEEPGL~^{B+VeJ*cBmiAaFa|BV*k@@UlbUo`Xb-zhZ(db_tlULn8 z!#g-5Gk{8Q(JbDvz+(`rXo z3=G@&!v2)rhB34Kk1>w7W5Xs1M#LaBl7My%_II;H<~D(wbKL8Ti%2@0-Q@8s-_x{e ztVGv0rzMrx@!)Se>rI|40cYyb$tWKLiPUt<=G#{1{tinHB$xQ7!0Gb4g16p?CF##E!?8 z1@`wujEoXD1#oZ)sAWD~sCjE!ZK09+uNX>h^lR9aam}KN8$!DMII!|Q9*Tw0d~W)! zQT63kC0)R?4Slt4SJKUAo!Wx*va)dO>-V-8`#-~2NK86bO8t0Dy2RYEzKPbD&tWHD zvO4huyj&|}T=-9@E1gR}t$3L`doqlgQDS&_9zx?&pPKoeL)LU~@3{$7Z!wX*ugfX0`z((G+RA!*gpadHWQ-3m5Vv-w%cD`$*PG_BSs-j^jqqQ&VO(K5ii6 zfW-APGyA?-G3~a7qWDC)20Ihk*8bGq4r)|AZ&y{*)9K!CA28TZ)IUB^HpB%*twKa> zSekmX$RE<~M6d;zkSH&8e2@iN~1@R50 z8uEWdrp1}qWz?I!>8z88SMHPFf2opPyo)d4LN0_-YuE1$s|JS;pX#{JDghztM`t46 z_L9Y@0BAqd39JgwC8%vJT+}SldHYi>T$i@UNb6KOcsW>|rDo`xHZxiw$m-!~t@+QL zuYB6?HOxw=KeQ|?R8sC!fB<*OKC{hTT$VW?`NwP4`ojqa_E?RHnz zgG@^VBS77+lL!6z&Ak20I3~ImvDk#_i73bX0wT*gmWY7wUl`pB>qtuDO63>FgMS@CA9D04f<%P^P zmozPBQMt^Q<&@%YUb?Z5TNt*!507)B;RASS=;Tf+c90RKKN=8q_<^J>Ux?IuG) znf8rLNRtUUrF9uz+|8`r)pjD6S$2;9o~@dRFwM!~KKAOT>B#7Eg49X zB|Ej1*sMSYqLov!;2p1CFa6fziz+2G@0a->BMjBTvGtabW{|~L{f|PXMZ(SIdn-n+XlO>yWu91tsB48b+8Zf>&4?q48yaS>ws`5<*y^jC^;UMcwtEspxl?1hqq=0-5gMcxwJ!qO@ckx?1GlHq zSdV9n0U28C-lh2ZY&6fy?c=r=7AS|~aO|sGMSlw~vf9>g1+K1`g(c}1j8HsY4wU_| z_~c3E#rj)QN8cJgm}z3mt~@X~0GT8AN}W5Ic-AwBa2@D=AU5{8U}Jz2PbuuX!m5i| zj$pb?^(Nz_7w9ZHjDR+{s(vQZoF-B$M+t5P6JTjqeJYH++g%4UDZWN?G!&e$H~%MgU^iTv;?dM1HsHrVDvd`M}j zqMIxU#UTM~*6=O`AG?p9YYm#G1u4|rxjZcXD;ob%$J8?h3_0#nuqhad^H#8@)0E@A zO8vuSS$i5HvhO-`Hr1Xs^}<^V{X7TD)X{E5NIo>C)EQUOYZykG9Qw)xx>za=h<Bm8zr|q@zYsxzCjAMKz=V+IFpsfShU7PM*MY=#J#1bZ z@VZZuJ#9C}Tf}P|+6w*z(-~|GD%m_hNRB+ooqyWdx~@u7m*NJgT1ZfXlYd(sNduGf zq?vj&PAq=#x+YVpvm%>6%e0qRSU;lbWr(mV9qM#;(FHUqGGtt%fG?$jR4hE2t)C{O zUbY#6WW;librZ<;53WrXyl$NGncGR9JoNJTcxCYb5S;gpan=w=jU&kFLsQo&v8$VY z95=lp)A0A?85Lm!16i2gZFa5-M*>OJ8}`&-tms@YwlqQt&U+df$$_B$xWI zeYL9tR!P!->&(}SHQi)QwsV1XCPbFpG)e-GI)4!OLO6|5do;e~q_z-hJl2)mx;*pH zOr1f;ySkwx!^Mz1V>YL-9nCJ`gNou>iHXKbmJp<4W6Npq>V#;Jq0#Nf0rzoUolbw~ z>mPaAKQ5PQasmCsd_0{9Dvo_UFP*T$Xk$LUev&E;j%6Hv)^THn3%tZ zCDrjTXhJ1vl)H8QyY2MJJE5PQjlr$zu-}#jQDN-N?+BGeNGDc4(Lg|;)x3ai$H%w? zv;ifR#gXj45|_@|SJxMtSB>4a0Q$?I6orCpu4zJH^5_3?M_ z_}0bXz4q1IUKC0?gIJs;Re-%p=Dw_*-?U^aQ+yvT62%Q?YtcxcB=f13rn#hsRCuYm zEpa~ACI&6#r>E$c>32~(J=6OIfw14D5N*!3pt>8v>gtXTZDP)VPsr@6scx`8i4zs-nF3d`Z;%-+5+B57v;45JE%Qz8(DrAR zBzu+;sOWVthkh~aM)xczd3rYl2dAdz+zN}{WN`_vmrPK1`)y;u8i%96KtF9#r0+#p zPwAw;%nltPt3fwN-%}4fEx0rodbRO&4;RKnEg1IVx&Nm9qdgy11w-7@$7u4n3!7;( z(_9r3@Cv<4`&t{T8H{Ov;lyUThICaqb^5EHcm5Ytu8h&?G4`M0ck z${+NeHFuwnnrccj_6L?yQ+!;!X*%xoZG9xu`9TBH* zyh&aYe7db28F{JxY8F$-W9We?k>kJo*U)6SO=;Stm_63bYz@N8b7r*AW zx*>Do@+I_n*8 z8QwkHqKF$kzaW!4G$$UnkC`yvbG>rkpD(`L+A2Qj?v0t=Z41>IiJ|lB&1zb4o&0Rf z+pk*XNs!OsQ*{?Mt2Z#qNbp8J7%@Du_Etrm4K`aBa3NH#s{P`2W~iXeNKGTLemmn! zWyFV*b2ZPv4>KeEu1f#oD(S!ty;iHX&eWY`h8)&cO!?3DnTQ((9o$fhK$H(Fb@pD3 zd2gz+kjMh+V>iF@+*Pdy0W55(@laMEG3_EdnhsY)QL} zPy}C<@IF8}0EUF2nIsfwlfkSP!H63$*aJXZugNlBX&F_)X5)~1sxYR;4}iAZAO7ke zLqN~Z_|+1Hp@bYYQ5)3*>cx&sMk&!YtYl^EcI)3$z$Xp0toa6Ug}=-eMLi~kQJ@co z)yB92-qproM-+T9SPYB%9qLbNFZ{y^=$&*u2~J{Hy;v3HT2$4lzq+$?JI-1UfkhkO zu>P4e+U}I>hf%w}U;4Hv{)8HT_x`z@K0yV!i?3ZBN>e?lv+vhFXZVzg9D)QqN5Q#gMM^6;&12}Y3i#|k_nF;jW&^tBkR@I0hl zxND0Qn}|Tf@wvex4(VBj7Xl0U*};rp!MW+e@^o^v0&#|Reb_w^+si$Bxyw&tj+bfi zvTK!CNgxE4WX;fRB#P|oPhz3hM{7!)EwMq5(J{7kabhjIzEKEm_`U%x1eBXyZ95hx z1;6b{;2BhhAOw`t%5ICoXGNm8c~58QbKcuN8zxTzi3cB9ODrkc=*wb8!x%q8S^$se z@sjMP539oxqwIrKq0bqBXurpL66ESQ(fmUOza6vl7eAvL2>nu!1dLXby!*Q1_x=^f zut3eNYo-9M|AayMpjf+O+WX1|O&UJ{wAR`T#Qn@n&o_nK@aGYN-orOJW{TJuwpgJL zah+mXv_U?v0R(^P<((5>_>0d-T>8BkUc4P@;(fO*eYD+*vpGG{2pPSUD%`#EctxCT zA*+RsUpw&zmzK%*NK~;3A)PfoQ_Kyk5I++Tc4fzV8-4sekOKy|%Na4OTAA2!OR%lI z%$zQ#a253KtjgAI1KB8UX^EC~iX-B;KQ-OQrNmK%{L?lKMx zMq+mUGhbM(m{wjHY~H1AiB8kU<4pl@&bnyC+QCbW(;j{%JUnq1CLvVFf@bqX`Dze5 z^N)9L-NQC-LPmQgSdd3*`%`J282FYj=|L|UwHutbr^Dl|%5LMfZS7R` z>^n6L%A+j#hngpzC+yGlN~eKOd$gT)r>)yRua_~gCn3%fu_4U1?Tz)QmAq|m0nN|N z#MgZ`-P#W-D2F%X3d@W)VxViQE43LpOum!3C5})E183Z{_g4+Vnk;X|{XK7vW^CzVE4K6c5d}U?;o~R`2ZxdZ3lt zC1P!z50meD_J@%QFmZR@aajp0T zHA)o9Qs{G6^ORJ$0SN^Kd%ZTU4jVo>fKG#MDVd6f5n@?ZOm|8==bB|Lv<(&PP zkQ~Fzhd1kXkDclLq{5F1J%%SFr3#|kd+k%9v$kB zHKk1)WG%Pj+v43{!HOcY(ndy1X}m}yVsOxz;J%&F?>NKK{*b97G^hE9g28*+!4X-p z$7ej;G3YL(s(5&glLljoBuhM=R!Dx6{fkmm=7HvnF$V%h%f|$H_4L%2prv;o#dW)} zYJfTWLvj^$gC6#*DAN?TzaY!$v;qLz;>COnZJpQz+u2PNB4Mklyo=KNkJ#w?q@O>T zzV9Pc(q&DkP#qkMXm3Q5>Rr!>NDkiq7EkpRZ1z)r=7OlvMD`RjPl(L z9ucF|y+4!P1V$C11fG1ehm*OhbFw)d3B8|UJJlQS_;b}ij6%Ki(HJYI9*!mD*N!w( zj0+No#KQuyy}H50UlXwbab*5w2~%Z0dj3GHuThAe)^#|<4fL)EsCY^X@egw%-q|K z*)FandnhCDJb3=MBNGUeGbDBjpqBAiso?aS96!=-mpIZ+mM8A7LlR8|oG7QQnK8uj z{xkdaqBvljHwO`rlheY&c^+r7s^CM;YTD;L=OEfP)v|y}lQ%Rh*j7JpiE~L5WdyCz z-3|`JLoRH*>zP=e7_SI*flovLa7SWjTrs-uF}^#hNUftRE_^Ir*yG_UYBerYJAa%D zw1PivY{)@xpRqk#GTdKkX_DJ(^Bzd`z9gGAuD-S6m$W^tU>2v=v+m##7Cq{#Plt1J zqSBP(z0wXBGNK~TDVy$-?83h46U|5}2s*P#Ow77JHrO}ajXZ6|mtZ(BX2@7eVFNE8 zn@{YXOqR=$8NyoRmoI@0=d~Ik0HD4K@c!8=H&!%qI2(wptsUJ23O+{JLpxf0Jo|^m zVuftrNUlMM;rFv=(+upUtV{G1Y@%tgU$l;M22~Xee_^B1@Z4Lka&JfA5_G=;JpMh> zfc+|kT)7bljLGQ*nB1P4;*YcXz?abYAN!xjH8Ownncu+XhYtuP&?A6}CjNvOu4L%- zxrTTp--3E0G>%YnGA|&cX_{fOv$0`XG}llji2%k_j(Ivyxx$9Kw^|^o8;>CT^Y?=x z>GYgDn>O$4{1*n{ttX){MYj-do3H0wLoh>?V?WX@m!sfOa7uO-wj8(u)#qgH!#Yd1@l;6iQMm$g|_p(uoutShfI4 zg%JkZaAz>1g@pvr=%um}iSSP2;ZQM{1_SR7F}h2oU}zW(q(b)T7T~U-O-J-JzrU&m z)_Wn;PK|Shc6@d;JPPEELJ;tJ8hT%G)hAL}c^z?rfq1lT=XWz;)9-njA_yrcLXv}J z_Xa!AIukrD>76@TUSa=4DpG`R7_5R3{-5yQ4|VUUg$Qp>KT2~n{I#a6M)6=Lo|j2? zCRy`ze#EUaEi}3+y)^c5jAS~?rwl?nAD)W6<);s2I`f18-JoXU+3&I%{yw0s=up<` z!qy=*%LKrdiD|TFMpU&Y6}C**J&HMB0x9sfxaefuWP`-IsOay}A3H_#>apWYD&|B! zEO6a06H+av0a={x?6DtXaUwHg^%qMzU1x+^)oE? z4&Q{G2Sb~=!C)gQ9e0RcZgA27Z!m%tP}ibH{)i-Oy zuq0yPjN;4y0<=I}FaMBz&S9|r&0s`kQW^e{;5ICp&kys^0A1V#rAIK;KreGnU%D!Q zB7%5s;$H#P>zmC57|1L}s?5b_u^GgKz#Z zi;^S)%hAQXCgr%aV`o3Jfp zZZ^sENvDa4Ai40jculYek0>7StQ)G83R~ip89!Nd(pY(NRvKFvR-C8+`{C1)*NV4K zXYkUH>JC@6j><+XEL(QtP$I?=zs`x**Zi>u<aB zKYvcD;2cN#C@p=`LwO(BLfz@Re{=RAPIGm7c7Ac=?FwlF(k!3EN}3}>4(Lj0LB_`D zSAW`@wT4<6X1plOd;N?n!({c|F?ZR?^$5a3 zeFt(k1iDG!M$cP3JfQmU{TmY&J5-o|Fy+-vV&>QtfuY|8pX`3OZXg>Z1M5@!VvW0m z$NPg7rTA+k5d=u$2wkATvdQ8=|(0d!ZH5Q}809Zh30rF@Vscc3wBy83^1Y z^>v2lvd)IG(YSQZi_9UHG(Y%T0swv>-Zs6RBssd#?Pfp?C;Rw5$_}I_S(kv#qpYgKR=O`N&#;%qi9`!#yOI zuGf7<2AZdJhXPuT#t%`FOv>ZKOjYS}{c3F1+C#raa|%x_(p8Hiel9^CG0d~3dL3Ac z(xVX7lePnl5wsFYVr2jiEh@{bXkvjHJgQn);4<3A&RO94AnilX*d9D+#7THnycSnl z=}h_?G5ESz@CEA(+5A2{lac14U{!PV0da1E*NN!b1-C!e<~C{itLmj|KXI$hN@YsYq&qvV9$E zjLI>v;GAAdU(-kICmUD2n&09_qExBim+g&grXx7aFNdLxJL>PufbXUIv3T2Vh#Tny z1xf)V7f(N|W)X}ltAm16;}<`h&G%(ieI0#I`u)uV;*L0JzKd1B#fuAE_ex%|K#RQY069foF9@Kfpk^K(*g6RV+^$1wFFV)*$?YdQ z1tyzR?+8dOZfm*aiuODaFMb>1F(~y4R5;ug`8PsDpuvMv3wfwidnAK^##ddA);+KEs#8RTKi`q45b4dNqSbS*!zvp-M zRp{{j^NGDCieApKbwU``3e;H2>uDBa55D-u_Y8NQy9Z^nk9FGdG^v&QeOPt#o7TnBu*sP6S$$ucz>2n+dfO3WYi+`3kIsDtKuCK;J&WGFbJf9-2oc(YA(QNT{6|17DA~7fkTm1l;fbp!o4Y$_D?^f8c+#1 zxF7Bi5oL2u^4?03#{5^PNk0|#d}E6O{BL?7*<_5{fX3^WXYZ{x{vPQYGFbP|j7!H` zl~DbIi!BKM!NQ>l?O{c?h)ncPx1I!eLo(_@fe{D?=-Dm*Q0(fL5kB=RUjItnsQ*_a z2%)8jLwy$@BuJ*q&<4tAr8jd>MyAscv$Ba_teSfRRjVP0?(LjQ$*iWKWya5* z6?gpir{CA0*Bxd$hgVwOrx`POIbR}ubUd=NA+YA@7>y@ zIMkXE8}_D1DlJV;f)`y=KYFsDzAP3-sudEV1-v&-hDuH($eFxB!Jyn|BCAkGc zg2AO%X6RuN$+Ml0%C|fTWFTc-0Zy3QQaI&1qDMF?u)7d)+1v!^VnyD(KwXX0v$zI6-<6;VbHPN4y)L9!S-fr_9oVTWvsU>=gixc%+Qx))v$>Yps60#WXRT(8zLhNmUJ+ z>5&#~XqTLQ-NFIx>Ir+uq-ZHljEP4y{Jj#Tv%lD^z7*eN%CIqcu=qxaMqPnHurt5l zPp&$)Z~gw}sXP|UK|>{*nZ4=`NI(Ihk`<(A{@Z~1| zfal5iXMHrH6INRZ`+gV1Rut>igZn57H8%0}(pD>hUrrDcNDH~$fwlvB>Y_rd{MRv_ ztwA`cUD1RGN_{bP)}xiPQ?vV`%HLh-jRQ}n+&vHase~K?iT+3< zr+8;oL!yvDX2sUvy&zy3lQIufi-ifUn6@kn?B3m6)+|8h+cFTy)_gyh4Q{%zC;sam zK<&PV@A|jC6s%6ps_Nrsp~;WWKCS+7kn$Ce6C6oMLMFP{kZ0hemMNqsOBjq$?faXE zdAqD>99I}(^&rsAdswl8Ixu9PDNC zURgSngLkDOVv;GCDeBBPUV+cu36;JRK=2V~t|9@8X^`U`(=)WJj<9%_x;6>0cm$_! zX)nE(q@mswdUK12{lt39YX4tWfUPVROfXiqC`Vx=F3;o0_c`eOgylw)t!!il8tMhEv((@j*P}AG;kStqQ);KCU0PdjQ17n(Lt1EPIJc8o zk>fw2gQgX#Wp)y7clfxG{AeQ!4`5JYMPe6{XO6wVaMpW-&lO4@1Buot^yt_!a+@>N z#C@mUP8~i1;4r$PXGnsl;|Y(`d`>13_tVnp`kh}s$1!-Fis&49Z)>TQpuH}bf=Ve( zq8ohN>HZ6+rq7!)itpgk`nJwJ`Ym!Iz%_y7i5l)Rn1O@iRX$2(m`n*tN zKMWuESV3(m-|1=fd4@jdl_u-8QiB9+fb!Tz-6tF`>LnU7Qv5W2$C$i z57_y5urRSbsLu@^h+R7*%cc={$Dw3B&HWUm-gINw7+kT=u>1N~Uq@E?e+lv3tH@v4 zP3!`-pW^wJrFTTnfR3$(mjBZH18M zQJZiANUz?&4p^C^?=ss2 zdood1R6sunhnc0jjUbejO(R_l-9kKIzrZonn=VNo+38-o4dGvXe~pwl9grYi(k&rJal#PDU-JS0L7@L^^`2GA8Nh11L)93T;Nop4SdXH8qko03 z3?%<8iba8oy>-8pa(HJ&qHeZa$Mr?H_j3J3P&~39L@zsSj5}p}`e)z^8eIdVWdxw= z)q3wEsO8q?P_zt}VJ+1da(U|-d4aya0RRizdg|%>vvR{l3U1tA`q9;9fXEzhi6K zTT@umDQ?8nG0`!(pVHP>)Uu~7NnOM(UHCE2Ah-Eb(n*Q}uOBHe8+o>d`|*i)g;2F4 z8_~5HFG5|Bj{pTPa`&pI@6+isKFhX@JyiTc#Hc^CVXJdPI!`|o^Ufcr8%}qA%7YaxTR=k=i z;RIF~$dTN74s$TL6LcuDu(|72VZAZGKa>KnR;j6IuvfuhXb-cSU@8MDo;eqbbSxvugU8N%8$49CwB42!TyFZA>fV!xS2e0^%PmD|&hAOMcO~~EyNiSXk z&pX2>cn2(5Y96Qzk9fy-e2K@o2cAWvwf*Meqezc{g$@FHosgRbQ$zGyarDM%-p$|D z(nC|HaMTR#x8MVL|Jn6d1OzdXe^&nvH&m$i8q!VY$&cjvs4mVQiQ@28My@%l2`8k- z4n>zw)Fhs#9Ew!|AE9oge)YGxyd4DyG46e+@uwe`c^Oel^XS-3x7^W^vSkI%!8C9p zZ!I#<@~-w_${2Z4_!{B{WmX?ii2ARQG}hidZGOlkt6jlaUv>8bcWy&fY(StX z5y--0e{X|Sb}DgiIRxl%1DxdR`#e2>HGkl~9fHWu^og6W-B5J8dOL5nt5!8g1MYq^ zxNA`^%^HKL|CsNcav z3E*hfOEWY)22Aa)=0C>%$qg;Lp0fakfB>y}eHhd0bP%foKu!8&JFw14lE02M2XfqE?Y+?H6U%vA_pV+sCt72S%z(esWJ!%3s62$w%?cF7k0qO2PQVyYh z2&=~BR_=6V7M4*h=M-AdDDV1U49{GQ`kC#l#=DBNmE!?-mq{b<1S!;EvS_5sxv>Fo z38$7S;;_m1@rW3;sWaJtfqEcAvUPs!%cKv$$cvyk~~#a zLy;6zjeB7*^P=e}1HVX0tHM~US5CNqQRX7G0|@rRX87UkI&(`dF2RP>t7>h)&)gh% z2KTlnxfqYTd|;59AyEO)xX2}C}jUI>uS>S~-igDh0MNIpHUdbgEv1fWmWc~c-c zECP~`Y*Z}RqFWlg(#i@w+ZCU-1w$eZkrnCkqT`fXeX+7tNyywS4yATmFlD55vu&K6 zuo3(In)Jb%T$#J9MW;0b#rU^OQvv`c@zPT-wFQ?q&pkdl?B;23+XD-sP*kpfA|Tbt zsnzn>(WnG}NH5^t-p;alhOgIFw(+hHe{s9n32R8y+ zqGlt+)}0kd=}_{1hKSHSM19QhFMq2G$wjFTyMz(40)0i0;&LsBFK5ipClAMIA(gfz z7&ZHA2mhP4Ut3GV$KO$akhj%7rb*UBAZ%yP0T=VytE3a?2)j164>&+grLm|{)P)~o zmLO1yBqfE<%oFppYRbPSG^YNQDv49)^SBKX5DBG&ue^<(nsB%!>d<)ISVRl57%zpr z*_jZQKE06H{XH>>4Qh@|_Z*|S@Ke|JT;mrXcHnsh05rqCELzEvHNL4x051T&v^U&x zn@hKU=xf7ii~LtM0$nE6%~nN?T5P=qj2I%5@)rh09i>|c2!Iw*AXWrLW4t4fAaSGO zCBF7V3DT*Q6zDL(Q39CYdcr&+00RZ-d!JFKQ~-Pwf@%F_ z0N_p8U`JG)jocYd;BQoWvgpnFs%@YPbhZc6!5PVPI*qQdC!X)AbfAQTsUR$;jrSwL z0yHhQ>D1QcD>|0meYCRhy!5IkyS@abhQHiK!bmXB{XuN(DQh87P2DL>p_+`gC7M_Eoa7r<+4yfHIfg+Kv; z;auAaYF|uH9_R%GE)hPOVS4G4rL%Hie|ErnEi;~eTV3Io+RQgG_yOYscg>_wt5)30 z6U`X014ettA_8-BbGppg7^ON~3HcFYtBwjKCKDy*4>1d4;|+du-LMMK%>kl+NH!%7 z<44FAl_Lq4?S9%KL5MY4AV9X>5b&#movRN#d|C0 z5-7XML$T|OQ#k64e}RwrFC2h)cCAqQySDy7J*Zwy6fe;W!os5(3{-osk0KrE_V8U! zUFxdYL+USdVtH9nKAHq*g&^#Jt$0tMt<_+gMjuX&85^sPE)&oiCV5_4Z{`YM*!$r` ze=fII>vZS*Af=<_GMF(r^FacH3&)w60J(hbYucA1!w#+001B%?ERsp{RQx=Hsg+JQ zfg1mc8qlFG{T~LE$~0sA9aBe#G@u^|f2v4B;QKi-0TW@tBqy+B;cWE(4$(h{DGj#s zaOZ_z+~swvxjofPE63s=CCcQtKnN&J&)b>P1he=Fphr{wMnt0nPAF=%Z^kM&s`2X9e>qHJF z)5%}@j}$v#EVvlA`+AUYD!OuUn=F~V<~bi8(D7xlyM3E{fZN|yyNS0{vnFpMvUr=n zV4$1FX}ExNI<)(_Fh8TCU?hd(GvR4VD&9#A>fW>0_*5j<&0-ch%5;GdTE+K((1Y1l z0J`5HMLMmGn+fm(o^VkT>KmYh^*^*fb!spAGA0i{UpJNmQuy`lsIh4cXk^x0rC+97 zkFdT*K{-R7x830*uM$MnZ(?}E-m=cMK7;Gy*J#%{qM6&?+xHgcD*OuKl_`m|0%nF*d)HmTH;1q1fZ#Z+B&UR=Bv`uyL1$D*YdtI zpfFoK9G$m+7(>4vaii(#TSvw=yRu8|d|!qMhRuDt7UM$o-sbVlfLOrqoh$fk3x{i# zi04cH;ZV=QM&xx!#~96siY z?qa_5S(MdwEwXrku0xdg&dguUJYe%XZz;L@T`1dzG1)~71r`YNrT_YMbA$WL!LVjj z5(-~~K5?A7q&Sobw6(g@haR43R^jP8FPlo8-?`ZEWUM?PD110OOnlNeA(q~c7zgmT z0?_AM`ak3E|H&GaYJ(e4UH0A$yVy*V564IUi&CAf53cjAJ_jqu0}h5hq0682)5MJ+ zJ2d;dq)oFJ)2E&x-R6NmyAEthCNCjXHDAxVF0vZnGsq{KdpRRT_A_L5+Oq*tx!$$r^YsWmM2txQ<}Wxg52Nhd@*oIh~evYf^+FFsTmt zeum@MBPp>a{ytV3D#c?9g7$$!Ru=dHv)VBWDcg22mz5-B_yL@p?9f{SBu3t$Z@1u7 zk8rb%RErB}h|#giJQbpxAm6MF zSZvoWn%sX6yw|Vg1vFq=4#$m z?#r?8YxQEIvkpd|o{yv!8j^f}9z);y(mcYp6H1kpcX9-i3rO+;nU8)_Mg&j^G_72S zuBXB!U|$9NI}6(=7O4H}+Tqdg%-7Q~76G9q-$|t=zaKA}uW;A{U?nn+$Q~S7-{z%$ zIa^&k0U~+SP?NZHdWQ zv5(#ZwZoU)`O1uWc|TKOkJXzAMzcV5J8Yf)oi9jKHuC9&@INNFGbFqI zu~57QUmxiVyJlz1(C0d{GhDHpWdquUv`8SH0fbU!e@ z>bEJn&FfzHNnwc8Bl&T zm=3Mz%YutH#|>LsK0S<|^Lt99=XcG0m*$>0{|-s>l$zDfylj~8K%Vnot|XTD941%S zb6yj?k*x-RE4~LhNRe4itE}i3&!O;7~O)3h*^0dyC*#DNZwMfwlDxsyNxOJOV z@MiO(^~U4z@HDw5pQ~+OW6CVB>u8tbS@HT#YhpvdWLwna@3j)68k}#_*q6F zKjV}?bWN$rvmiNUv(kP^xqE19>u7XsU z;=^162I-{wI-1tZ({fjxFL(83Jw3ThezG~f)P=$DOpW>M;RF)*_VK@A%7Y*anxDlo zJQ@`cNPT;{i7DT6It*599MqZorC!XJ{4iSgAI4YOsx#pwihQ_9x?%NiySvWQ{TnAl z<;-lZowr-e1r71^Xy5|D1{7rXt8xRwH(u*nb#GG5wJ{RU@!pC8P-$5!i8MSi-NcS! z-WkY?y(b0;lIirjC-28>ClT7Iqf^&zX$1+H_4TK-b@|Ndc|`-s6~IoH!331<#bDyV z23`2n2LYeX#fPXUZZRKe~i6# zSd;JHH$Fr~1xck-x)o45q*DZ)LnTE*k(92Xf{1i?j!=*kBnJZ0IgpSTEu(96?01gO z=f1z+-*G(0@jUy-F}JI>>pb7*tKOEt{t$rW(=2-76+1o}DYiF8n;b}n6my; z{+CN4>33+Mq5Trz-LF0M+U375nmXG{I^78U8qMD`@R!4VE!lPCOECv;X8I0;;OCD` z)^sAOTB}iaL_#i@&G;L64JHYijP^YkL07d_T!#4RIWku5u0~60Xgn%QBc+2v-QTUd z%yQ6NzdLqv^YIJrZ0%&! z2`5iO=H8}<+&7RgGdbHhM(+6p{#mLM-dKA^2vN}Bka+W%+SSuGj}FRamolI-HtOy_ zhWgmH6OXWlXMe1Vjt~*w%ucy;>M(jcDNZhFv!?xEFD!!xztn-`wi%4)2pr4M8Ocn< zx4n{o2KP*T-WC0D+k>Af^$t+Gs~yd#ze5=eqSQxKwnJOrIj%X6-61mGYBx7=7Fg%i z=~#1HpLcR`1yy?d2a5_&`{$+m){H|SgJ3~$bo_xw_|`(tjsGdx{YpK9pZo_Ax=^Fl zS<}zZv+^Q@nn^}V+?-zZX5vKT=MpVv@<=)Hd&wvnTH9Z!{F+gv$WVs9{=Q1A^P-a$ zBIO|X0p2&p4qO`eq=2Q5B*c%hl!XO;gC$>w1-|r(mv~my(R3+GjCh;@`VHk2O$&Xg zsFt6sQu{cxIRw?DBa)0N&sCxbQI(?W!RSl>58!kjjq&j(1*^)3lxz+r;S%f8n?;pi zMHPgwAi)F40a#z8PAZvrK|8uSC(WsSTj3s|^sO z+rKXIU(f|mtB{^U=U^xSTGxvS()ds2ZBTa_HS$$GPas7sG@b)IQEJU1ty2R;^&dEo$cAE!oj?AI4LGOlx-d+|5++gn z7a)F76Tl1|Wk`X&j0X_FBPKwp5sxlKy-|dNW!TR$>6vB|`xry?6mDss{0ZlXvp!Z6W&RjS_okc#88+;N4T2iVeW@GT7eK_XhKYVZ&l)qm z!g$S2_W0!k!-PfyQ;ToNRUyOVdTlY)xfUt1Sc$%TOOeOi2#WmK`5#nbuTuiuA|11# zFTdm>I<(!RU-k)(2{5t@yhy-U(@E#AH7!hV>46ifMEse5^E)bTDX%7!O}B}1R_*O{TRGW3eq3?F9GL3V zz&Qb#z--PGSE?NB+F`8kR;x;)hN$C!#dIe;Z!IsVakx6dmA|aG0M-IY7;BNo2vn9* z#SK||&ljPV207u0ea3qTQ<>b*Rtm-!9Yzv9Y7bx<%9YO|1&ZT!`W|kZ<-R=srI?Di z2Wi+md|+sBBazKM_jXNtq?1!lF2L+oEfn~!mg6K@)kK@%I!Em`;?icUrcm}$Y1x% zLr&>MxcZGdC!CY_qUY;n9!NYJ+zLglGO1j@H-@p6li}=rQ%DnQPr&@}p2K52fj0oaplLIAC3*`%1_#Yash-C zshr-=o|^i{gS?kniED8b_Q)BxzW$%l4H$_?{=++9Gs;Ii>?BWqIh{@PcbI_CqkjiU zKgr}@T@r2Qq#n2E*E7Ll4?tc*&V5Gi{2U4}(`3?cXl@cGR@t<;)O+cUx zcxx-f*LxF@`!%Ve7B%Z$c4=d2HtTgGc5bzyK~+0NsrAl7#;_^(;$&crWh1Lv$lPz( z1^*5W-Q<u~OZGALBwD4JLbj@%Emd$460iwG+D;6;rs zr?M{^-*2thub=C*S$})lV^cM6m4@vZN!v6@5e}rFel2`b%5Qx3t+?ts#Lwb=$?bnA zAuxxT0Rzg&pLoma`rb1Z+-W9uCy>nG`l( z#^LY#;*&MaE23JPLj@bBc{ryl7HK6oH{22DA`VMt(z37`IO4M(ZoHYUD`|bVEN6O| zALnBtB-~T)HQ8#FHqgxC-i2Ux8XP36K7#h04b&R%EfK9A`n=wRv3NKGxdw!mQn>Jk z?Q&!RdGxIP?^`$!*`ClK#7e z(>Wxw6OddWOUx2tw7*bBuysX_81vrJpPof-%PN_9WF+M&*!=?Q|-Jzvb{PQ618_@0X(dvlM3g)|(7lp`G{!6F{Ml#dIshMmDdXKI6 z&W6>xo_*!^UD@qBon35j#l@fXP&_^un`<}_4TJ|X#3-SkAN-)PKb>)zT2Ng3R!D|J zz@Pa<&p&P04GN6IHl~SB{ph*_cj%VgU-dqDRA0XZG7xj_G?XrB5Xm3pw#j>si!ysv z@bmcr;<23Oq)jjI$%ECAv%O7RmD9%ETJ&LuxSgX)|1Zk=K!%J^Jmh`1zXUjW5;fWG!g?=jF|4=j#VDB^zEuycf9f_DYvugK5a@x3#5@QJY0g5p zP*S5or6^Q6$!wLj=4A0a4n)2kp9G@%kn1iCZT|D4+(q?a*e=-Q#(@1)pw>0#xx!lG zedMIe(d@{^ey5vU&&C-87OPjP{XLm9mq(`glpx8BV6G>qJ}g$+6Ax|(MF5mNW)tNe*$s6FLRi3$%`gy&%30`Nq`-IJ-H{3f^^kq8I&I=F)dEL0< zzM=4}#5n2ov4s!m9tSN`b?M_mtvypy0lrUs2D;yTL+-DoRBy!%jf?@(W(@q~hQYWl zK=hd$DA*vU)6!me1FC8)8k_$&^SESlL$2Z|D3YvhW1nSrI=RX})!~=8$>G(BPi+TH}WWy6`NSscqtP%h|=+6%T_ly&L#!Nb%RV>_75Jf30&%hKIK;vUxykcKZV^LJQWUN-V_f!hG^+EoZ zZSP5?nnSKwxJP>^fJu&2j@HR!UyRSOl&*aZuiq2*UGB=0!^wZy`#bLHH3GhW3pVDe z)1g?C2H#%$n&b7J^$G+T|B|^W0VHYG>jPl#=-h~R75krCf~EXz`bO)I)-+?lZSn1v zl7_i#ASUb$O33rXVbE0j=a+o_RqKH?DjE?Z&g4IU+NV~rOW{eUDC`kw?do?lIH=bh z3G{|dmAAo-pAOrKkE6noM|ot=kwYG6*dB6ceMtDKz%TP3Q{ktb(7R?c(sK3d;b&X@ zZ-t-v^exUCo`fPLc1nmQy6GT(K~W=Npys@ex)2;a{^b9K`tvu+{-sq^lQdbMKSAyq zNeL9D(Wue?Vs&_433otO4HiBx(}r4n$-m4Ll_3pX$}&i+u~=b(2aKd=U(RY-#{2;rmXo1Ouw!+!4JIrw*n=rV{Nabf_>H%VMwcdC3tSo($fmn}_6@E#cWz;o zo;0j)q|5D>Xw^dxgCuC+JHGM0R=Xd^gLIKjl^|57>8r$ImJiN{0z076!U>6fyRLHl zIH%aCHqQnhGbiY9^28-rcj|P|BN-*)6Y&)zBH-P}4Qudzk(ave`xRYN2tMpr-SQc(LHEy+1c`fS=U zJ*uRCZ@kS2JHc}Jah#|7Snl*w!r+5XvC(&Wb3-Vd+ZwbrTKNI>L8oZ{?z7S1qnunkDGNd0LlG)18++ow6 z1gnpH&1kP$yeO<&-^y%;duo$Ha|71{e>*;eXN%H3=PWhty*i%2#PV6-t8VUc#$!jh z;oc`MEM9FN`_B4y+J>yqDTYw!kh<-t_ZKgw=w?)MUh9y_IKK=|04(juQ<0VAkWT-7 z>M#{hv<;ge{j?N8iFhA=T&kvj8Dwf)MF0N)GUBP{Ak7g`jyDvaBV^_PQ&k~6sb_RN z;Z4EE$)?;HHJcf$C`gb0VLMJHH~2~Glh6$mXX<2&sWAEO#7ml_N@@G@F(EoNK1&&K zOKnzjJ6D>l#cy%k`mXRpz*`nZ3pdkg3Mom zMl&w7!gX0TWe-*3NyO?O6p7u3wvpx)wk;A+L0uTZjCWDw?~`#(N5&r7yz%P0FGAu< z5oW3g%2dNwOy(ClKcw-SOZR7azQ1V?U^YcjH|ICVen;_04-PjJ>cniL8}8&7V}cyE0|y*vW!Z((|$y69to z8uH{)(VO?oKG?q6iQnFbDR2jn|7dXGsK-Aj(hN}&;SjVL_W~Ui)_$deJy3-DQ+B>g zO7bVy8O50)p|yz+l)mc?rce*T(8z#0l_kM3FGK#?(nDV`BVIul5PgEr+R3To=7`K@ zuEHm_YSBb*Cu8HQCNBCcY}=n=?yO9<{_anNPZI=Ig?>%MS`b2_hgT*Q1)s$t6+$|n z*F{;!iYMhQSa*qvo0o(52{n3K)v5_|phoCONJd$BsP2?A3R$xC~4{TJStRY^pzo|>B=tUbJEG8pA7&w&?bwV+QD#H`!i`vP6=z@gFiBCX~ z^jY)OgtY?oT2nyi$Iq^jiW)^(VJP&!#m8fp$nBC&(|;sONu-zN&g~1})+zZNCng{R zLZ5-vuA7hI-|Xy!EO!I!UKkBpl z)Z0SpXyYcjABo@bYW$y%-;8+|b`e0jN$V?1$cIP%xY5d&Tdgvgv7L%B(;Pd#*(nLT zN$q;BzXS)}1lK_9cA26IECyzP9Mn8JGWb9cj#1+qdn%r zQwL1&wt--I|)Dj~sCAY|A z%1nPM^=R%tiG)TfPnmi<48!uZ)ORs(o&P8;mX#G0)T$PuK(OH9wNk>4v|Dms5w^1GFcShyLV zFZDAUKYz?DMi0Fnu-^}`Kg%KsMKtWf6dAcOKz&amUCmG@{&>9xk(wy;+u5)U7I>{`tn;Xv7&t z@f9!O@OlgXOX%^odu_Dw9v9>>s-d@{F1&v}!p}Tvtmok%+1@wL<^JzcsjB;S+PoIq z9#o|1#bw;z08ii4{d%`40{U!-JMw(Q_6{ue0~|I)$uk1++!KlSIA(dQsM~3OL8A2X zLr6})wS)%QZG`q)EBIObJ(U`FmT9j0>9>Xbe(_{3skbe(JsB;xrrjWc?$` zdNBFA4aqnB?#y96Pe9=BscTdff4=-ZLeQwc2^xRc7T*gsJndW_GOhd`2oTHjFa`BzA( z4mfAe4-JRqdZg<$8Z}vRNIe@x)3R}xe_RXYgM8ZdO|_k|%5hL=sw>I9_he~~-3se1 zmZ-Ys|I~Rbl&j{~)FbFSfmkGN7?zViC6eUD+7&DScUu&pV z^SR8h2p*m6z~%%LA?f?+i%u@}`^0KB6W%!{;s?Y)z1(cjboctt5VPx73AL^fZ%CfS z9LsHB0_)cV?P|v=eb=BZ9|M@sg4y5WoZ_nslE?lzs?%2vl_fd`Um7^FUq6b$%~� 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

      -TYQ0`<`#wchb@IM^W@!5hy$clS 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

    - - + + - - + + diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 5a1be8804..a1ee45b0e 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -534,8 +534,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo {Event::ToggleTimeMachine, KBDK_T, MOD3}, #ifdef PNG_SUPPORT - {Event::ToggleContSnapshots, KBDK_S, MOD3}, - {Event::ToggleContSnapshotsFrame, KBDK_S, KBDM_SHIFT | MOD3}, + {Event::ToggleContSnapshots, KBDK_S, MOD3 | KBDM_CTRL}, + {Event::ToggleContSnapshotsFrame, KBDK_S, KBDM_SHIFT | MOD3 | KBDM_CTRL}, #endif {Event::DecreaseAutoFire, KBDK_A, KBDM_SHIFT | KBDM_CTRL}, diff --git a/src/common/PNGLibrary.cxx b/src/common/PNGLibrary.cxx index ae7d3390f..901d42478 100644 --- a/src/common/PNGLibrary.cxx +++ b/src/common/PNGLibrary.cxx @@ -296,7 +296,6 @@ void PNGLibrary::takeSnapshot(uInt32 number) // Figure out the correct snapshot name string filename; - bool showmessage = number == 0; string sspath = myOSystem.snapshotSaveDir().getPath() + (myOSystem.settings().getString("snapname") != "int" ? myOSystem.romFile().getNameWithExt("") @@ -347,9 +346,9 @@ void PNGLibrary::takeSnapshot(uInt32 number) VarList::push_back(comments, "TV Effects", myOSystem.frameBuffer().tiaSurface().effectsInfo()); // Now create a PNG snapshot + string message = "Snapshot saved"; if(myOSystem.settings().getBool("ss1x")) { - string message = "Snapshot saved"; try { Common::Rect rect; @@ -360,8 +359,6 @@ void PNGLibrary::takeSnapshot(uInt32 number) { message = e.what(); } - if(showmessage) - myOSystem.frameBuffer().showMessage(message); } else { @@ -369,7 +366,6 @@ void PNGLibrary::takeSnapshot(uInt32 number) myOSystem.frameBuffer().enableMessages(false); myOSystem.frameBuffer().tiaSurface().renderForSnapshot(); - string message = "Snapshot saved"; try { myOSystem.png().saveImage(filename, comments); @@ -381,9 +377,8 @@ void PNGLibrary::takeSnapshot(uInt32 number) // Re-enable old messages myOSystem.frameBuffer().enableMessages(true); - if(showmessage) - myOSystem.frameBuffer().showMessage(message); } + myOSystem.frameBuffer().showMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From aa28a21decefb255845221d793683c8834cd34f4 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 25 Oct 2020 15:03:34 -0230 Subject: [PATCH 108/263] Use proper constant for invalid handles in Windows. --- src/windows/SerialPortWINDOWS.cxx | 16 ++++++++-------- src/windows/SerialPortWINDOWS.hxx | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/windows/SerialPortWINDOWS.cxx b/src/windows/SerialPortWINDOWS.cxx index a9b738c7c..00154d0ea 100644 --- a/src/windows/SerialPortWINDOWS.cxx +++ b/src/windows/SerialPortWINDOWS.cxx @@ -27,22 +27,22 @@ SerialPortWINDOWS::SerialPortWINDOWS() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SerialPortWINDOWS::~SerialPortWINDOWS() { - if(myHandle) + if(myHandle != INVALID_HANDLE_VALUE) { CloseHandle(myHandle); - myHandle = 0; + myHandle = INVALID_HANDLE_VALUE; } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool SerialPortWINDOWS::openPort(const string& device) { - if(!myHandle) + if(myHandle == INVALID_HANDLE_VALUE) { myHandle = CreateFile(device.c_str(), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - if(myHandle) + if(myHandle != INVALID_HANDLE_VALUE) { DCB dcb; @@ -51,7 +51,7 @@ bool SerialPortWINDOWS::openPort(const string& device) if(!BuildCommDCB("19200,n,8,1", &dcb)) { CloseHandle(myHandle); - myHandle = 0; + myHandle = INVALID_HANDLE_VALUE; return false; } @@ -79,7 +79,7 @@ bool SerialPortWINDOWS::openPort(const string& device) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool SerialPortWINDOWS::readByte(uInt8& data) { - if(myHandle) + if(myHandle != INVALID_HANDLE_VALUE) { DWORD read; ReadFile(myHandle, &data, 1, &read, NULL); @@ -91,7 +91,7 @@ bool SerialPortWINDOWS::readByte(uInt8& data) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool SerialPortWINDOWS::writeByte(uInt8 data) { - if(myHandle) + if(myHandle != INVALID_HANDLE_VALUE) { DWORD written; WriteFile(myHandle, &data, 1, &written, NULL); @@ -103,7 +103,7 @@ bool SerialPortWINDOWS::writeByte(uInt8 data) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool SerialPortWINDOWS::isCTS() { - if(myHandle) + if(myHandle != INVALID_HANDLE_VALUE) { DWORD modemStat; GetCommModemStatus(myHandle, &modemStat); diff --git a/src/windows/SerialPortWINDOWS.hxx b/src/windows/SerialPortWINDOWS.hxx index 1fcc2882e..9a123440c 100644 --- a/src/windows/SerialPortWINDOWS.hxx +++ b/src/windows/SerialPortWINDOWS.hxx @@ -71,7 +71,7 @@ class SerialPortWINDOWS : public SerialPort private: // Handle to serial port - HANDLE myHandle{0}; + HANDLE myHandle{INVALID_HANDLE_VALUE}; private: // Following constructors and assignment operators not supported From 4660b239a585a0ca001dd6bb399ddbba2302041a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 28 Oct 2020 23:37:25 -0230 Subject: [PATCH 109/263] More fixes to SaveKey data file; make sure file is always 32KB. --- src/emucore/MT24LC256.cxx | 25 +++++++++++++++---------- src/emucore/MT24LC256.hxx | 3 --- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/emucore/MT24LC256.cxx b/src/emucore/MT24LC256.cxx index 15cbfae96..ba6d2348b 100644 --- a/src/emucore/MT24LC256.cxx +++ b/src/emucore/MT24LC256.cxx @@ -50,18 +50,28 @@ MT24LC256::MT24LC256(const FilesystemNode& eepromfile, const System& system, myDataFile(eepromfile) { // Load the data from an external file (if it exists) + bool fileValid = false; try { - // Get length of file; it must be 32768 + // A valid file must be 32768 bytes; otherwise we create a new one if(myDataFile.read(myData) == FLASH_SIZE) - myDataFileExists = true; + fileValid = true; } catch(...) { - myDataFileExists = false; - myData = make_unique(FLASH_SIZE); + fileValid = false; } + if(!fileValid) + { + // Work around a bug in XCode 11.2 with -O0 and -O1 + const uInt8 initialValue = INITIAL_VALUE; + + myData = make_unique(FLASH_SIZE); + std::fill_n(myData.get(), FLASH_SIZE, initialValue); + myDataChanged = true; + } + // Then initialize the I2C state jpee_init(); @@ -72,7 +82,7 @@ MT24LC256::MT24LC256(const FilesystemNode& eepromfile, const System& system, MT24LC256::~MT24LC256() { // Save EEPROM data to external file only when necessary - if(!myDataFileExists || myDataChanged) + if(myDataChanged) { try { myDataFile.write(myData, FLASH_SIZE); } catch(...) { } @@ -167,9 +177,6 @@ bool MT24LC256::isPageUsed(uInt32 page) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void MT24LC256::jpee_init() { - // Work around a bug in XCode 11.2 with -O0 and -O1 - const uInt8 initialValue = INITIAL_VALUE; - jpee_sdat = 1; jpee_address = 0; jpee_state=0; @@ -177,8 +184,6 @@ void MT24LC256::jpee_init() jpee_pagemask = PAGE_SIZE - 1; jpee_smallmode = 0; jpee_logmode = -1; - if(!myDataFileExists) - std::fill_n(myData.get(), FLASH_SIZE, initialValue); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/MT24LC256.hxx b/src/emucore/MT24LC256.hxx index 6f51dea26..56c1bf804 100644 --- a/src/emucore/MT24LC256.hxx +++ b/src/emucore/MT24LC256.hxx @@ -113,9 +113,6 @@ class MT24LC256 // The file containing the EEPROM data FilesystemNode myDataFile; - // Indicates if a valid EEPROM data file exists/was successfully loaded - bool myDataFileExists{false}; - // Indicates if the EEPROM has changed since class invocation bool myDataChanged{false}; From c0e08c9475f31c3acac9479670ce0753d11214a6 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 29 Oct 2020 00:09:25 -0230 Subject: [PATCH 110/263] Updated changelog for upcoming release. --- Changes.txt | 13 +++++++++++-- src/gui/WhatsNewDialog.cxx | 22 +++++++--------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Changes.txt b/Changes.txt index bd6306930..88ddd7afe 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,14 +12,23 @@ Release History =========================================================================== -6.3 to 6.4 (XXXX XX, 2020) +6.3 to 6.3.1 (November 2, 2020) * Added basic (entire and single line only) text cut/copy and paste. * Fixed bug with aspect correction and fullscreen mode; snapshots from such a mode are now pixel-exact. - * Made serial port used for an AtariVox-USB adaptor editable. (TODO: Doc) + * Some improvements to AVox-USB adaptor functionality: + - Made serial port used for an AtariVox-USB adaptor editable. + - Autodetection of serial ports no longer messes up devices plugged + into other serial ports. + + * Fixed crash with missing or incorrectly sized SaveKey data file, and + with certain functions not working (erase pages, erase entire EEPROM). + + * Fixed bug in ROM launcher, with last ROM selected not being remembered + when exiting and re-entering a directory. -Have fun! diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index 4787d8fd7..9c37701d2 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -43,22 +43,14 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const max_w, max_h); #if defined(RETRON77) - add(ypos, "added adjustable autofire (see 'Advanced Settings')"); - add(ypos, "added new UI theme 'Dark' (see 'Advanced Settings')"); + add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); + add(ypos, "fixed bug with launcher not remembering last selected ROM"); #else - add(ypos, "added adjustable autofire"); - add(ypos, "added 'Dark' UI theme"); - //add(ypos, "extended global hotkeys for debug options"); - add(ypos, "added option to playback a game using the Time Machine"); - //add(ypos, "allow taking snapshots from within the Time Machine dialog"); - add(ypos, "added the ability to access most files that Stella uses from within a ZIP file"); - add(ypos, "extended AtariVox support to handle flow control, so that long phrases are no longer corrupted / cut off"); - add(ypos, "added QuadTari controller support"); - add(ypos, "added option to select the audio device"); - //add(ypos, "added option to display detected settings info when a ROM is loaded"); - //add(ypos, "added another oddball TIA glitch option for delayed background color"); - //add(ypos, "replaced 'Re-disassemble' with 'Disassemble @ current line' in debugger"); - //add(ypos, "fixed bug when taking fullscreen snapshots; the dimensions were sometimes cut"); + add(ypos, "added basic text cut/copy/paste to UI"); + add(ypos, "fixed fullscreen mode, aspect correction and pixel-exact snapshots"); + add(ypos, "improved AVox-USB adaptor autodetection"); + add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); + add(ypos, "fixed bug with launcher not remembering last selected ROM"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); #endif From 0ec9e7af9fcbe6f9195447544964b1480fb67d1c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 31 Oct 2020 19:06:58 +0100 Subject: [PATCH 111/263] added color parameters to 'Custom' palette, fixes #657 --- Changes.txt | 6 +- docs/graphics/options_video_palettes.png | Bin 7790 -> 9809 bytes docs/index.html | 39 ++++- src/common/PaletteHandler.cxx | 201 ++++++++++++++++------- src/common/PaletteHandler.hxx | 83 +++++++++- src/emucore/EventHandler.cxx | 16 +- src/emucore/EventHandler.hxx | 6 + src/emucore/PointingDevice.cxx | 1 + src/emucore/Settings.cxx | 35 ++-- src/gui/VideoAudioDialog.cxx | 136 ++++++++++++--- src/gui/VideoAudioDialog.hxx | 10 ++ src/gui/WhatsNewDialog.cxx | 3 +- 12 files changed, 438 insertions(+), 98 deletions(-) diff --git a/Changes.txt b/Changes.txt index 88ddd7afe..0a08e446b 100644 --- a/Changes.txt +++ b/Changes.txt @@ -16,14 +16,16 @@ * Added basic (entire and single line only) text cut/copy and paste. - * Fixed bug with aspect correction and fullscreen mode; snapshots from - such a mode are now pixel-exact. + * Added color parameters to 'Custom' palette * Some improvements to AVox-USB adaptor functionality: - Made serial port used for an AtariVox-USB adaptor editable. - Autodetection of serial ports no longer messes up devices plugged into other serial ports. + * Fixed bug with aspect correction and fullscreen mode; snapshots from + such a mode are now pixel-exact. + * Fixed crash with missing or incorrectly sized SaveKey data file, and with certain functions not working (erase pages, erase entire EEPROM). diff --git a/docs/graphics/options_video_palettes.png b/docs/graphics/options_video_palettes.png index cb8597bbe58e4cbcb40b2fc8c292896c55114284..d965b45b3bc7c49b6fa16bad9e008da54ab4cf11 100644 GIT binary patch literal 9809 zcmb7KXIN9&){f(+nL&zU8AaNRI)W52gd$x;K@bRFp@R?!qDYh?gqBeTgGfoLOn}I9lucUtg{%rCz*FOQuZxj6teE2^X9b+93s3>Y1%W(^E z4`*t0?$qVWmva@j&&;$p6$HF%f0`EV2#nLkbx8E@+}Z1b!*0}gM^_Iqijc+9U#M_AXgYD)E$%=v4fZgp^{A56YeKLpi82l zV0F+F>%FzU%I~ok*kxX9atvVWjcwZ>96nNLVBF#2Hht$FJ0qJ-Xf^}MT;F6ECGJ|F z8QN}_Ipt4e<&tJXLY>QXf2c>2@0X zNgeyu2R2CbEJ*E!fYk$8-@-H4jw@x;cYD}b3v7_A80d`pPgksezw4`=g|&ZO7C1(J z%w7a3fk5Yf+TtZ~AX@9hb34bkfq&6)N$g6HG6-}5wA&k`7$b1DSjMB%@WHHWAv+W# z587b@f?NZchJ)O51R`3b^T!QI?900(Ku|4^xjpE5ASen4E~q@%KA=0b?DQH0>bBAu zmY$mdg7M4s(^j4!kYN4SpG`z$)+G?=ptiwDopZkSlawuKAC3Ghhbc(1h{@w)MkW(S zq0zym^*68y2|LyKamixcHkpR{(&vZFVT)TRei~`{af;aw+vZ*+BBKk8EoSFG??;ff zB|zja5%Bkg87F`beFWBc&T~f`D&T!i+K9e(dey90^$fW)`cXlzYolHUChE>(-qGROiInMtmIL=POH1AlKQ*JoF2-8OPM50hXuB(i zJ6Mx(0JY~pI=m={|HBL6bZDH;zOi4`TWFcxcZJiIA1Zs_SEgHwY1Da`P;#ex30H*? z^N-b}27+~r#;5xOE{wr@bj~N!qyzQFQS;ZeB#~9%`3S*li>{{ahlg5j!QA$EqV{X- zu&2SpG*E@&0xicR9`wdLFc5*n9)CW>>jGT#z$VH3q0TsoIjh7_;prEdy`rt-s*@>h zRm8XAlX>-Dez))Kf~!qJ)%Fy-eRvVNh|`?M2kZ20n9^Y&-W6XmT(uBjy@F*qYj-!b zKaFg@8oo9%ko8yZ!F@4gyo`O0UzVVkxp>0^4NDbNyV_FjBdkQ5^?WA|BL8uO__(Ix z!k$po-B4->3A;xDZvQ$Q^~V_!(r6E4{eR$wh6*C!2K5>CvY|N%skO~hqtoYTcaC2H z%#DDr4`+%(Ge}q;EF>9Dh!JK8La8d%^t``s^h_MPMu-W<(n&2xYm|G=x;sYh4;dg{ zh4*OcCN4tYbXQke#%qj|ko>;K9x~K7^UdjW>Y=G|6AXmbphB&IyPCPge|iHcJ2NEf z5m+2Pi&Hz+p?Muj9d3_Q>$_K;qweigt-%mGV*}5Coi;fi7OP3G5YCk(-wH^<9sq7r z!V;3~`eHGoN_R$;rmafvrxr?X6-TKa zBEMF5au~eh-Ss|y%4;RMDc2juv|mV_T4>wix$ARK&u^&Lf+5+N6GGjaZ%R{do8jHs zT5)Pw#FET$qOFN7`gs33Sd;++B8a)ct*NFr{T=E=8?6r{UB$y428T7lnC2V`qsb_~ zPpG%cbKKNF+Xlk;lePv7>v!FWcbtwCR4Ppg7FABjVAFaL&C|V^rw59aF~1G?lsRR@ zLYjNZ)SlwECKqeQVH)=YD!j;Sw4=DnA|4VZQ@z`tJ32IqHY%SDB34f(wf;Wnwsj#3 z%RE2kTP`eL0U5!UxPqN&nsR`n6R}B_jG<#Or6_WkYM9bVmRpn-GuBM>OnqyLc=l%0 zMN-ML;NGc)a}K+pRdJ5Nl@*NBS}}#4zk^^9$R`e61Gx zhy1)EUKGlf5^BCWxVr!hctNZIpIQ@k%KyG<(z6IApNU3MG;mc@mineZj6^qrW@t=B zqppXmCb<$~JRvZrNS8+t=WoDD$Fd}|V6P6gHyCx!mYgN=as)saA2l0nduB99^uu_} zKp>S*JaAH?d-+X-MCVdbgamns9+BL!bXTBfH-hB(^W|N;`1rPj+&-a`nqq2dX@P~b z|B+&5Dkb&Lbw@i#f(GUsUfoTBgV6D{iau}>Xhk#Oq0{FNTvc^mSwuEY*#$R*{U_Wk2CU`sLh+*}dpR;Jj> zc9;btE@}Jr+BNhKFK0CNK&gZjI zO+!+?$BYg{hVuctdUo5dI+x-V!r-pu!k;=&s4b&>H=Zd<7of7p9`^m!AI}m4wzb>V zhBKQHq~rg_l4+1P?Z)~@fVl=(jASYYS&w9@{0~9)`IV7?9og2ct-7=0Tj#^H>(%kgL*^*P~v2gQg;=6sj0z80>V%(zw5*B^#qg^x?ts z-msS|u6EPqRr6j7neKYT&D&jf#cqWV_qV=G@Y!976m|HO+bc)sS|+UjSZG-BSg~D^Q-bXx}n;K@PK`s3mfM0`2;F-!n!naH+LNHd7 zkE7cUa-#q4`QcG4Eh0uf()oWKxN!u6ilS>_jsU3NvW4c`1DUt?q z0G2Z7g;)2WxqAJ&f#;r^@9ycA^|Wu|vK|G)OuvZLAjIkDoe>?D5e{Pt0Wb6cc5R*>>A&aTORyz8^m`z~++z}gTxs!2 zL8uW6#USSq3#B0M5wapM*@)E6WhxMy@8JwV(qZYH;57DOd~7Qg-ki+GWfVXF!k(|o zsFDnYxQ9^csr386FF+YTtPW^N{)=lcki-Eb@)y5>oYn?m}= z_}zOSa|q5~o+n6MZ`I20uXmP4L|3>7D|SxvvgnRtw^zCoBanrLQ$5>`q|F_&*AOU2 zNLWk`D{Lt?phTBe!sR&Q2UN&G4aCcU0EXiGM}f94FfA#hQtQR^R%*wuyd#ZCbClv; zw#8973)h9a`m()Y{ceI{Ji=#q(rFgbHL7XQsI*dkMJWCjq8_nYzuS$~-&1gvwM;-> zW)TR;D=aDj=?YZD3uusG&zPk+qJL^*iz$5_Q!npw0tkpoDvY{dj|vUcAc!9+K25fh zKtRnltiG6-cX{#MNzUj1?9wY=jKhuou|VJJUru^ruO<{XiFopA-7KBNyeo?(AIKR2 zd|cU<%ZFrwQv%*Nx9oB*sa+p^xJT76sotv03(I3y8E{1SlS~ROc~<%N)rA|~;z!O- zX3VFYA@cAl09C6!ED!tTi5)SV%ls)XgM)xiHrYmVUB3`QB;vEzPO?`+BLNu6qF0;b zTu3rJZvVdC{0?LOK)^Ed@`ierCL@O4EG0$^buUpOhB|@j`aKm3nDjoL@i(WbKgb(B zr>WJ5P_*Cph(xmAhy9-mhHc660|`6w`-tcL%Z(b{%ok;Y5q@0*b z^bOK79!%dpQuK}WJm3TJK=PUoG0dB*A^`vJrd$Dr-q$`ZSTt%3K+|osrg^c~x;z z%s=QYOkiK%(sIj7N{H(T0523_ag`s}0m&bAol-~{UeCMZ#i^9e=COwRoK6K;xolYz znx2y%@1UHtbtCt3i+4{ZT@Y=}`xAL$BwN!qqu-cT`!f$^=s6`pYaXk>2Z3W502;0X0Kh%~7K4zqMWyNj`iclT zg$@=$XVEbtU-j^RD1}^O86J7q;UJG5bR>vE z;r9Bj%swak*%lO(det|v?@CLQ_*ryQ^HOG})++s(%W)aa{EcD6-m+ zkv*#I-!j+KC8u9gg{OSY#GygWd+bV$%=ARoah~9mn8wqj+J4HwintgtaJP89ugY!%7UYF0D1Ipww8> z5LBMG=zL!a{MQ|TF<9y9xe=Jks?i8$AG(x2whvtmcn%OG6%KN4T$?KVzIxF@umZ;$ z(L4QQSLLqmVwWmOAx@)V9}B{Qgsac>HH@`Zg4p*KoWK$-R#`HUC^$1a;0^3)X+Jm&Nj}pjViC+Y{E$`02`eqZP!l@URT1u z;VKPro+`1hL)_xsaVDC1ZtciQD(a^-}tQQ0aap5gYvF?E z+S&2P83$ClwDNdt4xWK)Ewcx^#Z9ANTBVwj60hr7=6ZJP6N7(iJQNqZn8;PY0Btup z1Z9LS((Cl1_6yxajws!^@xpIz`??{f$gn@Vhh2G|r3i`kOU4aE#(ST2YkL;#XD>Fl zevHEGd1&G3Z>)(&tFz$^TNOjo?m9??nkK?tT|lS3^YQ6wf09mdHXxn((S@d?O%}cG_HUEypI9+ z&&Ou)>Eun=U=^y^jrMzt7%k)8*Q5Y4o-w8*Yjfe89&cIfU~e|%pQTJKc415xV>};; zF>P;pZ(w^o+wwwxmz}&ddJfETUeNT+=^#N|Y6r>=3 z@C5Y{ms5+Rfz}mp(m6q$P9Srk^T+3Vu0_6I?`MFv1)a^mDp9iPI3l66dSfJ6an*Gs zS!osZgJwWKcG+`DW;nT2kB+nf+EiY!cX19=aQJrQY*GbUbOXxhFiM$e zB3FLbRh&>kR86W`3dNC4+nbb$g!OJ2c$>@+7ck zKD6+oPII#Ef5FBEgG=bGFwSXfWc@ykV1(uyVt00&nXcLO4+np&Y&M=#@H_BX(d19g z9X7Qz_hX%l`-h4LqqHJ%8(#NLXpySA8$aAgJI50$;3)QaW`FrmZQegaXZ0YB+Z%Yxr)d` zY*lD~M0V>=rmQu$q!1m(v8~&#j`N&ZQ`s#Oe#PN$TUHAN8xiWK$JZx>s+K6mDHaxP z=E6>{jD`k+xjlyL-Er!x^k@*hhu7Nb%BXuT_yyC0c4K7{(C)13Bl`Q;Pw5T-aX$`y ziKjjg^vs$X)*P>#oYLF?bl3c7?enUtTwR_AJZ4?W4`#XdW#~{m;T`%LVkjhCPDVP7 zSM`<8gHw8o`l7+KLkrgyVmt-6u9q!Tn706MJd&5Y8XKg@E5!<7cLB7Cow+@a>CMx@3(lcRS(24|-U;9iG# ztks8*qbLfOYr1u#)(mbCmGz}OetB#5tRqi1^J`Lgfm>3(ToBUa`)cxbPuaI&RzZXO zL$}*_I4f1;tPg(Ww;=`<@=ak_`LWzYtH6mo=~kzOsHpWL;`;*cO`{llzv(RR{^u-( zeJPzhq<+~cV?efmCg5+nVToyylO0k#y>&_MlLil0^kb*ru{;KUTkFR2WJy3d78%YN znIE)&xZlS3_tgw@(lqvnV~|3@zprZidlQ((?1I#MdB7g*=JRn=DfZNO_JXt*)=&LUJ zVIbNql8l_cZ@ihRt$ms2v)6MjI$>%$$5#&bt9+mWCdv9Htt%DFtdvDo#^-`7Tms(1 z5Z5fLqfo=q2}$SJu9E_qWE+T&h2@~Pyp@nw`_ijqBcdphStnV{P7wrd#=|qBd~KiE z7fe{Gj9Q91f`iA!2pa4rjW@F)FzT{bbDFg>s!$8Bb{eeS){q-KIbVwDf%AK1`C=gL zXa!h_#(a~}^b;FqwOGvLgG#5Ky*fpWis?lCGOW%M8utUf@{6Pxv z`^p14=3v}#+eK3OEB6tVew)arwNs{aLHHoONyCg0QsWXwJSWi|q0=WW9M&}EFV;`0E4W!wWY({M_!8*}p%G(|3&+_nj5`9CKhZL}FTuAo_)` zBhY@CuOpa*^>sHolmKyPWL+Ahi4h(rll-gdv5aU`0T6;9h3R=gxcv%nurr!Xnvp2i z`Xw4a=t;pd-R2yUwMW?FKwtyLu@*pQ=IdJ}T(6jX-e0}&f-OW@3DoVX+j$0fzX)V- M%H(AJiHo=YAJhh41poj5 literal 7790 zcmds6i9eL<+n;`&@;eG04nmex_N6g0S%y@SvK2LCi(!y0rok9XCs|9=Il>GXl^BE} zNm*OQ2!qO&J%*7POH5;5-iJEpeT~jP@cMk_7 zK_C#H$?22lL7;6k;D`S2c3|ZEE2Uq7f7?*!jgNy0oA-?Y7r(e0ni+yX#kgI|&O3m6 zcuP}jBM%Rce9b*yzqZtqLwj4YGH*KrGYt&%U0o43Z$>_P^sv1A<;Ra7n9MO44CLs@ zi^U2P2r|!}DK#}|G8pH`dX@pj37K!qZZ( zoYg-B>3>czn|froQtA;80uhA-ixuSG!1O+zvmA0oOrfu>L`PvjHVJ~h59Dta>*8OT z=e>8X?DMBFZ}b|0f*k~L0rHPybzi2LHxxSe*7%RVzp=y*ic%CJoKPrmfYn?(_x_ga zz(e$8Y4j2Z6fY>0eo&zZ3VUsG?!zV5&sWfs7+_pDOc0!S(3AvquQ0hzyOh#*rEmiC zW(g#3BWQH(pi2TYoMe(xeW|GJO5GPs-xBDEoFM%8!9WLSQlLrkolCT=DDq)qGpfkGVuJ1sgc3Z>81KSFK zNc?*Bv@Hq*;(xpT+g9h7;|c=pb22$;XdUc0(YqtFM=$l*;KJo(!asjOvwma_^R)i+ z`}T*-)V?qY9m#G3HqD;h;XXkFkc8m^πvF(mB|8h$$g%%g$eca>mIlr={CFsA<~ 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 N6C?AJg~u=7_#Y
    -palette <standard|z26|user|custom>
    + from user-defined parameters. @@ -2143,6 +2143,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3078,8 +3108,11 @@
    KeyEditor Function
    HomeMove cursor to beginning of line
    EndMove cursor to end of line
    DeleteRemove character to right of cursor
    Home, Control + aMove cursor to beginning of line
    End, Control + eMove cursor to end of line
    Delete, Control + dRemove character to right of cursor
    BackspaceRemove character to left of cursor
    Control + aSame function as 'Home'
    Control + eSame function as 'End'
    Control + dSame function as 'Delete'
    Control + kRemove all characters from cursor to end of line
    Control + uRemove all characters from cursor to beginning of line
    Control + wRemove entire word to left of cursor
    Control + LeftMove cursor to beginning of word to the left
    Control + RightMove cursor to beginning of word to the right
    Control + Left arrowMove cursor to beginning of word to the left
    Control + Right arrowMove cursor to beginning of word to the right
    Control + c, Control + InsertCopy entire line to clipboard
    Control + v, Shift + InsertPaste clipboard contents
    Control + x, Shift + DeleteCut entire line to clipboard
    _cycleslo Lower 32 bits of number of cycles since emulation started
    _fcount Number of frames since emulation started
    _fcycles Number of cycles since frame started
    _ftimreadcyclesNumber of cycles used by timer reads since frame started
    _fwsynccyclesNumber of cycles skipped by WSYNC since frame started
    _icycles Number of cycles of last instruction
    _scan Current scanline count
    _scanend Scanline count at end of last frame
    2^tLbJS;(&~rcPH_wcEX;^*He=KIZ~P znnww*>T>Z!f*St)vQc&B2sq>1%tfgj2NhF}q3qm6zw?y|b2K@X&p(szgWV99pAXKy zTeAc&q;^X}DJJ*!U~;$g5pEC|UgNT*w1GL=Bj{Tnx;kUNg;2t;RhAc_5* zI^&ni!&=FsFavRgao+F!ZBEhYd&BQdW_joVSZzyV{i9h#@_VMK=HIjGSW)4OMBA*I zX#>!jHafs|q^lwET_J&j00*-@EK(zeH?apmEX!zOJs?=&Msw}9uE(c7_{5y){d>5F zI(oIZ5Ln`+4vmIKQ%4h&1P9#{24+4r!bk{&!skH`owk*zJYj=uQX@vCoNP=0(V2iu zC1IkT?PEw-h%~->qCqtSHt>aFWrLW<^#7om-7hXdcGc`@`H0i1^NPLCeT{4a1rS-r z&=)E_-Ms-3f#7rWgj+-tct3OiGLzu$EA_hgRu9&yv!b6twUiW7BjLH60H2TvWMtT5 zmZQI%1k|vI=ZKl?mqK18k}O*SnZ-{ULh?cNfQM%;Y2Df4y}g^R>wNzbi_Ds@uqi%= z6YkrZWE@*tsu#v50EJY(!S4_-RB&N5C2WmPM3hcLT?_aTjnZmveY{mOwtkCr0ij%#y1QT8n~NYLpZl*^8vv? zY`Q@ux>e0#3xI#I?CZl502hrDhOcvT(!z$ij+^&RQKA1a0^^ zQ_~T$m1!e{&>@u3jw>Fm*U{;C{Axj^bm}v4RxlLO`Bz$IBJ9N+gGkT@iL|ReSq_6H zfES>XmPg2BSBUThVt8d9jK2bqPKD6l*WW+)Rm?S^erd8R&H#%G)IP`o=f7 z<0KtB$G~8}wv5>p^o_APOh5{4xb&uqbNudDSLy2;zH0eaTWZ%Oj)CFP^k9YoNxzf) zA7O*3s{OhB|nkgX*l!t5k$OW>pKJWY|HCzp!ukPIgMp;Za1 zvkQ*{z3Npn#6bITMdhfH7~Y`p$(GyY3$tY-`+DF@O>$gH((y5@?O~q?2b0AScM2iX zc;quLgk*z#P~8HbAaUN7g}wznl%uWAqTna8;0cVT8CvSrgvOtgl5On&NWOU5xqxI!we{d!OV$9+k`qY4P;BV=eDXGhcmZ zjR9V!Pe;_qV`lVkLzqZzW1+e4ydf88lo3cgY~>0s(wyTWl{SXKP+uRmy^Vv+2uIEK0 z@(wrdu=J9ulOh@HoSb?LdX%R9&nUom1PCGy zaCH}f5~z@VSMa*zdp*_Jq|gWUY5400r!F7P&Xx&FFApFYpY;*W5V>JTx#XVpU@64C zuAJESIBJd+;6_*d*ILr6wandblUu|)7AdTZ-UGQvu1`l_~V^PfkpGERud!S|hJ1;h{DQxA9UK%r}UHsCfbBZj%?jt!+*3O{Mg68v5Mr z^*EaQfo1YZ&>HHBOaDP}QVvqYIt*4N(#9a-8`iqGpSjz4&g2J_${UO&Iy5S)t8yxf z5mP{JAyzOC<1$KHkJJGw|7rKtQo*(-X(6!t6erWD8pu;UeZHksg-aX2%3S-t{8M$t zntNe!{8Mr1!<^jBlL{jN3%_x*;l!tKf~^UV3o${N7Msxa zdNOP>4A9DQ&fFeh?mL=~Y#?vD7J-@dEfVit=R52uP9(NPAyP4{cP_n&5Rjip2ZS?NLgGC)}p|GbgM_0 zm3|$kC-2wb&fcuY*<0~&f|xkstZ?~?4&L>J&+9st=*L}|(vb(AC*Wg{gzA}KA{@N6 z8ld}?92J@!-W^C*9y8RQxSNP`fNU(+jNYd=2EP|(!^$6Ng1!;{L?>*nfASN;3wQft z1dyPm^0W}kB2s4lk&b`w9)ql50*?DnP7;n~DL4f1!Y?PAn4bn2FG_y`&kYjmMn%1? z4t-4kU^@$|p^Zz!=Fd&7dVzZu?Ak_@p$2qCCr?Jfdx@RFQwKOo*b=1mrCPmLwV@J2 ziW*5*vdeZ31`7F5H4HCCvk7$m_3yPyeKYo^Q~y`cPlw^z7Ble%+cz^!$zISg>7@#> zO6%8F1)@T6HmJepC$gvAD__64gFb=7;}%i>m4qKWQS?%u`Rs+7Nx0(SL~{blZJE#5 zj^v!{sJya9oA`v&P^K*zbr8Q*mF{RRxir{_+{Rk&eAxNgP(=7Hk|q4 z|299CH@NV#!UawTBSYWQ`@bML?#8n!^{Huk!Q@v8xDR!fp`X9C%wcmHk@TN&1pA?D z-=x~cKSYiV`YJx=9k-|G@|LG8?_nkvaL|Ct(s5i=A#aCQL>8<&x?S=v?z&cOTsb{- z3E^(PSe{2teMfZ}=5YcVF<*SoZmtloGkN7CF)16Pvu+B#(D_3&TBUIIV!OLpO=`C- zlKq3d0S%Mc_bD1B?|Iu28hP~S%3A!`&upn;l>0BgR1a0t??yuhwEe=M4(gWfk9}-{ zr^j(C&Rg%qS`scIYgjiSO+EU9GcSKd-uc9-2uELO2h}X%Vvfe9a{`e2ebEF&&l`qw zj2WfU@Q%0$biahd-9OhGF(}reA14Lkj6#nY2Bjd;^+8J*J}ko&fb8O2@Ae`kx0WcVTNbY=6^Wd zck5Zy#s%#L7Nci(wo35L0tKr3Fei5!g0(%Mtu8W&gTUcX<5oq7G+zXbONzJn#Vt9W z2gcZAbQtSz9??x;4wz%2eqpI!kT85wG9IVo-i@d9-lZM28;{KkH6N~Q#C_8m>Rd!Q znR9a56#B%aSAqhEa>hV$=m%$Ws5319*q?ZVKp zogepdI4rctXgNlbi)@4z82NWU6C`LA;e?;<8-y$-^dnuJOFHrKR-EsGZ?l;Tj>hq6ADq3oQZq)%S#}UY`(651<>Y zOqs>9yvBJ`TsXoGPNPIVUG)ynCLe+w24{X&F&@2Q7mN1}L6FGbBasFQ zw0ey#!(SMx)vL9mi>jm)YC75P%IwVtIBl~m`m$A#9eap&UApAyBjk70D*dL34eD+@ z@mG(*9ss2|5}rY42wJ~Q?O8HUA9cI{|e)j#Bir@X)vJz>|eZz zBhRJDYq857M5K3OtG`=Q~HDxyb$t3mWqM${#rXtH-ZnG>6uIFjh44+;Hk8^F-L=GM>mS%;_ za4?)1fMC|8mUz$^r7>;H;FT~l7dw&gAt7<*(F;F`+HSK3c@enQY2o&(_m55ig;{?< z-tpDMG>1WfRVH?>DXd&{VQwBwNAzNE1chHCDQRzi$n@3fP^IqfA>S)%2_XIcuxumD zcH~+n?CB2Wmn$&|Nli(uoZDL?{7FbnqpSnN9VGmMU6P+bO-&)R?Q$J^8P6st?8PMS zEH{inSsez4wRL2#lWK9cO?-UOJzARRPsMGP;`A%q$S~v74du(*RQ*>5N&~vt_!By# zKGb7@;EOo#{9Lp}hE=v6>B+WbO{rpMU!tw9Q*%kQ`+MjaQ5SkQonUP%gDRw(%otPy z_tw-;%IL`?xKFTxt-{l39h+wlQ@WEIgb+x-`O{Q*sxz2+>W>+D}(Mow;y0xAs9czFIxlQ{$5owpmNKFBk-Cs>?IPr~~760eq_}>iP)3F9g zj)8==hH0>N)4ar54G`S+Lxn0kZ4z0mr8&{4Nm@4S8C<_^J2kl zHEbTECkm&L?X_ii0!<=a!LV02B4@`DvG|XGlhX?8=vUH|5m=-b<4+HWkcbE8xY79Df%kG!o6>@{-Pz4%LCiXN7Yfo4MnNlZ0D$x`AeYj9Q z1rNIMB5iFIjyi%)-Ov!q{6#G68fSQq^@K`yr)o_KL4%Fj6;*sig0iLa_W~eHL!r!5 zeTh#^?nvvyfNl zc?x#F+LJpaPJ(9Kj^g+zI?s~?mfC6xmeH{p&{T}8*pw+hGoKqt77cAR|4&7^I078? zlBIv$o>=*ubVa!hK*!@_8@NcG9SRfvOD8#?%arPlxL zb77Ash$Yo!1I@oHqINPUQGN^?OQ(#3kpt+H-=)KS_(lkAd35k0^794pa8rSl=wEp5 zdGR$D3{Na~7i*4#!yV3%YY;9%Yz7Vi^Rh!&ws`k`{atfW+NEaD_%VVSfL>v56;mf6 zc)saGEUiNYnf{BDUE>zf z2+C%C7xxuR$xL zRsw0>)bWZ2LVJe675piu~u^)l$6bqL?OBrjOEz%ePpKi!aDTVwLk6+`=;F?<_`E~!wR z&%rXUUb#ZQFH_?8`m+b-^A~|iz_So@GgNy1%z^s7+%9s`a*UYC`n!MLxn8S16vz88!9T{XdTNZ z?{YltO#s<|O)$Xnh%)r=-cX6+e9*<2J3R}RbcMlQd*V!%%O{n8(qrJ{PcMl64@Q>= zw_@uMsr(nu!i$RP30WupE-lo04!-5##GVcwi>n}?pSut~1oPx8M*6EQE_yEYA5B|1 z7BHo~8-RXv1>N;`<_-sP<3@@l6yJ>M7c|AZ!B_}lZXqih??#{GKk#vj$1fYmVnG%s zhU<{)xtAcl11}@bVDFms?K`lM)2=r=IY4Sp^v9Ml%~pB4Uu&&3c0jT3QSWMXCd`-W z02@U|znW#G{vtlLn#j$1>&Ul-`~ijF9wAsF``!cMo_ajNn|eXlHNSIe6F56K zShwc`*0`4sb?ppLuV5_HL-Y&|7YI>vG_6GKrmy!sh+UPP1MD-Qv2IQaSEAR*s4wVW``}EEe(MuG zA!~;o-k_JwFSO!AC~4d(^sCyiCiX2D7;mUeo7D2InipYZ>zPl^3cI8J2y~lfk1j!~ zIB#+eX|1NN1XiPu93-TF_+%8%Khx@Yf470?_45~8$0utyeY1JWQ8HWpK^WS-9**u* zMdBx8mZdSkt+FlIxLm4}@0N#+;EZ_l@rI9iX-`Js_0t>sIh%kNJ_XIU zdjHf|g6y#oCfO&IVoGz{;ZKtBRTGFpH+1%1q9C0}4R$`)jNJ}?HR&?*&0kONPhw1-;KxRQ?_1vtzDkDl)5 z{GSs7C%LjP&NV^0C2tgX=marHor&+5eS_wo0dy4oLcjBa*C#U&X{IS=@5{p1O>Z9# zF^o$}=mGHXUZR@-G)QWNs@e+8 zfVbUwNtq_)5At0yWC7j%{pzHiI|` z{kML^vRlD)T>f?HSDJFeq1_%+EoKpC56gdVeAVewA(82n$7Q?@+(Wmoht?L8v=IYY zUFhHa(1mX!PIfQ+<{vUTTaBz#kcA!NwbK|r8MrEkOLtXb9kV~O zUtFvVD{uXDdF5$~BdGV&v_Vg{)tF|GKR%>QvU6i(qGZOV<#*S7%jG#QnMyYvri8!* zekVK=)Jzib@l50zOw?Y! zI-`Xh`q)%xlLUDB9Tz*m{C+p4yrhzG42iqTd>uj@SE#X{Y5LDF(X=}DI04Wt0q1CV z?NMAV%j@%Q)lqjYk}`Ql0TBm4VHHu8PPCYeilU_EwGXn6#Y{q%jI7k7Cb=BxHH4nW zdkV&3W1KlMz91nRY5dypWlZVv23n+IT)+qUDZ$^@%KEu1F6&u`Cbq3oGVJ*75-7Db z#2=dv2Aabfd3zZZ|()RHy26_oDB6(X?QL z@_C)?-P%xx{uQYMgErlTb#v)s|pmlq+z}1SykTYq|s2;UKYH+2Em)te-0JT(HB_)DmA-$@n_!itn zXhDyTJN`6i@sRkcSQqol{!MsLbpFagpVG^#G0EgQfjB0T%vKs=M=r%j`8>-`cA{ET z^W;)rw>dB*EHYq9-RN@MC#33YWY>7+9MRCUcs45Bh|P_EkV-(yfvSedgupNRCew(T zL}I@~(@{xE%M?aNxis8HO;%Un9^J=*`z?A0q{v;lwwLleJQK;|1O+`;ybxEj*sCje zDBP!0*jp9^+j9Ql@?F5H3mvhy*KVjSKT5qJP(Cy;VR&mM%tmnp0SB>0 z+xZO#fe?8vx-bHA)9l#3$hdI3sQ}UIc$q6Mn07`54X+)b$d821WP?F{oR8K2e1CYr znNa6+xmGRiNv&*(kI^jyp>cjPLP9k&dLaK(+gP+a^*0%EZ$~@XWc4EHihG`SdLD;= z1+w*EcA#9UN04>PF_u)TLtmh?+zGS&SecrsAMHp+%cSou@Z3$<3%ter^q0!78Ygzw zB*VzWs%Ji;c6>3koqgB~qVo9U)OB=0J;VY-=(+hR_(AGdGQePZf!>kg9Gn_YSNi=a z`eWtKORPTl+`P{@nK*YGyHy#a+{I($8`)(X$nTVob1dlUbaaenvo>jp5QA`Jt?>ZS zKZyQO^2X+8JqHT3{b`-|n@JV>Pl49Zcl4Ez9=y^NR){K=p8!!Q)2oo~BjfYdr;=zK*|w*3Pb5SgYYHsyehB1C7FqIa8GyFi-yjhz$TS0)AEt47Q2j zL?~igs@)$sVPayAt{Ly%urL=TER5zbTYwYKIO&}*5t({G@w`&8U(Zaa-P4~yW!#fS z;G1^L)fuW2%lC2nAw@AAri;h8xBWX7f0Q%+L**a&m&)H4x^GIP3tq(h-|um7uSCWY zWZj8qkLoZY%5pCk_>82^MXW80Yirm(K{Bi1UNw+!$yB+%lf_c(!-60sBV0HTjBcon z-`|QgzH!k9JId{h6}PITY7e_9Cfc-RUapil7FTGpsgiyTm$8wn0PaT_q-mwap1ujJdfG$J#q(}!2IYQSozo6Yrdnrf-HDE+@pjY|J% z+^MtQ0w)N|%#DglyJqdOO%c4I(_Bzz#QPylEidG)Lkd~R0RkO4l2~bW$fFiT_H|^S zB&uJle+>9k4#*_TrXu%!CjgQ4qaU|%kpnmsL`S%%zJ5zJ&2s3HMO_Iei&LXIdk?7> z)fm zFS!(sw%EDvPo@8D+SJgO!5?#l9FNt?k}7{)1`pr-6!J2ct0pBeB9=QZsMQuDL)hQ56s{BPg~pd zmu(#XJd}`FzxO5~g6|L60pzNBJD66CD!SJ%E>-tAjPgtVxQpW&ZwHQKMk&4^UQxcYiNHxwx~vvPAi{b%$Lfdg!$%LDeiWR(X<3FY9v7SxDEhV8 zSVPZ{+vlN255{HQ9>~?zZWk^;GVrH@97Mj+n2a*r`xEUnP-N3DiCUD`x4R>N)0E$E zZ(4-RD!&#oAou)jzx>F(ZDILZ_!CmhT~aH=TY-0@3d3=&ZNF;l9!d*zFX1Si{A4a* z@XLr2%_4k!7i1{rH6r(^Y-}Pt{k(?H5!p@kH>Da zVh?EFo38*RFO=Q0eE-ecBC-=V6tkm{8Rd84!I~(moeEr+Ads5`XJ`7_8(R`%_kMrt zIp4FysrS~37`+>vax~S99#W-`PUCM!Q;&`4uk*O5jTeXNKE_b_a9iaMZDYnNCs#go z31B6N!d@UQ+hn(`@ja=jB`zVr(R%k=!fn>5o0o_!M#E49CxqY}T4j-uq%Y2jq{(MvFT(0=Z4yrYLnc6^Yn}?Ox=ln|^H7~WqIGFp#UI2c9 zYe4>4W9kW!()sel4PKu&RrbuU>uYa6-Vv&(jvv3>x5}oHnO!ppRqrXhEW^Dm`~crE z=?CiznUy-7^%0)-{_tm)E!lz!#e5V=TW2FLzwupri~IL$49Qm@$rl_v!ajFMPUO>b z{@%0j-QLMj;Zo=%>AZ~VO{KP>RWr^Wc|FBDm+dP>+Dn`X3A%r~sS30H@&Gk7s0u~X zDU9O2#|sBvMrxPdc}~E1)6UvHD<8gfL>*4=LTZnbta$^A)B%d+Em3VwzM$S{n_*Iv z_rb68G(_Ki0$ODIYkZYX;u7~GIifFrjxHt3VSoSrmyZ4SLV>9-@R6k)UmrJ5(j#u& z1;ZkcuUGF}*D;GFY@s#1{{E-c^%G)tCkA5)D!U^VA0zqRZxgph?(9|KDBHyP57YhW zzxBsr`k8IV(TVN$J%T>3uQ{8y6^q=$&ol7OeWg|_+pN@oxw9ii(-uUd79Og+|AE8oX zb%Hy!+HDcARP5!`FmG9{rVsLsBL&=Mr|f@cJ{O)+$0;rr^QdS9kt)VknHv87j|4^9 zuP3)6%6gAW;enrb3&`$-PcPfcT)Nk~w~TWZoHUl$x)cW+t8X$oaVD+r!dIJP{*BCM zM>?sM{&c9ALfEexhlLLFXa5NXHbD1{jnHC}+GgPGx4rYVC8{h|dT{@mEun`-(!BM6|6y2+;>+fjH&QCd&EN0!0UMPO%XnY+fSkT%!%)D zudd>lliM6B9P;rG0;!04Bu8>o(0YN2^~yUX!^Q4Ejd>YfB8DDOW-ep;Pu}sl$zR5` zGc^e;yBUqV>Yha3rjit?C4_xu##nS3LK-z9;}LA!cbQASS-tn5B8T31d)d>L7g31e z8^eWkB@}CAr14)Zk>h!y;4{;`XUMfk%${3C+QTTSb?I())@REtl0rU&WocINthCfG z80!5>IH6dKXm7GT{9_7dDt z5TSC!^a39*Xa7((d1%c1z4kE*8#QD#T$(4Ol;R^n#!u&pC_ueZU@{{N-NYrk3H3?c z_<;6OgdE_=1p`{t7DypqI_=;0k0+<`&wycECTj${HFt#Xy_oeP>M_zW(N=RL8x9Mk zC?Ozd{HkrypR!CQFd(;=!FsH$T+46U{?s-%`5T{h+B46ew}H*j)p)q{U?b5LUHi52 z*m^fU@~kI!LUqNz6*WO`eCpYMpIpsGbXTChZP$gEkB>>3{a43|-+&*N`fbPXEd!xN z%kMHapeskxSl ze?TB&QEUnZjo%_}Rs6y!+4k5s9~N`@EyEwlEBM&6Hz@yXy+bmqe||itRe>t~{G{lk zT(X_<0T6`A^fkT_F_A-kBz>9?(LbNWc}SxelEdLP5ajiMa&dHuqrNK5Me%NQX7mAd z*e^Zi*LZH-*{UMX3o&bRX6H+2cUJGjLe!z1+Kl<70`4tu--{?|##6vB{978!q`v>& zR$q(t61U_fh%(`-R`L7_U98xH%Tt#cv7(^^vK+hSYd(cGtOpQ?X-p(FShuUjjy@Bo z+Ne*s&4=PYEhpa<>=JVqaf=+1ZsG~D>5s1m?}?zK0-g2a)kpn;w#f9H43;Hoj$SUP#aDpRo$xS-PY1WvATum=&7FV@< zM7HjjIyUb_pD%R3qOU!d%V#6s3A=iBGkq+v-K&H2ZZ>mn_Q+^qYbWj&b;jP?>?~hn zU|Xenk9}+U_V2ePDkfmN)>0eU5t$Y9qZXS2Tgq|rMS8IFZ+dXK@miQ#?=kamGZ)8h zhFlzf{*)Jy>$G<2H|)3(_#@1qb?u88WSN5t z>9yZ_3kOFSR4+@$Dr9ugVnfA^)6X{_QQVDvrgaf!EIV*ne}9(!$J6#PRHIP)5s}i_mLXh!k_!CD z{PM?-EbCV_V&0K5vp7zt*}M-FcHaHcAGuuB^^>oZ(BZOw0*2#jW)w{KnG1z+#@#O= z!#UYQ!ckoL$z*3;LZ+!vD7HVNolid1fhLRI+KLT%=mKEaj|^K z64O7)xLvIYrvtNHT!$aojayPv*k`Q#mat_!-~Fkm9w#c|Sh$a!NUn%w_6~cW$`fm) zkC~dGxA6ZQse1);HIk1=7_CG%Oai-6Oisb{>2XP>WX2WjA!+YwUFPe# z;-+f7v*$k2spvbK)&!to$P^b_dP!^~m`>NBH^mv^!=Pe5CnrbWyN+c4U zU3?0Ze*0}Nw{g}oitgtYb ziaLjFiMF{iCFKm`NVv4uVRsUKlHylaw2xn#Da{CpBAxtZglJ<3FPUBZjKFeSr`BC9 z9>;7=eeCV(k&_Bx^ll7aj|wAJt<2P!6vz2QP}C&tpA}}sqNZ5Q&c*V?|JzFk?xUxU ztnY?|iE@pWe>@Ak!rPOTWLI<{=-aAsr9J-xewS~t!GrvzaDE%=My_>*p8QflwhfLN zaE`9@;``QTrcLK{({U4WICt+;!SRc#I`l%Jm7Z!;=GS32z^?nub470{Dg8|;3{X?5 zVN6cpSB6!a4YO$+X*;uG6|g0@PqDd*;UqmgUhKm>iv!yF7(w}jD*M`DX3##$;ZN)@ zXLLAY>e$`G=lk(sc`!}e4(+5&W_`XFg@hhUt2OD&t#pfoZnW<_-ZVU`=O0bz8df{& z%k~UU{#dDWrhONGbE$J&?WacD7~(`;N64w>9*Z42IRxUXGxFB%_ryKfE&5BzG}1?h zX$Tiu^nVjmceWF`A3qrCgdVgA8+}WO`qo%~As$H3gVGq-Pd z-Ri1(o~kC}q1F8N#8orJ`Xb8I5N$>3SOJz{R9r|vT5PH)A>@Gcdp;v@dq5L}h4?0F z`ZIl<2$tbCm8>wLTlnt-U=SZo*EM7ZV&xD1jm5viXQ^dOUrUe(>0d|ZwWYvb#D_$1 zP{RHb<<}#%UshW~q~fiSUf%%C;N!@C^Q%@6^z}d+2R3Z=9|@{jzWod3QHsK~|F=nu z|G#S3uV>)-zvAvtY`tyS2*==mmO)VSkG3Zv-%~d-LLLv-(_8wyOp_J*=TdXOSd=tJ@1Ij%`JB}8!lU$Qd8DGrJEY=Iq z$^n)4luHUco5OJGtKN87|LY@-w;?2JGDd6R6zG-m(j>YH64-T6y=a!zcrT^hCrlT6 zFRP4}I+Hi`(5OUIb8&alquNV(vr-s!k%K zu~B5XRuO^-<1OKxWWQX|@uIk+_vQRU$S=dIbm}?awiXa?)p*_EG&}PFK7Qu8!G*??lA8cE8_R)XS1eNwFNx%1OL1O2K8iP{{C=tvd0}VNy z7G>vlNW+I4R@BI^1wS3aFotkLHx602|zQlKP-kc% zFk{j$U|o`_9f>}aQt&gSsY5$N+Utkx=)e&M$Jq70m-fU|wPTP=p{3B@eWWs7-@>B# zP?SIwO;fDe5~@jYwN;|p^64A#kT7^kHYKNlfsS=O7=L&xUjC-={XV+d!8(Dh9K+S# z>qADWalW4_2myX3!7^u$(f8UqVR2VoYq!a@Si)A)avj0q){fEI#o?1!G0YefA zV=3br=dLUx2&O$4Yl|i$-?T)uIlw?@@N`ER242D;zW)O@-G^tYn|B@)B9hF(N#w~prY=xu) z=9RA!M;0+JW9E9@PU`lRcF0lFB`2gpR4GV%bLIHHp4fWLy|es_xEQBg%k0 zzjM*~V3*5KG6cV@BTPQL0ipx<{eJo*iWV9rwQtI$EPwx9piM5H|>;gjcDZ= zau)d`QSSmO7|1Bo-=oDE}isElIIZWn?kQ zkg9CA91pSZ!Z+Kt)}Y9DmDa-#LubIg8aJ^H|4gOce?}1S+fdb0g0Ec6*VZWw`>%Vi z|1-)mY2N0L-ar#+L(D*S{9)@%9Ms8PFV&Z%rS&W6D$@YX9>IR4V99EWiA| zn)dY`M*_WW_0W93hzfW)X^iA<{Ke#gUM5Sj}#yubhJ| zkDHqKAWeL^;O_^b@--|=YmNVuuA0HwuSWd25E9Kxnu_;`hnO;mnfDopzOA>U%9J&1 zrQlduwRK5Zhi}S9mSZ$YAwT8!nw1j#l){-sfle6w-jjYuw1Pc^X+ror@-8w*JwAlI zgv6#D>yG;e_JA<$<6{TeRu<0v@#{TELYFiNuHzRY4Fb{(9~DGB*Lka2bv`$S@WFYF zBSEq1oPf&#SA#AWgJlVy%JH!_GR2JIs0vai_iKhnhbh923-$;rgawKMo1P25@NffBU>mkmgVR9O;rM8c(mf$R?o$fr z9@ygklzJ~!b&W>3^Ke77PnBPQ@-;r3Gdp24{YwEska6+S`iOkmg%PQtnt#Mf^jEgVU!mgkX zQziU<@Zb_%c?4|rpP*_6Bxt7q6cRy%HgK+5QWr-y=0vsxL1mu+pPm0-q0;dD4D%pZ@PsvHJf%+>8Icq<`X@e=GTG zx73IRUT6QcX;{2|@n172`0r%E)bPq$rx|7$Dh6qOiq3yFz@1-xrVwb-F?ELdhN=$# zTU;f8)&MEmuJ`S0G|?Ova35-}{3CBM{Is{t!YdYAgKJ@+s_l2K{gLtPW<*VOYLoZ0 zGEztbRfF6y!2Md$h2yR1J^@hR+J#wN%?RhtuY3ugvhIBft7}=OdR+ zD8|oiW$%pPHS67w%;2F6)=i}G#8o^_-GA93CS`V3&)T7u7pTj>&qZc}PUUW&%$si1 zSyR{PeLGcQdq64|RqfV^;o)gwi1&`_X@l_(Zd|@HCi#7U{xyvzR!}G1(B6+-QXk#V z4IBdTOdrMK%?np4p$s&0I_6+sEHM&XO=jZjLfv2r;o-g0O%}v7sVrg3c0!5fvd#p5 zSf|^o#f09u*b1?xusGiW*7N6)X@kOBv+YKc;74DQq|?R_zgw@Y4bi(4O3v21@5R1_ z!$$Q1TIE_RFd+6%H68PPnYd8?I@zE3;fXb&YYD|B;syKyTU}Db2f_0>`Ql$~}#0mbei^#p2NJc022m ztQUFn(q9dTu~K?=7KQn9mwuFR$l;$ArL1`lrLjb0gU_nOGAsAZ-u-Ge!7vuknzrHb zeLAKGc~E%uo1&DKgcMG_gfoF!0Y0B9VSrfyqz)aaj`6dojlpcUqVl=Cyry%WoIyp+ ztyQAfC$^T!O-x-lC?-PbTCu24m9llTh_Wf9^x`T~X*PH<~%zz3*U%$Sa9B) zO=4U=o~5fy^Yxo6rki-coCDi!<7y6cag_1n`C^C8VUdcfFhqd_s(=hHB_9rAlSiMrMOyk*tOD4;88+?SZoY&Vtxq5OCkgF+$0P0T-P# zG}fciVzqLvXZPdH+uTZr|4fgzP)N@1Zw!}R8?98VsDsCC|4?G(frCtYrK^=vd?w(2LOoa@ zX%D^jYg#pEJl~x$mxo5_@}G~yDt7t~rtIq(;~$@09>0SyQ;W&hxOn=Z_Q}e_NE!KR ze8{Zv>?&Z^??C`Sp{O0VVz z6x0{w|55BvP~{x|;ySNK{~zW~koMT?G2@h7X0u`>v&+z-;`m~-6Ur4Zlq8w}nXUvM z-nhQlT8;-Hjf4dFo>84yG|RhX)}c(Wv9DeC>}85le%TQSEJF>@x43Weis11{Sy^9J zc6w(|u(ERN$kNm8hl9L1+GxPCDEr_B9%b3XTT3StKy z<%Jzl3^P4SPQpFr+A`hO-F*-PF=*T_B_jS?04SV-kCES43bP$ZY3Vkl7zJT{4e3!% z%y;3izEZ)m1~kEL6cM*Q(NM9v$Jg{GWG3uMgydrsEUsrwv61N*7Wg|CaM>D{J*1HL zKPztwHfGB>;Z#{#saXhn3>{a~Q3=oVa+k1y{y{ib%E$bLW9Aa3>{8}&FdhUNDwD%8 zbd6=$AV1Mu*142@0k{_7{U`&K%6$LU3$cPFo6j$!*6 z*SO(1FI)_S^$?M)HY_T#tWVz)QZ+DU~am=KMk88wm7mv-bCb>2B`A@pZbdpWxE~ z+3TagY9lFFn$MID9WMf%C9U!mTe?(Iv3`hXA&XK&mKPia;9SlW{0>>#lE{@ywc4ah z4)@2E)A%*E1_Ytyu9K>n) zC1)kSwZ}BC5Q&G>7Z{??E4@cSc@FE4a;lQEQ}x*TZa}#5 zcEjxv6Ayg{Dg(R^rwRmNQxVU8sebJjs-mJwE7FEX4DR6%5qMTce>PAwdk&z+!m52U zHu0ByGH7i6>ems%2!hK`7!2(A?I7HzM4rCcec6;w{@oWnu?|@7EyB-u*VaXo2ld>p zRlBIYblI48H7vAw8xzO!DbDN>Vr~eKOUj5I%L4P%yb84#Bx9dyZW;H|@^Wsig^-~9 zi4usMLf;E9k$?I|OiU_M6ar>f?&XL|=f7v)L_ZqNpmvsr*Mgt7iL-UjxwWATN$lH0 zTDYWG|C0w$UCX>zZHb@XYLaBHe%ht!mC6dZVQ5nr0k0NcoRusho#;^avw{7>5kG&6 zx8sy~T}$OCBfQ_1nO}T7Q%u)%dL$T0@+}1QlJmVaozJ}a6?!!Bg9O^!GNmj_?>z+H zR0vb>rbE<1q!h4)=W7%64anCwl~K~h|2CEv6qPq!*vdygnHR9FU^$tm9!*vYt=*KIDGCXt~Y5>E!+eoG#6qZz^T^aD8 z%l)lPGr!R|PB;#CX(WooCjQ3rL}KAoR-nhgae>iHcWidZ58GBstolz0udi4OrBiiA2zLkOq!l}X>xUC*Bf z99jSz{n|aX9aZIx4>C=KYm-+Uq2v8Dj(T+m(hamMSp4TYjv!1s%w|hq)~I2BRYMcY z7J|gw?TvR_PiDO^sVZh(uJ-$`JCS$XcqoM?NcU0U3S6UPz5MXXdWy@slXY~0&xs8o zf9V@n21_Gvola(X*~l(Ch@VmmT*Ta3s><4v#_0BBrW!BYO!kSL8KTZ8(L7B_qDp;h|?(8)Le({`Q+tx z@a4(xnZa`8I^{Nz;4fT_?zq!?>nw$;^QMx@1YH*bMflG1oCL#cI+OFt5_iS3kTOsC z8LP*Je?4UnFqC zG`Jv{Tr+*Z>J!@g(p+M`aaN!X#2! ziCCU*HF>x$>_;JxA)9hWaHivtBe%#Th-H_a&%negOX8P^_K8Biw4_;z@0ET3a6y9d zI&Ojz1HzENGzy#u9Q=h|)!Y*wqvE7xNmSqS2|VcgX&pT@BgcC8W|-(eTcmCvgt-A}2oE8<#m(Ec#8WRb zS7ib>ixPg%AHZ*Me@JP(tvo5*s4r8u)9GkwZFX~U_Z?hcv*;f>E88p zjmdJyY9f}r&Rh}Twb1+68rq~QSIstqyNDApe?MJDwG1`DUv6UWLk;D$288|XA*T2M zR8>wa5lKfu_ljTj`vsZbena-IIwku;?sEITfEA>!jLCpInwlotCjO@p)^6m7oHNP% zICtu+#&*3I{FhTZRdC|#W2M}z0gh9_wgiHDD;+OLl&is856cpMdO8;t1fdfVeN%QX z7y`B_zk!=uP=6V-d)oVRCtKt9{MTp1-i=z|#!W!nul?SsLkvxd<@dqtw^6joVuf2! z$1`^RM*%>tUV7g}L`e>wFIM^1%@rUmW zRxTBKvEnesC3Wj|oy}n@rE@5S8i0RZVOENm#*MuHLS$CBBmlJ#miP||Ni-YC1zCIx zIAFC9fhvSY=zolLmd{RaZSqK52d$LRRD2HL7Q<$?xs$WrTy<-|oze$(HS^6<(XUXW z9u;Sc0ZZZ`uY=%n6(W)>B3h%QfBRmV`B{x>P`iM<-jAr&dMub99a$@j)Lgc#)LuAE zInG+TSUJV>Y7~F7-E77)-B=NHtAg}`(Wo2VKRo62VN>i!o6Cni zAJ4`6JHRHG_=-pNeteI1?*jDrnF1kZayt0z(@d)UIt7DsX+A(-8k#EM)Ft-}FFwco zgY8e46E>EaOUB(F)7SNQM$+5&mM=A5zge_p)fTFZ+fExcB=#i=|32VILmWe z`=zJjoNx3?eEy%YF}V^NTjU|)P~=ru=bX@t$IuxU%OTvB`})e1qZkGNDWQc za3hb_=+s;{g!CpBF0&byW2l88$tNPZBshElp#Y(v_4FKN+KeV?qP(xTjsfV_D#eRG z+5%=oMSa17D*P=$tFbA5Gm`l!IsF5@=|9al+eBipm`Gf*uc#p*##;i0FlM-CiDgN@ zibG4(@j2rKH+du65qM*ZB=FMUhs$RzXSHS>NS00_zPAtjK}C){$)mmvz^(*uz32*Y zmNplsk(e4*bm&!e+-_v>G}A$40bjxIwZ;b`0&gPC>DxF_bu|gI&zSy;%hK5$U<;Z&$&}VDCc|~ zO3`%wq$CY=Kk;l)ybrIopPCXsmvKd=Lbe6-ilKV6yUTHn?{na7SIO~?3l{@mf^qgu z-k03_aq7Y*FY^+2Q?sxwwb}*1#w|x~3sflS!W74uH&DRC$SR&aIMmkuezM6N%tS*j zx6X?j#$ns>M}VKJKvSo~cXYPQNbe-109`hQY1T5aaNr?|yBsw}E*llF!MENNEO*oB zq?}GG@<(!3bk0Oz6S43HZcUo;q4C+u;kX9f^?-tQy%oe8-W^cfo6$N=Q}i7q{q6mz z3HRG_R=d%b_hF<$x_h_EUEY>45$DehMV8vG5 zT=ZrzKscW8jV9ua8b@WNafp};S&6BJghUtu0)pGgGF}I>Gknfc$lcy#UQ|>RzW&e8 zBDa0o6vE-iy1S>6w$z@uglQv_lka7}__VS3dd|C%EbTA2)-D`ec^YLo;MB~3LspK{ zn0CJ*`LVuv6>3~d7AGz^6a*)KxkU34yf=f@qG*~8-)wSQ#W>DX`i@9?B{0x%$@272 zFZB@(*^$0`i-zh^BOb;^iH`URx@rtiDhJ)O=XxUg48!~OiH$5Mi&I7Rt@@ ztcCINbue>0cf~x0yzEu^`Q=b#;@yt%VAui=WNmG0gE-`CbtW$tCoiw}pD4Gef*KsJ zfUg7H$c$VNlOUm&ipG=V;cc@lAMt}$g4nNhHeOy{-#ufIRqD2{gW8*L(U7|Nk-EQ> zi4jh-TK8MjFJ{Pr6bNl?5(;Wey0i0UyJv-9fp)NEdb+l!hngtm{N&BH zKV7E)H%)IX?n*y+G1|w|)6>JlBIOOPReh;aKDPjivToaxUl#Q_WXl$;e?DFFe6n4hUudqOV_C}|TDM()IKhje zRi|i~`eqqQ_zQ8BnS)%w*V$vC$?GQCg2=aR$F+wLe!smQ0fWqy8_+iTtg=q-D+id0 zcq_`oU&>tU?Ii<~OhBp2+LM>xN7Y(a@Y>9qAdWV6MQRLDX5bw}Yv_QKH5F)s!V#NB zO#fvpyz^feRYHYpuxZmhVgEtoo~|h0#(mGJX;7rP>(jnH7}hB0h;mb*@ZFkH?pNzo z-Tc-pc81Ta{4MNB1VUNCzteAABEB3HO`B*FC~^N4I&ICd)Ltf4A_;T; z%Qgf4z}(bTs2szHZM{Tz)RZO60C1`&N?-uwLc`Os0tv}`TaE@r;AYeBY@7UXAkDC) zHRSJVlLMa&9`cW5LAmfB@k!wQ#f({*!%4f!8dO?18{dsEge9qb&k zQ=$0yXfLGZ#TsBObvH|sYZcR^|I;f~aN-@~*I#qEb_$ileGPjIaNZ7Oh~m9@$z=VS zLyzLmK~%yv7QbiNnAYD9%KyFUbJNzi+T!QnOL)E1cQ#SXTmA8;f(u}|ZM?q^37kD# z0D(aH!h?e~$cI;2T{knxU{|lP1=Cgmjh>5F)%e={&m`+-j4TwuxSu|LlsO|o5h`0L znJul?`bLv$np*kw^K!E}=BngMXy_YSQ~Hw(>XS@mR@ok~##M`Zaj3*o9NSNG=Oxnb zEg`J0ahBIcwRMt*^kLax0wjC8>@!vmUbh>ErJ~`nEg* zJ&ya!jY)&du~@iWg9@#Z?bz$RBMq#mE2b11dpU45%K@-J&qL zk3m#X>HcV#P6@4H^XmWdN~tx$sqO#2+}|F&m=)z2#WC>UtFDIfZ>BI=PpHEheAfn2 z+`{37`7QzuLzKerkNZnuoc5+bJkP!a@sA!J_ZI-O8z` z7l8+m1q#IfD&y87jgJcS%zR#>ThQlx{q3ZfxE0|JaVq%jNtHYW+@j#GR&n_f`;6D1 zzQ3q_Rmco+6gUFhI78Jkgx8alro|_5uuv%^v=+SG;)66SYyma>nN}Txl01atJ;Sl~$`eOdqZZknE z;X!0d6NcUXt}ZMutK5XIr7DQ_*@6yMUdm=I+w}0k<0z`bG#}rfiSQ1u zYEU184ogB9(fatzbc8+&H%^*=Btm=11YJ#-FGWwgA;3e?h|l>-LxU6aka6Tnneo{_ zuT9}h1RLNjx84u}tjXN3o)DK!$pegy>i_>qFyLHpt+~2-xbrIj|vi(f7f8xaQ3hzLHk>O#ZC>Ez~vUB|^*SI?K)0Lx%@pZo_%0-~M*95OGFJn|PDWfv~KZ!TFsx9dF(R3)f1sn+y=kgBnc!p6G zY4e{lTOBW(tXhM+NC~ZIP`rL3xcmA(pROA(HAuk?9n^mquJK$UTadzrc(v*M0sPX< z>8oZ1Y_}eTWjus#On<}#>C{S{fZNH`$?vF17`ppnd0xVVfeg74ZIgSM%~23&_B)}k ze%)U~TGCD!5^P|pUT2t_!TayDa|3g9&(vdV~D=-*fuSJrXeai*{3Ko!LRsTw6u^f z+7WhsXf9u3zJ<98VOykvxS#6p?C_)@Eeu{8dDZ#cZf@uWnk%6#x&T`&)w8qlA-jms zr}zeG=&A&X^*N+D{!i|Wu^W_fgAsGlGXw>a5+{=KiYbLnLeUm!-@g-w8ZI_eeCCIQ z7bu-Am}PkY8g3xK&wG!5e&V4T`P{m}hPNA&sUtf!5g`BeNr?)nAUKz*ON%+=YSU$$ zCOZC5V;AZ&Q#@rHliG3y!OpQUmA7?B!A49;51!yhC1Of`lrJzDRRtB7p6u%nPOw zghPDd0W&~it|Ur$6Hum96SP1dcjaS?uynQ5%N`YjE@ z*Dd>bcRR?1M6J2Y_B(+8o%Xw*cGdN6dc}!V0#4>peui-_ESFqV4E^XY<1sH=t$+FN z+h44<@EtrcfV>v;{Bq|@GIK=7iLh+4fpxE!(d6eNf#+R7Y&hUXyQYKqd#|ruBTc~w z{SNM_&w#vCsJ%P#2^ZYwzRGO+g0!RxFivz5(oqupM6*vXvb_m(F~#d(ltB_dvZFyq z*Lk@ItYL_b__S3N-rm&Fic>+wo}V4M-A_@8{Ln8X{F3SPZZb@0OG0WEBQI+=gp^K(jJ`anKcBzcG`nFWyCxk28qsuOwET zD&v%Qk2G*maFm;K@!hcE)x{Pj{DOdt%{Azlq>$t4Jd#1RYP!o5c5c8Ffbf1SPS&CO z_KYK|x^W?=gHl=Zb~${RIbUH2Th>CXO?;d0WWCpwM51#ERR!6VPevk$Pu;wa?*<9l5S z5^g1Q25~l09|Giak2r0Q0HX{CY5Jd;efV=_GKiZ8@obm^C`VUE!^6LR?S!gUKSoAp zx!B<%UwMA(ZZ%TWffcW!LFc<4-@j?)^CUzSe@6pLp>J)YvY#k-?pPqa%jF|JUrBIS zy{;$2Kr*!b$ldEl4z~D%0JSs1cdW;DPnJ!-qWp*Qt1Ubp417ITq}A1eBV8eZ->GG~7)s1&Yg9qSlCHWgsTt4=OU!?h9-l!J}<tDvgeZ7`Cd-_x2#{#su0QbMNTo=rBy+oUb+E&$5r2wfD_Kp~drH z*5jblr-pe6ti96(Kd*uM-s7dl2bLp+syWlX*m5rK;p@DV;Tgj)zdMBfh@H-*P{IY? z-sB$M9J@{Dw8%?>UIHiziT`E%0u-3o?0*y(PbN)HxvfzdxVM!*;|bBG+2rNqZf-C# zeRkBOcw_A=3^b3nGQQ2j9Pva?n{$wcQSmzL@Aut>9CK#Q+gjx*RpAux9_garVRAj>IxUR3#{iACp-?xg!iKxUmfe-6rfq6+9SK=oC z;{*i|YpRg}e%;%D277dK42%?0)euntqZua2e%?KukfCPd5+5&bjm>VC7sem=P1&h1 zBfL;7R&9}G%#NjFQqqj{tSn_XU3!fWqe(B_l)dRTLqkD)C=(n=uw2I@grW7v+sm4TgNaWu^O3!70N>AlI}py$_XA~0tb!&% zZcKvgY#3)@5Kq+Pdw5gr@89RDbY1*DxtkjIJS9J4`Wege&MOoP-OE1`cTkck9Z$vv zefSR3_AIFLjfkHGY9U}uRr*-&?@`^Eb;ZjwV?lDI+JKx<;q*Rdv`EnhP2R!HQyX>0 z%!Cm`*4u`*NRS7~^Ne0!JcQf(5co62^;7>dS=h~Awbv8LkJR**8FU%0-;GHTT<Ts*$G zxUf~1Ozx?Ts=w|tNO?q;s0@;ZMlXs(_nGX;zTkl8E_cZ+eCi~lqFeY&9#d&#jS+zU zll@8#)EjS>IY)xfMtST^zDCt6&r#|<2 z@586&q^{1%eJc!R)Lson+$h?cB(_isjil|>7-tjfgXsn_fqdcx7{R0*_M~8`Rx7&% z6sr>_9_E`77wcAP79Sih9pb*YTHXnvejgT*grJTvmzbajJJ}pQRHIAGEzGvatI1ZB z2hxKUkz0}(dT72T^k3O_36Z)USo;I`|9A?5zGwQP(gEn8FN+Q_MGpirHgA3r?f1L3 zifB%AND99C)1s)OK%UlFEX1hqd_Cz06NM|2`dbwv?=S8Z1<8;V@tD{LbMzs@43fYdsQ*N%Ai$JT>=Vga@d$_H zeEi3T+jwD?eutyXm3?P<`EhjgOog~I<=Wa>m*d4*t%{EXs4{1#@3o!>n53|{VW+-w zxOXqW#zJ2YS()Cjle*qR2F`ST><2g}>;}q+ySUT#3Smw3?Dg*tHF430RjVR~#d6ul zXPj$IenKGiK@Z3SWFa2)`@fVTL9z%`Z>7#3Z`*z$riK2`>>c<%B)NA0l!ew+-DVYInPR{*>3S2E0|(5!YV4HXqH?fyD#m zVR!&K5hV@v)5w#W1lLKq>q|*UHR3_N?K1j1o%NhQ#Qy5O1$skT4IG5se*j?2csF&a zpzE61GJwT+7#|HLU7~*7vp>>U=p{L*8O-MA3}G+F_j1@640>v}SxUx7dmCWa?(uTm z_-EyhpQE?8qpR!W;gx0mt7`i%!l?^Rl+16&$RVgzH7Bs5A!UxZG`Um)NJ7d2cAx{yG)(`6?9URhnvSG`@>qQQ*P??!GHLCe zgbn2coKiZ-SiT|ON8FjywS0uF%a&413LHZHadmlX-nDh5y~#Q~D}$WZ!|~<0RsZGw z`(J+dzn7Okr}tw;X-3spk{cU7R_ZKJerRgfdxzH--#s9AKFZd|PP^xqv)#>d%JDVR zMmfyP%nTU&Se$HzkgOCcQz^8MK=`G0;c#IF!-c_2(Q2~aoFl&d0~BzLwIAw zyaR}n2y;$wyAghBSQnSrJ~agz_&iP`@)vtQYGi~pC86V_$NIk4V-4Pg`}$$s&55ykVD2$ z-iDlb7fb!nXmWbE1A?0LiP8Xu(lC$fOe(satw4WdZD(U=lQ?XIFx3`5bIK$psquqx z|2=HAmdquzhMp{9rxDVOi?s>iprfLjvMZ1-MH2nO38#W(DXLJcF4i0X zFI)2M*E`?;cwdY*u6pctZT2I`qsK^+0CAP223?5-{F0`M(Qk)yRVT-KKxl7c604Gk z22Jv9wB>%EPkt~Xl84iH9`bDOGU{Edf4K_dmFG%BpHuM)H}tIX=GC{W(F$2d>h)b@ zCCxGlDM_1bH8d>3lmW3LC zAiU6nzEOTQ0=5V0ivAvK@CLa8Yc*%M2xTH+7%@U**0ImUcf0uP#nnYBW;X`_l;l{- zkgJk7KeCWWV8n|$JUsOBYE7`LCyL;xnP#k~V%7jpzHDuj3PFNGZ{>AhOV=VC&MB_% z-uU$IJ98H(MJzJn$K>a4DBwg}3N~tIX~7w&p8Az;D6O#RyD!YQ(?&^2zBf0IKWzu< zFh5s7QQ%6Ci5<557*YsZR)Nq#QRN7#(ORTI@iC#JWCMnUL$2zC%o%E$ExI9yctJJH z!SnZnW*YVqNrV>!PH5|}WmsVU<%W#ER0T{-eAs5|=HyhXR~7a7y)Gz#k_=IZNtf9)09ppTxd_Ac?&@-l)jXk})ktZKAvgQrKv+b}h z<`+TCFuR3;_+~1jLJR&jU>JA^n^eMv5{IuzpXXF|#ODqQS>uxD+*CK3gv+#6QIXQ* zWJmJg{Q>M@kF#fAj!nJc;L{wSptEc=LGIkTBK%|i5UFd{!cB5N0@--9uH3P?POmD? zXnDSP&QkRUxkk0*3vLKHQ{uj#A(eL5(-TFRP}Xg{F?tw|`|wO?{-15rAa2Iwp~_#_ z#6g$4fY0u|Neswo1rStw@^{{R?uw6(SFS0O6{#SGQj5FI@_+97bZ_UEI+g8Ur013O z!!4Pp=mDz09CwlCXH|Y)zBUR}t;nAfWuurVGH3Z%2YP!MqPZP(^eB(iXF;x*oD0XE zT^e%y5Zm>UM-0MmdxSG~5no!^cYT}W{l=p_lj(XBL(ZruBJUH366nw%j`@czCk5XD z%#e2}1AT#Ud+L{`kC&H|l~t`;nW9Zs&4BWNP(YJTodSKzeP6CLMybP3V@HqP-q?}6 zRlvRYQZ(&x>7K<@%5#unDaEnaF#m1~q-USF7yj%8kfXS=wUg8U zV2%&aVC3P`8l|D{>VIqE*i3TNcCIVBkCV9+wLNh&=l)2HGKkogs(qkD9{0_5e=wB} zA^uyW{@xszRTkzF0VpRyUCx8KV9&&&-}>-{DDZyi^i{%wre|BYo`R|MorV%vnXwM3GdY|&?np!UB2pb^dl zPi>UX=`b}pIS9-XMTt5KunD75xXm;NfTe6|M?g-A^#~96ExK_79E+kG56w~4>^;BK zVFr}a*_A2G11p-dv-j@U#kNw(yLZ&M#1RcPZrm#$E!6JwmYnPYdY+;L7}TprDy|%x zb=Gu0Yu3M#7*A(0{tm)G<#Eb&EID0cjO(>%-Kpz)-n@Hiw$Y4Bf1g#UID)TtLhfx` z;X*eY^x@)q`02?GRm&{@hSQk;;_d9^p9kZ&);qI2V?6pfRI}(uwl7`kQfq`)qz})@ zgOZ*x?8r5owxEQ@Opig2zcCCVvLp9$G2az-LoEbu!Mop#`siME?D_L(w20pSeyRKE zYBfmV$(D5V|*j-oJ(fAuKNRe%EV z(X9`^4xt;Wd#kc|K}Z4^&RU@GLXRmh>F*y|l( zGoK_@BAH4_oVfV6w7}9$y-*)Cb2!g}Ce15(zgQ|}9OP}s60ohRR-U?gQY3mP8a(1f zr!?06eq_*t?0Q)K;@T~=spJaUee|L*2}zqs)f32WvWzWl-K_-3;kU=0wh_*_S@A{m z+QXEbDv-Sd5~@0-h3_d@2Q6b60X(ZKxSC1j2c{|Kps*4U8q4z7!7F)3S)t=HyYIYw zEOge1B+TopaD-n&;k;D*UiGX*3a5MGFoCg+sBppUo<^dt7L1H1rQG=I%3(jM|Lrwl zC6%biTpS%8kc5Cu$7KxSUec8MsZ*1@^68Jkq!6`1r|y;jy=ZfH6M)uA$-M=RPVaK~34`psvBeg|o8=W1gDw zxt6L*o$Y4W>MeJEp+SNZY$EMXzmHh-F9z+~J6_OspOd-J>Xzc~5de^@*U+cG)`mVZ zR7#calT;as9kG(W_$Z@vYX0Z%d#{<)Ko7Zu@z6JO_It$&EdUaYc2b`hB&0&^^U*{E zAGZzSkfW#81UtmQ3USL=^GoY29c4>vYi*;On4MVUOhZO!_QLU1aj~ycF?BFwNw)(L zuK!Q=Ne2Fz;GJ(b#EC90Qbk4vZr>QkhXTcWvu8wi_KXKwqxz8B?Blz?-L(244@@un zWHOcq=fOc{{t>T;xU}IxrYh!~GCFX!sk^(88r8K1{^9ORi ztAF;sXu#*{Q-D9h)>jA@zO0pns+y2bw-uRFgnAt+dVDKh*)}6X_q1_(D7-pCxV;JX z?pK`CrLz5KtkuW!PMOGAdy1Q8e+qIZfBWkn?r8GXK_4$QgDgbY(AYSLgWwRnw6*_eX9>%==#hChh7!4J!g@Sh3Ht#<%ySTN|+5UOcpL@Gj zmOB_!b&i{Vy;(I`_9(S(FzWlj*k%_!J~0vbc{CScuZ8@eI?vgDFkQk)_ZT(n=;`af z!$J0DrnBgF)wU*ph$fJUH1&CJR0Loa^R=fXe%auBTCdC|(0{ZG*9Spl9|2gWz&IB} z>kEhB`a<$8vXb;=NdtMfnFV~7DRJ7{M;0mk>`nnho~e*x|{rLqAg*pYgr*<5II8;k^RPJ^9g#R`4(E; zcPMp$sSWkbirzRK34lL4k>n_>SR(BU{!lfCsC=x}Mojt|!EdEG73>RGWh3Nim?Ihg zU#=l`SH)C)29+@glT+#+QLs-R_ZY)bC_Sk7zY;mQ;VB|5gwZyMx#RE9VVNani5Pi-&|FF=@n_Fwzad-Ypzjd zNk#~2-$V>J`2AiO0Xf7XT)h#l6Ox^^7ZE@QXAoUI|8Q9(P;!p?nm|fnx3!_UPSSVI zdljAp0x~yWF}_&p*F^jCmH3SV zyShXa!^DfkWdY14%bDZmpg`SdH@?$cURA@-=!bA7@iPc<-{D%sRQmb_7&~acmdH?G zU64C~gNqrE!+G}^sNpjNZvnw!Tw`msJ`Qu5KUP@5_<@#;GI3J#4n97jccKD+2M zM}2=eIe8Wj3R|&FCc5|2kc=h3X$`Ucl}7+QKrO{@%Afr@J^?M!-r4B_zsdvA15D z4t6$}%pHte5mqOLiM50H0V!BW&>C=LT)Uv?7G-{4z|sAB+FP^GkL~)Ph~*k7w*5&* zkM#CdoFp$FLGdbSBlv8MkmH#|P$m?x(GeUV#plZL=-U09XbgBLOWNOsaVsn0J|4QZ zdJ~%Qno7PWisG0{)t)H3^~rYf_5IP@Y^bRws;=^W4@2_I#?B6lgRtL0k`g(!lwG41 zSs1tF(+9L;G=Ck|NkUY>O$}5?W7hiVzkHV+qn+iUuT``E*|*vV>!CqEW2cHgiy#y8E{(S9WMXiDT(3`;V@+2Y~#q~C^R{m0+`x_rHf|+ zspBT$iLbdzBH6newH!0ET>zjxnWpQlf?i=15OXVS8=8-vKAem)m>^eJ?PxVmEi`SG zFNz()^w-(otHlN`EvVL9w89$7ZpahaQWOTr3w4qd`lOZ$PNuo;@Fg7+pLfD+fEwV% zdI~V40r+(0j_+sgChSbZM~_0QL%d7fv>=Pj3F^&k9fuXa8Lta(w;zFb(75jO} zeOW(T+G#`>$da}&Gtc0F#e?~ZGdsWdw-aoVx1X^EcR<~85xn?NsUu8byRrTw4>W%J z@X*%(niTg6e|v3kD~~q3;MhI=Q!BK#zmiij@4pryur3lsI$exBV^mp?@q zv*mlN@SXr=%~Fi(eZ637S!qn)nM*D%IVsmu2BT!)LoO{i5CzbiF{h4rt$hZV8_&nt z+B}}Hk-+x1Y933oO74bKue$Cw8;Dth^^|6+Zz>M@iLcbnk~nm^gE-GJ$0?lr@jWa; zMTCf=9u5nL!rq)U*Bt25UzI|yWPz<$$5%EgCandqaJ8($$Lx)uaG zC1LX=u+Q`XbFte`g%sZyYix+r7)DFHUH5Q|UWKY|7-J`+#@^O!hwJ*Vnp#HY}l6k~`2R z*`#@;v$4k8S{+Kw_WBBgzNZhiKK8iInzl7)tkFgzV5Gp2#XRbi*541Ykm!qv(AxsI zAA4u^iD!1z+rXPviRXAeVe?0R*H|o8b+Pbk_2V(Xs8MlWx{N_Ks)YH`Yb?@Pv+XUeZSWb;tu8gZ1$5O!!eVC081QUXJ`uJ3Y^tOe` zhIB4{f)&(q#J$16UygwjRzgbpy?p|x3In1R)c^Kuw6*;8id;eYuvkt%_W@Z}O>J$2 z+`&cb*Qt&z+7EPr!5a_}e~9_%}dQ2i7<3hiwiS8yVH6=*oR)3L%*0-F;@9?@eP9OOB`1Ly%gwe^HwNNnB+Np`tS*y6h%>B(2M8F(S4+^Kvl` zLYa#w$9D)L`;*tb6S7I_31i0Dp7$o?1_#S1s#0a7Wn>&^EpYb<4uDD1VW9XoTs)Ya zqnVu=FAX_=fik$kPOw!hPU*Xqxr?l~L7meVz1?%U;p(!bp@yhlO2x0cLlRgbZobZvuACm&G z^Q8V&!x(cD1uJNLz*iFRr94z+`}ag~@RAG3vpQ-oO4h%t=1;p;moEX4y8x?*C|KN@ z4*VT2QLag%6}i&z-Dm9qZOGb2ll<}>F|`wly6%N*`GLmp;*5s9%Y)Y4zVRvTLt3Ls+WN+ zHvChYYvUJkPrZ0V&WHPNxqLST2cA4|amlJd-#=e#O^)tN>Q zWsHJ-jfCBiUqs|DiXLn|;dIT~XL1BQ+J65G3`Vz&C%8C)U6?UPlplj31ohbe6A!u_ zY3zL-%nN@_;^eayldAdi@c*<@)WH|o~vYbYFTl0=opnItl8Fz13T}#^s$&mo3XNlPKJxB5toyJRRoyeQPS_B zq2xNE>P3g@*`|!#UL{g^8}hSsX|lJsC*}j*O5#CgETVy%84#S#RlAMWPZRfS-gdZ2&@mNThk zi=rIL+~iM4GhdF?qt0d}KdO%$QwwqE$OCnrt#qSix=HFU(T4Y0{?uv+9l9#00@+}| zIx>LIH_J`t47%QgBGKcUbdgxyf1HBA^Xn%oiJh1;FUdEm@sN^9B;fj+KpuNZ_PF(Z z{vCBs+qx4N91aZ)4Yr2%m%x#}$HbS*%i|A271C8EYXEBr+)AT%_oPGR{VmgSsyy5l6=BfrlK-LhH5{;tQnuYZgV68_am#3pEa6og}V5SS{5tq`UT<9 zGc|wt+ZM(wwI%ub_GFh&PHthd@8(+{Z}%(x8a%Rs=4WxwCS3lhP?$G~%=%kaRwADlZKBfW z^z<9k95lL{6D?oLM^z-VNe6A5x3BYxpGl68i%Sp`v8{~#iOEYDH~@7_!go zM4S)q+rfH+K{PZHaW9G*{aXAzJ%M?z`|vP-)&1uafp;~ma9(HxZ+z?Wr%o2O^r|;# zuO@qxeoG%@%uh9gWrvMLI2FniAMeVh@KQs4VD25q`@yK{AnPBFr`$S(`Dfnki6O^H zu8DtN{cg@>zO+|b>wYqbx*aR&ajo_MD3_8(g}GR*epD9|i98vn6 z^}{n}D~G+l)6*_s#4f(qe7v&%w-BI$<=@G>%C`>{k||icJ2Rxi^^E(g=)1E#Qa$t% zT7gjYUV>Q@B*V}_7fX}})C~T9qM*$9XMO|TKi**wOSwh;^f1A632%VSw=w3a3I1bK zGl3j3ydeCZuqk!w&Qncl&r60_g%g&axkZ)x%Stld^2d6RhgX8rp_i9vhAX!xNPG!4 zPA|n=5yuqgUPt|KxiOVF2Z-T_tnzuVU+pZ2+2OcvZB4%P?dvDM4yb=reu7oTz2Ny~ zT3%M!1UM)b2JcP6;vy8Z)V4;c3iW2^nZToU&CSi_|bt0Pd!)A0E zf}NBBX$geNj4ET0gG=;|-h1obp#Ij~ZcjnKhFbD~(+*Cx&Hv?J9CVgNFr{G-ui@cT zcvvxCR(=oA>*AERn>CAr@Rk$)TT|qU-CQ?(^`q#XsOLOui_1ho-_v6M33LUpBBo|3 zmKSS1&FjM#6MLY$0Z5JBT^y^V)YQz})WU)@_EIX8IU&M(|0f4e?|P>9+Tpg3|MgD{ z`qLJUxmRwp(~(`CvMTID&h$go=;#>Ly#?RE&QGzqNck1Zuyt;Y^7&mBR#x?$wYB^y z0r2H7Q83M?!J62tTc)aiBPVj|#y20y6f(=j- z(MdZ+ZRuNoq{t z<+a{jHFl{1bzGYPV!B)6mq2K9@8?f764_J>|5ou>`(N>uT*6dcmE2<3-t!7BYA{Jj zQjRq2`8DB_*i{O+;> zF%afCaFNm$sXyb14vLSXy);P$Bw`54&B+O_0qk_(y;MF}KoV1I1?~`P!RfVphADrK zGu1Dbw2GyY@Nfp~`*2nt@3FzbD6b~@e_UA#W-G1Pe~<3k<(eTL5h^BI({)K@*VPt% zxn*2Wa&0RYmoveV3jY02*-8szVFFuEeH$81{xmukuX@~oadKOmNy+@e z{5*e3KO&EeV_-@S`ngp|)>iB*0ALx&Q0{EsCT)dE0Z+#R$d^=Yg1jl%eE1{S>95hY z)~bOLZ|%a+o|t1jG?ns1%}&q>Dhr-kHovQHDEz&BR|*D-uu-QZlj=j~v14=*n_XJ) za@tNO;`Cf>_xOBk3uju+{dHj5Ehbtu66DbeC z%9wdvhgecKt}sV`Vf+H&Vo_NAj95q_>dsoFi_1n{HDq9 zDdj&GSnSG*t#6at&Wz?U@%!Jxf8FAI%x7v!$-tH2Y(Run_<%JD-+fnTV*{vK0MxHW zzH_mWnX~M!xp4|TgB4e66dg85rouypN;Gvr%-9+AZBWpvTnlJ3%a;Sa9ClEDNIPR* zrnSF_|Dy?HJ*F;k1tupK7qKv5IqKyS-&iPM&98Qx3wM3yc~eJsqg^E952wSTGB0Bs z{LhUp9qaW0ZZ;`EIByRmcQ8mzKQKE_b-#Q^1s`n$-^m>JcVBZ^MixjE=5_dhZ36BK zK2LGwj(ve1A3eO4^6WCQzx(u*P`Svkq+Y{G`k(r5Ryu@!{JMn$m9G*AOi=jGte|E1 zKw6VoU?$TD^3Z=vEL#PiB%=JUj{5y~xWF03 z6J+o3Pj0&Q@>9%7 zg#}rBo$T9vx^=2c2bF2?#Vbn#C!r2E;fhuXCS5BP0*+y_ji`v-We0+*GRIVMBR%nw zZ5A1Zue3(~|49B>)VLQX^16NPO)swR(-Fo=aPer;U}JOcmpdu!OTKu_&rgnO$6$z_ zAD#yCfW&!X{{wA`i2cOlHEz{pk;QMSn7exm!pgxBAzRX7%3^Hl)HO|&O`6;c zXDZj*+utUT3EZpaS@ADCBVtnsOlr5LqDPVxK@n2lux0wZ2u0I`5!#^S{6R`Q9m_Po z#hP=4hbfD0=mt!4B4$YeOw*fMw=kD?GDnP&w=e-j8kgTN1|eEX6T8JKH~U^FwEL=E z?css+aHfUYh)v;_BAULM~q?xZyGDV;At>82NK?e3&sZl1t@Qd=pt1e zutn_jJr$1b$7G~1hRE{O*MK)*=&%V$rJFO{g?na=Yb!4QL}umTycdKTH{)B zR!U5)#_la(%K*R=6_^l)E_7keL~yKnU5!DzisQB3m{c^X=whJvbGA-Q!`mzGIGwy7>t% Lry~0mY8>=G;t zEf$sp{y}=LCM^ys=_lU+K0L5^t@s)QDv!dtHhKtr#&D2%`yK?sZAJV+>a;H~1%b}r z%f5N7;jX`ZgVA6i>A`S2mzXR0L`Tal`}M=57hyl}A4{ef(kh@Pk$&Nf>3Z-bc-fv{ zMD+{T>pkQL zbM((<+TPj?6Pt^*piBRm*TA>@0k^jqqWOEExC8|K{$1JNBO=7JgFr0YLD2g*AS~8P*&JfuGdnpulX_wyZ(=z+ zl)t~w@4oihv4BF^`7Zi^->?RJy%Zttqh52KtMXb-RJSeJrFG79#AmTd28VfM`mPgD zuxy8Bo6yFuDSh83H+SEap^-^$jqzn8A5(U@ThBzgSCZ`b*2+Xhuehog z->T8QjV7c{H(^iLHMI9+@73PL=-S=sHoM>PUCqvp?{;#g*Ka@J3%?uq(TwY3J-^rO z0rtK-PNr2?R`L3-7frnfWKdG#=6SIayKrMTv98a=;e3dvV=oQ+`Mj;Yur=dLYK0x8 z^7Wo*i<7U6p!rOcrJ2hLE z=6n1>VIZ!58Fi{29kaDW!&@tuE)*_ znP>xfrT2b~{Dn)hy{>1#C$V_>xpn;lj}2A(LjxbrQ5xQ2=ew3MfpZ1tE)j6Ewa3It z^8O-&?J6;B_cq{1H8(TfX7pNS<)QIpQlrU6&e^5(!Sm5GMc!iaJ+#E-S(D;2WA>>i znW?5NUSIbMpJe$_L;mIgS$n6S%cnoB?5@(fIV~c$;g zd!H>Gy&=rW9C%%q!^*?Yy)@De&v#oSP8S42l33<2rY&q~hk+>@64apbLu=06ACB_l zn-t#sE-%`2h&+m7aF~N4>TPt4Vxr}Jt(o7ry|X)3rkXV4;If^?b~S2W>TKXkw?lJP ztjCC@I#)FNlf9~OVcV@{olOf;MeO!QaH44|DpMJ$)}|~?)YKphl+<~#59T9CtbH}{ z9I+`{vb4klEuA8>sy6GP*_BvIf)1oa zK~P1ca;O z1i?6Fw>7rK>H`DpBKhS=Ek4Ww8D6>-N_Hdqc_ObgPD7(%@aA<;+ zhTpP6)ed{1?yb3~hr02~YdzQ2$%G`h+_8+Hu*F56Z!c8zl0E{@&v1ppU*r5R_s9kl z7;)^1rZ)jtKcl?srt=bjf4+VL%oa|KY z#!jPm5jGr%X0Yz#t6=um?PA-U8d&UwKo5sinuK4_&E~~BG;y%My)ef9N%c{?azzUO{|l&0=C^)%Hxz1->GOjb#s4e+ z#d4f7pQnBG{V1Z}E#-ZCLbNEE^Y>^hoc|I=_GiWYyIZ{ww_mjej%Tapum-={83?To ze<<30Ju41Gm$(qbPz*~fyPIwokET12C%h*P7>$fl-xKT_|5WA*fx6=}-ru9;K0rOJ zyA~Eo%>@{b$2H#4*oU9wZ9|L22q*2wjxqQk8$);=YlhG$ej3{@%4# z_0QV3Xjxx#ee5hk%Q3voJI&sI2sQusWlrg`ePDBtOphC0 zjr-P&5)*?q(H=CIW*~e@wccD<4_7#7Lym`?@_u~kj^BIPM_e-<*0&YqP)p?gODWje zYS_q#3Qv)Wsa3q8`VmO(O+aRhF5nCNA3i@IV_=kh%{oFRpQfN(zVZF!rqm;A!F3wu+S;AxQu`nTX=sTaQ0Ir1luh(7GPx zX+e+vO5DYf`SU+MD{o|hnJ{sRC3u}$ zUMQ4~mn^+HD5GEcc_`Zivkka5Ypn@Si*Sj@phbl8@-}10ZRYKNeAE%wAFLCc|RxsXHzrhRW+t9G#|~TV2#x zgwGHbM__zaVF1^C;C*Swfh^X|M-cvyB$PL=MzFdPZ8YL%F4M1HVwdG4tR|Ye6E@mAcz&^lKKamq2kvQSFX^p4*R7Rgmsub7)fc=9$ z#?qA*H;>4cMl{9IXCtriqu5Sl6DNh_PwtLk_}ZP-VMP)5L*XrWpw$pKO1kcbYq=BA zZ@ExfaJimYEm*CVu{)vA+{m2r+<~@ME%&<|W-Ai`^PVog(SoY9Pe$yNN=hP%Sb(KV z6ZKHc0}KL&95n0=3oFNdhNVD7(Kwb;@Wt|v3?D!C2y907ZbHVohVOto`ZbGgl#RPN zxr~%$-%z;9m&5fW8+D;aaQjvMSS@+__4e|5M4Y)s6%9&H8A`NCOy+5M+vLPjPQ)~o zFmJz%FAMp`LF60ujCgUzv!_7R{s2Lw+`2dCumO>)cVG}m{rzD#L#D&=tewf?C%&Do zslCaSXzAH&aOqVsbI*6jk>A_z33S>*0?H;en1NQRQcbrZwsP{ltx$>kw3*{3zwUF+`>&%mc@n5J>%1 zJ|eE;Up6>$m`2U=1~^Iizn)YR*WW6hq(gFvJ-86{ znCQ?=KFA)QyolUz^AS<7^<58capi^S)}EN@GLkDN4Yvj0_m6_-vap?p>u|7$$OUYU)<4>8jZgXS%G4$U|(gSvzXpT zP(y9)U@=7(LM}bOBkRlBJ&C>LK06mmB3vr3D5cB*e7JbWYi*L`NKIT07vO}|!lMK^ zs_`(IBy~u4mB$0(eP>1JP1!ICZ*AE=ymb3$YR`+_>~{Oro#(`4YE790>wv5ogl}1v zGTjYzegEJgA?Uq7;NVNvl}|`5(w2F&r^*)6L`n!}l!hPm`<3Yte_44hlaJ-cf~j#; zqY}6g420^Ml|huI0Vo9!;T{noq8r0~bgR|n+$W*iJSk6|hKX6A7-fq=K9)HoT2m2Q zbIg?Ov-@3Ch@RG@)*=Rh0Y`-8qo6X5H^enV%{z)kH>>$D1%~;gRa&Z1koVhv*o|jP*Qtl zypj&7SXEK7)8Q;c)#885IQsQRAtP)rr%0gf&OAG=XhMI5$90;!5ERA*asT0QgC7sS zegot}5cKP_DfyBTD6aIDLqX`Ug`t1k;6jrCx%C%X^y6cEQm0>Kwo`Pm#8P7|+n-fx zl}enUstH|u`?6pcc~KMQ%*N}SZ{C|vH9>UAm#p>pG%W8}8kEsF2(Q-+VwwBedyz>C zSD3Qn7!wR^m=yJ1UJU3ViMGuJtv=9XZS7h7bvJj`focv+VJr z$6{nFZ9#`AYW?nyP;7Th>NTQcAG1vwDk z@xgbqvBLqLA(_&(_xO~8p6Jd_xibqdr7YA4lDrz!XIPhfQ&eC1m!I|b-^}2kkw|V;ILVr12

    !~yOzW^wBowC71Xw$YF6%A1ii0f$C=6C;{Ffe@|yNH0<>>m zypJW&(Jx)7s^z5XqzmoESc`1U?}KQDSm&!UmX2euOYBCs$s5g^YD9iyc#edJCQ5+3 z@fBEyXeGbPf?JK@fSqH1z(%=DAB}ZfPLF?BJ&_9n%q!ryQsZR*yx}sbz_9iiM~f+a z&_Hln9ORr9C#d>Q@a#zrRlUngA23abg23~L!g6=c?2umOR#6xx$aLwO`BA?D!kB%z>s$=h@@9EmRePFf|~-`MyCM508$bn5#$-tQM9Ge(cHg zsr?fMQWp3Lj+4_=W9@F<%&hNiobvgR3-65~7+kry>!tUx{HXuT(Of3IQ{IHr4*S$` z;E~Y+GRE9ZfjplhzgWQeDUj)D)3ya=lvCErI2b8;lJlRoxKzY>|x7O@5Q zzT9lAp(O5l9cNU(@7@=PN-?&SPPht7cw92vt@%I`VPa#UniiBEEn`ulm)jKst`9k+ z$@dQW!~_RwX!TgWg!?2(jGP(@{tKeu|MWYF94lnOdiu@s#2CIsLN=)5C-V)gGdn48ee*Znj7s;V zcK-MY0458gG%RVklbz6~@#IAM2Qwkp*O}zIJg&#!(wig+N|*4db&bCeW?^xd#vm-u zh$f<_vMl-oX4nfN4i;_&I_l47CIA@wk1N$otE7l1-!4stG;P5`t~;x2rcZ~5M<}mu z3~n}hGcPAnXI#hEfo$O&3IZ4rx>q|)*L)a!h-+k&K`QEs2oy>baQNGlz9pxloqFB( zt-E*-?a8xjx9#dxCGaGkfE7B{6aZT}l+BtxI_o+INI>{hfl%`p2MbTMpki!H5?r#o zgzYRSE5Ud7(^cQEOIzJbaSsf z)e#?zpMS`@x3ug182?5F6=wjtdzP8=pWX0AaD1?!yv@=;1W${n*c- z|7KICl3l5VSn?MNFpkx($(-IJ`t#9H~vyv)DtBN;i%U6_UA zp=(@#gn+YeHG`oNl&kA-X;NVE$bV6@nMa$(iZ;wJM3B+4RmI5_*>SvXG#F$o*$jUU6f=(2kNwV5oG#*jTUFSwRTEX$>#Qc;f+LXPP>-ga&AK;W^I{_h;R)67M14g;0)Cgq4ia0+EF*J>e5R>v zmFCNqPI#&0F`NmAZA6M@ZMjR_7{iIoPKtCTTZs=sUw*Mv*#;k$RuDhQyESMhH7CO@_bofmW(xl z?7(b(H~mc^FvX8&86J>;SP%FC4xo-!i@7_Y|AT(qMpeqU{Dd^e*hct$cEMXtA?smg zTY9OZ9M}gU~@$4oiY65 zF;464?#WP>fGo{Tyn|{_F9SO{4vY_@dzt7Eu#p?PYa8_yuoQ^)^qWTg7^q;Se0(x|DrOtflFhtKQu`T5nF=*6A>HA&AqkE_m_ zHi>*2r)K2vtW(Eq)C7aCU{V7Qs1X?(O?gXk-x*OJxIO-^5lVpR>5)3bZ1%|R@o?iX zgT#I#bY)R6XrtQ&W&MNx*CS=N06Btp4hX^_ZQAv*^Qt;BgQBSEM&ozQewC#4i=cuZ zt+G$^1@^8{KnloE2)UWZ#S`-6v0w`iTIBe*-JcqmO4515Mrdol=swwYES%oP1Zcvp zHhg3TFt;?h;RJ79C8Q?#11v8u;Bj^7_Sgl=sB`eNTHcT)J^7(WXwf+>S^i`JGALO9 zv%F!M=?Azr(l8E67dcTs4`hZKGpzB49@4>1dnHll-xvU3M2%Lumx_uJ*ZTS)8p+d; z7gAlErV8*VNwYROyupunal8S?UC|PP?6m?=EN0~@)rTNZ^s^gR0|s7H>7X;fMb8@U zv5r>h_m-KgsBn^ndj~!Wd943J?QK^BQ{$iYMreXDPR_KAp?&OxKc}nL*Q&GB?;{Zm z5{rRcLuW*kzJuv@u&VG9-I@Q4LIu{BpmudZY zbDRgBrDx&p&mS*xQg7>#UGWv3ou?uFZSy!)N}(t2b*BCjzSZT6Cm;Je{sZFmi&e*Q z2OUwp8;6!ry#|QwH)A4fqlT15Mqym7@Qc?FKDx{LtEh{?mE)Hzq+qL~x279LM&;|C z8XAzUg`iF>p`iGeU&mI|v1K}9&rJuT#J6dv)&2fY^!A9zQ@bD2hz1U4d<{Y0ctn(l zXJk}&n}Pj5al6n*7eM$pk^>ggjh%zVfM*UUbC7#PBrXsHU6Ft!mozf~0WS!u9s+>L z{TkD(xZtv~$eyxCnQycoV3q?r>VZci;G}b11bzPmS7U%c9Q-vpkOvgw?YlU6@z_?= zje)`S(3RF1xbuxLsetzrKJ;Uec7~NWuaqwp__H`V0EX*-H|2_95u_>^+@J$NAi0_V zRXTz_qC=Gg3&UYe(=azI=DYSFzqb*EP_CXOE*IxvT{f^gr{h1Ff&Lq9%pm9>Dja@D z!=f-g7neOH{aXCzt+BYcMJtvU?K|`(G*}o85mARZK`IGn;Tt(f*HW}Yfh@QjfYgl5 z)Qz`H3Gd=NABw>kfVpx?AbJoC%#{hHQFd=1@$DwV=1KS94vhLt;8Le+_)oGfWPL}^ zzJp#Wf=QK(=#css831yOJAkaZBPa)9>1@1Dgfkt_a9gv0$ZKR^Or!4Uq2C?dF(YXC z60w`Yet&OdGu=>jVPRQT>?<&C4T4e%7xBa~xI$h$50X%B?qOJK}CgE9IfC#s>e_bey)PXQgkeLiPP`iW%tq(*0= zJnuj`)hp0dRsn-GTc<_`odfgj(rIH#y9&&rYAa zj|&&^RUqh^4vBpEItD4@;a^>Y$`W!FZP}}GqHGBTNV`OymRf8{y;Jg6NDQ4`@dwX_ zcXNZJv`JK4Gzrwj<=2U3b@(vU{UT6Dw&Jo|rL#8{`S8+l*tfesz36H>QM@p~Qm2 z@AJeBJ0bg8xsidRyn*XU^U$SV$-cTwswhFwjKm7eGp>E3Pi)@t_(ZM)xMRWWM!8i% zc74xT(k^Kx%>Dc+zPyLB7d&$2p?^yBTPc`Z7|6STGt1Y0#AIg%|DRVAhd@Y)78?=S z#b7Svoy3Z6yT>J?Z3K{6l7J9J7k~2~@9wy9S8dt&C}w0A2|gX?yg~Do(tNhtJJYC` zo~b+5a{jr2?G}U6{YTQqr==*^GLNgN29hPPAwVGdz{Olhm#GF$X#N5nxZ30!^JIU4 zTz35y_eo&}$q)s2gBCjNFB{qxt$&!(KFR~~H=6i^Uyl~d!KRRO>!Lj4 zqs!+2*`OXx-1ZC@h%(wYg%W{qUI47(zz%;O57JxwN9ThFC(Tb{4QGXB^H^Axqddg3SB1(%yjra( z3$8N)w!^fq-Fs!OPyB^!0wtKIfANZpX@JT8H>Kfl~R`lFqi3E74r1}dB+0%Rdn&iPZ8J71W=XO5_K={YoMcZT(BZ+fMp zm6Cd28*PUqP}WTDDb15PCO9UkYGN3uyyp8}*dXyjlfY-gTwkU`Gr>{Yw)6=X=`5`p zftFQ*feJv>m@xhvj;3R2G%JYW%+_IT6^Dh97J0zraw@a8RC_W5tcK9^z5Gw##!mK_ zmp4hV0|@}9L{%RXnT*k*K6*N{AWM8pDHn2@0R(cPc;FFyJqs71^|fD!a5-;;s(eCV zK5CZZ$}~-5$cu(~IqRKu=7>Rfgq@UVt77WV1Z6%K3qbcHfx_}om~Ol2e#Gmm^?tt1 z=?r3gv0M~!$&HE250I?>Z(#-OMCYWMhOp$YxT#tEBr=>!2^y;Wp1ybJSQcBb?#zdU zI!;c6tnMgkPJ}8<+BE>{y3=K;hr`G3J?|5u^JpBE@l-N-?V}rx zbpM36t-dXC3hv-;pvc`$>et+1h~a9&>8gGJWjlWAd=m3=K{baQOesLNAYEAe_WcWs zAGY;DFX08xR)Fg9$c3A`Z%^s78Q@O((!_BdHB63$~@ zme;#V*^&&YR+Ke@7f-@=cqRFeRwLhD!~ibe0-#)s$P);aGt!BG0%1XtlEx=hxKxGZtQ}wIn0HG z=(m)c2Bk>#QDI9SRg&B&$S6C1rP#U^{s(~8e&|@lkAXPYcMB4Hv&M8_XQV#k`}$$2 z&s#rcLjf{@?Sn558?7`#V_V@37j90#a}nr4p&b?DSewV@`h=sgopixZ0aD=DyJN-+ zyARXIhztN?vpRr0WH6bMC5_1ylhZ_u|d;FCZ zv0!3O92)=NI300jH5Mnqf7S}@FTl%zvNAs12nkRZzXSHqn_!QBRgZgluTZuhr5DLI zR7Ybwm<08s&g#6_pM{sq>U1$>w&-Uc(2i?vG*T}MvqgVU(q7R)auKV!$BbD(eg@Q> zk4dvyJEi-v8BTBZ%JG61PIbvnt9oAvfBNnGE8eLwX~H)f4*;urc1`c54?8um_-j zO5*O5m@@|+RAC5YV{oayBdJTk8e|lx+AfESCEIabFCe-CE(ZYkvz3mQLd9|$4-*E7T3Uq}Dif5{|0?WOQeYoS+~`MCrT_60J}X@|2_%V@g^kw7inLvXkAD)tb}1mJqF zFw%d`k(dr^QhX_kR9~TAuy~c^KHxAjQN-nm6w&TZ!5H+2=+k^Mo?eC{87q+j59_$v zq-FW3ZibsKuw3X5vD2o17;7ksGaT`ves6EALdM8!+?E_KZNMp2;f%8r>th%19kZpUEA&Tlh4Kb#4*3+Jn%OfT&|v}y?BGD z4eUQtQ+}s)_)JZZ9{WrjrEVI&PifXr?SSs;|D;HfF>0kMZ;7Km$BOb2&>|p;9IxQw z0SNYq1(ECm+m?Zc85hfD@3GeZ&=h;DgG&FnlktoliI8;@!Z{9PigSyn^|%)=ET)4a)s2EtI&q6L8hWkVqX5q&Aa z(46MR&dP|zzeSe($+Aby^Po_<`ZJ~GW;Qe^rNH@3cChTVCF}NN!S#;(WZl4Km^M zJieVjMTkrszucMZaco0bv@=(nYzPz}8s?pPR!^jB(n7E3dF)C7H!t1)>ybzhLK|U- z?@-+CnABOYsms8*Af#fMAIEGP@T{Z9zvBI0a|7jBA9p?CH1g7GkG7@$D+5U`!+$Q( z7R1;f=<6AGRQF~b-h(Wr#VoxW*ng=If-UCx>#W2ex0q$|z) zvH?b$Y%2E#X>@a<)yO-^fk7)Qpl-!xX`2bz0 zx+E{ZGhWgEVcU@5XHFWRh_MV9hyG_>7bAFWcTgjc2Z0O)Fl#0FzyyyE%}Wm$7=_eg zA^oZOZ#)~inWEq}j3~$~)HlzDk?%D#UBo4x8w`YUi-&f((!o!b*HiUoS8Lq48kIr~ zEQ;caUL^Y-x({SR5@wGJnYt@9eDi{Usv&D?#-tt!3(L*nP(xR==gCtwph^b{KjW0F z>UIeX-KT7tT(0{WHgTEELpNl;hPA?4lxUKQ{G6O(X>8Ug&b)E<6YM=*H(`QehU&sm zXF)6hd**AY#I_ZMJ?P7n;}u2!_O_p?w2V2Kmy$Vkg0@>T&YkI2G$I4G{p@UP^DIf? zH9N~Oat8D5evpZ>P`hn$G>C<$%x8JJ!kO4^^}tipHHIfa(0UH4`Qypx%0YAOknM}h zQICd~=1~JY@Aw#2JP4MAnUBpqH4Ae@ndkzrjQFLDt+uD=RbeuBbVKA+8*1ndT_B}84^kGlyFHDwzdg$4_{UAM zKwZj2Y<5=@hfVvW%@Y8QV9^~kLIbns3~pxOPZqqeY^wb1jlzD`X#m*@%~C{_xBUWS zeS^E*YJie538=>FvL(6oPvPdZ6b&c@v><$7z|iVGlyTq#WI@T&#y_VJ zlTh5tvz-0m4N?Ff1-KoMKk`4W1O%}}M2O`D$sCX#D(PHaUoSsW()5F-nCulBYXj znz^G zK}gi`K{)6Ghdn^U1C;sCSD0Ai6m9|*Khpe|06Jyto1I%5%;nWu$twMlC6wHr>ivib zkzh6Mfar#4WyyYVSc;lLfI90DCsexv699#zK;$aP34wm6#sZs5X;#1q_evcl}D(-C$Ot#od&!JY)+BaMYnlqcO z(lbimo8z*i?O;<&J91!YVr$Xwl-V~XlRK86L5v^-l9tGVmg-+^D#ENm4W&Gsfg!=0 z4%|ayLV}{Rk}dh+%6b6|(Rn#QRLgE1I#!wav>K*82y@}0hOMFcHs^Igp?4FH&VU+$ z|CjI7S>>pmP3*I(syd&`YI)@ zBtyyuHdXr*yQXZv9mkO!7>-Q-xc+Qme?dxR$)}G}gZTxIgo^Cee(zXP4C9$y)h2jE z_{5>P`7UScR(3ig^o6vSMZa8}#sZJ>Xb{UP_SIb#Qp?R-p0w+cCCusah|GK(X^^M*GC4g zUp+|mDMqP|LK|y;1}~;fTL5vyW{wMAwcS7}Wu#fup9Pg)WMxxBGO0*c$vVBS4WFC~ zc=>+@Ml+Zoh0rXvU;|De8CX`7t95xi*IEjSqwHQiwr_pUm`|?}{=#3f^&cPs%yiix zz@ateijX2!4|w^1MQm$&JoaZ4B*0#$yf<)_kFrf4N3Tv@WlQSZXDboTJf{Z!$~M z8OMA8R`-2-`@Vn{T=^WvWQuL3(N3ZlQAh#{S50^=Wh0O^E{QtSJ@z@GLn`6hcW{TL z6fumcW8L`QhY^}Ma~2v$ut{k~47C@8an_M&qTaqpL7H~Fc8s5vD*ODR6#Q8ia=sW` zLkw#9MGmY6P&3+%uf_rdRjVIiKUvo@nJ)6&1F8V6OInSJO(k;N5G{K|VREeW%Pz~b z8V<>K<6Ihx{v8V>nm>9vNMWRU94Sb!n1~_t&Y(ca;4HxF%jy$*BMCEraj-hPp2{FN zMonjhWMa}yGp*d?D&irShdeKg$-Hc+F4t{T27JW%X|&+GCQmO(-};9kY!XGTNU7%n zPv4mG0Sa9Z2OX8q#?ORqO|%B{f9Vn2dZwTNqf`Ntcun!lRkE~|=mEvM#e?DQq3(p$ zMf@J2F^c|3v<0LoyzrqzmVQeDv>sm4Pb8#0@)G<@jS3o=jZWqogt+$`RLt2lnd0&A zVR+n>{*bTYZ?zgRmXI`ZKuTm87dOSzZP`F-&8=N+z4kj^L~kdg-O_`|f*a0hwCFZ{ z7Aamo(=V7wu$CL`>%?+lJ9?*qJO{*M&M)5#v}W zm7X`KdrK`i3-@py`}G{ns2lFc0YT=Su>PH( z52Zh@Bc?-eMVR#XY%yyd`w9C0gMkGT-ta z=I-w-!1eCwW3I*t>*ilvQoR%SuU6k&oWjhULu0a;^2bL$nN}onBEgs>{&g{0lgfn+ zF*eSiI5uFXnqot6iHYj$zbbbCl?PB3ei$m?>Q^lT+PiJhwzZ=;Q&cr&C&8|Oc^K=Z ze3AgPyG`YX+D7c8J#70aU@(P54l4QXxi!4Onj?`xmnRu%GGeWODbJjQ{FiF64i;SlNz!mZo$7B>1d?kp+b>78r(uAU?mqc?yUg>n1G{|^ z%*4U6y^obH>a_c|Gs8V>$`S{*@)P0nGGe7+GEu(fAqXx76&>r~8PFmJypplQVu)C4 zpYH*b(p!%iJ203YjC23XBL}1GtHevw>3@36^7{Yn;*ul(k#B}CC@TLm7XViPc=-iD z$?mLVS6}7M?`k3kYB|6kB8iz+|uN<0Y# zB4m+%E}OK~35bl}c@J!KDC%6@KHSsUmY_e0%#yT&op73mef?FDcr!JM!A`vl;SBcm z8{k`_tu7Z&{5E?zHfu`7e^&e#&9zvPMDmhKZJAb1vLyt5JRY)kdm~3_+Zz0SJ>M-f zJiFs^QDMB}=d2_6LthBR91t}HGHpsHf)GLgP-`|{bljAkIQzHbNoG8$-oFk-C0_88 zXuo_3GBU~x>jVE=Al(Kwnl_b5UUH9+4UR*#%DQq^=)o@0W_wXJz&N(oVg(Gr6(c%Q z-xUu*R;Y~~`=>bEu=sJOcN&hEdC?LZ-KJTAMwR6J_+*Zpah+MN-h!~7ma#uA6F5># z>z=X(a%y*clB2|t0u)SH0dqc=AwVhmSwly>?n4j@E#L%HMfO~BJj+*DD-g>kbsw!t zq+p6l38|LeE|-n5C|5q!#s`8y6S+@B^nJ==nFy9k2#BA5h>N(Mw*QKtIT*9T)z%(=^?U zwgo^76}!&+;E?QLE5SFbE1vy_gr-B2++$P7%v_OC8L zpp}>T-1jw9wY???sE_F{P^XMe_KCN8zXlXg{-|)}@N$%fyqzOz7TWON^iWEMyp408 zh_CG(dnOqP08oECuE5x^M{a}hZ*Rj4AXN|bAjhY#3IKfPugv9BTk&(CooG=- zWeq4=F1*THzL#xfSv>LC02Mo_$1-agLj`Jw35`PYzk_M+`9E{NYKNHIY1JUy1v?{w zh{V6f2W;)+dgzh={q_Z>X;APUZUFE8HZirtBUt|bzw3&~(*Ae)^#OSS$gAT*&WQR+ zfZ}D@As{coDz=?si}@vYzy%9~?qR_#AHXmof```E3}FB$&jv_Jq*)*{1#RyfmxiF`{t}2O5YF2-uK%>yw}!0~i3( zl663{RQzt8MZ#3ZtNW)!L3I7ZT0RD9E@I`r`>p9w!bj+GcUvCN< z0B!>qq`P(ekC(9l64l7@YAU6{nc^S&)Kkv#i?(Cofs)D2Pq`ZhJZk6Tf2x;#2wmh! zSpPb(cp>cz1B<&rs$K8py>I!yiVPgaO37Uw6894{^;05D3j{*MtYjz<%M4{ZAMCYN z#O-bc+bBlug()!Zbf#DoD;Dd@TfsI?eaI2uQ3L)Df}s;|l8F#|GtyLknw!vBNt&;i z+SDr;bN+02%U)kmbbQ-)yhLzrfG*p9u9D1xvTBVYty`?Q`Mxj-Sab}aTWN|0kUrh~ z|8%d>(gh7p29YYZCWIa8;Xx)nN_nr()prfFtIXGQewW<-F1q#YmAm+(={?{$Y<=Y&)!mSrlJ~fq{?TunJHOJpLq8Vb-GL;^YoT#m`o)Z^!n@#% z(|~*@h4c9_H+w+&^xXte68{P8BY#Q92+z3`=FL9oz_WIrlTRqVH!12#r-B|E0XDU! zJ0)`ye&aU$&6QVCtiq=enI5}Vms-g*1R8K2et$C>xmZL7oQ|7kLbMYJo|j9AXe2Zj^0Dgx16^9nj;4$J5#@C zbYR3WP0lmCbLW|CE8?e#%|4rX?ChOE%09mo*D|h4bth2u-=zHYIlx3Ve5@qDex?R= z&-i^oG9*FNo21Km7>%T)u6T8i1cCmZ7PM)_ScPFQzK8o##U_`*amX(2GHWhs(*oc#?@N25$1}W0 zI)m7KFRP6?7wVRj@`2d>Km8Q{8(01p^Lwrb*9UTH{nCcl=x)W^HvfrBD+eh1c4I}% zS1b`7f2mnEC4T#>?0dxWB}2!6`|;-&lxh@JWB?0)RGxDpxe>BF88`SoF6t;-m(J|&C5F#YxIdWgv^>UTjn4bRhr^<_DREx7!d*U=p1(|-m6 zS|35lbU#Utg58Op(O~!yH=hW~kKg|0^wMAFF~YpYy94XrV|S7u`ma zT@A}@S(@+7erv7k9hz_I%LHd)@B?*+ZBq90j^7~;x0%hC`(*Zdx31=7&GD5*#PP_M zm4|E|2eu(-8qD2MhmnQUaR)2e1$8*By<)4ls?d|Vnyq)0srKzjXni8&+pME! z*It3!u(6hL<~YYYGt2Bb{tdJ zg=5oIF>=v^+JTZLXs|+uhyBibeloXF8S>{-{T*de03&*Z&3)grd5#_j!`mH+}7@ zqv4V$UC;IKB+8=@`KZg8Tr|qc>D3?XtTXl3;%|}*GQDj9W!_9RQv8oAnc&Pa-i9Ko|aC<=3n#zqVT7Oq<{qVX0w<)XTCekk)B)RF;umk zt~^0B*N}14g^-t5cE-r#`2qGt^|nLY+9Z_(`TC~YBz=veZV*44S`XZn+7 zr7OQ0=M3tu>gCVu-fKFdW1&Tp5a9yo76Bwg{%_<3E;*5>8?H+QBmw&c&ajtN9az0J z2>71`HY!!;EojHlL2~c!DCFG?>YcBMlkBdxhw<2zLooo-Hj7Bw;7J0|(+&5qZjqHs zj`z~^94Y#aMk}Qm@DGL4q9DWZ+g7Lp)?G#evnKf0x8hkZVgMPHQcr8)Ljzq9Z* zs;>l^Ig|OaxUpU?i9`5|bnNvSFM9tU!rn8gskZAD4x-XQI!F_h-UX#f5TuI~MUY;k zDAIckN|WA;bfij0MS77=P^kh+Z-!n%Ahd+<3ith-_j$)SXMFjQ5kj)Fv-i%m)|zY1 zxlVt-+z=RG!veTQ6sK+kWz?3}LiY+!r0{(j^sD|fxzUFBC_xdwzyzb0Bt6r2itNP( zSSzL)%*9TA+kRoV{*X&Ay)1Y*iuxv^VmNSXuSJ&pi^O+hNj~ zm=u-R=~?c4#^MiC$6|^#?}5Th(TA2pucifVzo~NF*FH+4KkU8pMeV}S2a=VE{^Wb~ zf(;UbD;o4KlDBZOc!SW*24~A96=UtnqS&`Hq42HkXpj;8&fgP_NaWMm43m92ZyWx@ zOdc%EBQ}qxlF|YWpU-*tgDdzcGl9c}rgY@#idxL>N%@+=4-e3j@7Vce+he%^TCQy{<=!f^jJ@vHuR`yImkZZ~NI0oI5xdq-!b zAnZlK2H}2M2Qs07(JkAdaDd~qT|}a1S>DTddQj{tbxaRJ_tN)KfF$80?7-!t2v7tX z+Mw@{vmNjsY5-pBVdQFvW|=5jkkVDNP@nuitn;L(kl?t9u&X!oL<^RrjZJ?}X z5pB8h!9~pad$hO$L-ZH6A9hvZmfrUA`8E2MJh68ts~4D0J_vRJ7%FSzZMgP?=G6)UX5Rx6V=MMzOJr=A5e?YjTep@}H z@V_fN4JajD5w3^F0`90kbav6Ww0;tdD8+C~5$?trrSJ{cwMcj^f9qoH zQK|-<9-fA1&hc`|q=czSO1W)9V^9N)dN~uK(@$lgS@RPE+a~<~t z=sewyc6V`CD{t1>l1Tn9Bh;$T@D)}#8v#<#_&@j`rw-O z#Znv$;#UzR82U{qk@vBYtvaIyvi6m-T~{_Fd1F~^=@sJHbK21b+c6zrZjs;hyoMa1 z#3^NP)$;OhN-n`KjIKZg)LX^>tL|DMScK@u8b`J)YJtFrl83a6_~N^oU5_eEHhIHQ z*?Fgt;VP4c9)}w9kFp4W+Qvr_F@T1St@2Dv(c1P+-{3>nj8$94s8%24@F)ms=+yJ%$fGe;j?9fm_*f{X7E-^vFn81jNIj4W+VVmmAOhaaNhmb%`yo?!Vj znu!_DBOhd9)2oY>uQ?Jvj>};6vN|OnWF;Hvmq?UDfD-5WH!?cJvM@`*O1C9r%L~uU z_ke8(&Wysmmeas-vCCqIn}VQ+)iJkpg|YLW7bTCCZi!vusxyX2HafVw7o2?Oim~<_ zu3aNAY1k+Vf+X(usH#~MynmxKzx*|iIOJV|k#>5sNzet~q;P15ee+hs%=avQI&aq$ zs)=vWNglID4AL?qQO;3x*H1achXm#Fz_HZm)Vn{U-2UnKzsBS4mPwmsN`C#eYy?lGB7pfA!;H47e&6PB!9B%EzOSP|T#tiip9N?*ZBCky%F_t-o zAG6wp-<0;X1jPGBx2EqX*~MNGP_49Ws+M_8$G1luo}}(Vs~bf4aR0fNDO3)2W8!pI9OzK)qS>O!c>N5k0H(5^z z?k8(@11VAfNOG49^mIA%Q_5b~^yrv8XQH+fT1hYp>9>9TwEL+?ynL2X7SC&b4ilGO zMPQw!C?l;A)M0(rJqh~9Y9q6&785?a%89sFUAzO=R!-BW=cy_`@QUVWSf@=6xd-se zD_3yoJnl9hb#UkBKd}}3rEgpIQwAAW#s)(XDer874wVTgmDXJ#ak(YXcmIhHxK&P{Vpqw{kPjq8jP22C3f8{(iP zw`rT2we5eD&W7#!HgS#`t@7=-<>+1r@Z_tWB>Ny}TrAw9AZ`GRwu5!f@Ca?{6*V9r z;O{hGY3!im(BzsbpttS%S2_DEw5>9RiR1y^f)MsN7UndtB*AIav?DM$dERs1(-cea zx5{tB+|m1dbPl^vTrQRw)wDCS_J_$6Hm69?ygo>NJ{o)f8_-dJn;eA?DarZve(Z;w z!AaP0ZCeiJkL<+Emnk*phS`%(LYS>8Sm?;9UVy_{@?h%{qP1_oZPo4+v)0Qx_(N?U zJ1Bd&g@7JlPxV;N`ZDH_BSJXr4m((d88AJo8$53lH{PYM`i*?cB{0Wzb}A&(xIDiu z9*ZH)@m6E=>nxr-ZH&auBhI(lut#@|PG<+p{RfN5=VfsF263ybqK`KLg7EW$SlHV; z=cjt-$4Q>hjiRY%ZHv2A=YJyG;I)eJ^zk~^4x(!35b|5mFwl+?oQb`Yp*eFFH?zIa zA@7GdA!u1F&#B+R>T3FKqUR3QBRx(1tID(j4ranI8@dCrJHDo{VQN77u1VE_s-)NoR@}pZVt)VHV4;x3d?br@6E#y+D zT!Mzhn6rao@*}hz+gBfiZ@~WKKwHz+8&Jjl&};kLE5zblTPD~);pnx?g$14>$M0?Y zPAMr)+38<4az|Vf$$+n>tN)aCIt8HUSB3wkxKWX}IZj z8Io2bWa55$auC)KJ>GigXqbHz`~L-q(D*pGsQ{`vO*kC{F9_4ozD2@8`(cf98A3Nw;e{2KmFi{)CKohpzJZ((HCC zj(|d`MEmh9H2`$&t}~g5DX_VgF-Od6n@y)m!zI$itxu+PlmKlzu0#GmL>x~NUm_By z|L@kegSMOp??rJ?5cK6Sz6uOmjxgD4xu1OmuIT;7!Adb66?^?7JEoky20pYu-0~}? zDiMl^fbV+JLr+)`La>zYj8#WZ7H1Vs4HcH3l6vS4+7Y3KXE>E;V?x{+5=Zd+Fr zaHa1(5C=}A_kN@EhJ_gFcUpBpZG}yz%O@lK_+>6tm_NxX(_~Ntw0qR0aP7xcU$F}c zgCP5Y1ZnK0$b*~7x@)eYN_2!Iqh!={hsbzQ#Q8@48iJLgInh$y1vT2H0B!S`QK&lF z4r(ZntDCObkA_a_7Q@c}DrkD6MR_<2{+u6n@YO$;bg1tZkV4NPJbr#3u|#_)qYpL) z{E?907+kNX4V_oqxW&8E>Leh3ily*yR)jeF6n6i^%=@R8qf?j9ct=UJ@x}K7k1uc> z=|{alIkbD&U*8KDhwMx5#dyJETT6BoHQQoDVf*i0pgPF9IrMk>b1aFw)LtgroXaoS zrcJkF= z%d=GJgnq_PNSUF>%kg_$X{+pwi2JkjMbj8{k}oyeT<1PYN8-q;pQvGPw88 zpUGOhFxYPOET#xJ6iE%($a837sKYpMojgBY%Xj_s_rZ3)n?r;DajgdgLf!2=pR%vH za+?DZDfgBvoXt)DgZiI`^minl60=>24bb|NKMV|8YH$fNAg5PH3FOmDD5 zQLT^XIW}6m-?tqjR<2$-sm*EK)P${>>W!qdovjRJoet#qP6!#DMRc}3)-^pknXQ7M z%}udA*Bzd}^M5uQ<+hR4G%dZ+zI)h|l5dLaYx#R-@Ep_{Ash=4%jPsxf<-dKBb=|l zFNs~Z7jDY(l;wh>Sr{Ml9c@bRpTTQ=ck8~-cx~WMv>Yo+WgUKFTe^q9>@P_?Ne^Q4 z9sp?JOAi0@Ue>y;kFisS(_9XiT6)+)l-?QBuUQX-Ak2Ni0PIK0*S1DvhWL+T4bQo@ zA1xlJVGe&%eux}v^IIA^#t?$c=|ke#<)gfIZVNmPS>owOHoOZWSrIXv9c`G@lQ;kt zd!8=dwVLtx%(Az<5i99-{0yOJI)%+OV|RmEbq(D#?NeH&rFo#q6aUqeqCdL29~W&qt7@?E*-z5;+!p^Y0%{0Se+|0NPM zviwkJslNr#RLo^D%P&zZ$uj96nSLOl2_0axhcJKDZEY2+Qd4X8>u)5bl0}9nyZoKB z3Gkg+awHv9&&E{rLeH#URj-u#Z#UHCPC3*Hw!YH*Df6OkMYx<9>fMK&z+f=+tp302 z@^jv~uGO*nbfZ%o>sijH?L2-T%L-;jkhFf0ygj5fpD zZ2{fak*KB+ANJM%Lty~K*Mj?8Jmwn8w~~!fM+-&Y(gL+>NaG>P2e< z-+LE^*-bU|;;?E(R@~*ntb9I4+Z?v-5o{YWJ2Y4#DEzlYpq}Fk6SMVx(u;N2(Lw^* z<{{8?McYmENfw6%K0Y;ttq0Ee4d%7&w<+y1oguYBMAxNK{uVF!-}-^rXEi{Q%MW!kyF zNw#yW?K5zib4ZaY^Y^gHBk#|g%pu>Pl+$q;z52eoQ1b~{uaVOG4aeVGnzA0dk+Aa+ zA)ix{fJ2G^WXb46&T%}~oYw}Dpc6aoTIKz_(XmoYXc$}-&wfhYzwGws{46K?=zW!7 zTcOij*x7DY)lmmYwjX}o<+My2w)%ra$73)4mXqUdj3qT7_HH_#(KU4!?_k%Of7rg4 z?RzIhLISO~lH~V0N}tL(thYC!$~RH=xn`s0J_oY;01#obytZ)*o|aAGM5{ zU<+ek*IyH1e>4L&99`JoGD8o_q=4IMNkW&3ogxz|7a z`azxZ2TRXsVM`wO&^HS;YYPk?#G|3al&>xNe7dLTO&N;e=1>wR186mj*)|2Z(K$;9zQGDRlM z7t-&BjSK>qWQXm$c-89jEzAh0H0Tsy=6QANrAEQt>WxW)p-yi~x|Jf6 zr(8#MilQ4rGL(|55#vv*T-Dbs80;J(Mbqi{l=byv*npS)u>$&SN`J#%`hbzc+g6WX zb+EI(0|(1jtKWBO&)LBPPRtj)KvngqtBMSC$V=)=-Ou1B-wj77U($U=dn}VF0wmX@ z3jSQgx8b9=ZnA(#ozrLuRjupjRy6PU#`LCOGf#6~pT6schgi#VNg76Hhnvr~Lqfi+ z8E?B0b#$0G>%Y4=v1wPI8#^z`_hd{5!it7kP=O0EuX;(Fyhdy|N=R^4w1ZsEj~u>A zxNfLPh`*20zT2397?<=9%oNhdZ*b1-b7Kwt2LvPZE7P)ROs=^!&UY{W)?M4S#iR#1 z)_u{I#v{F|G*j9f4$K<~vX4JZ#zfpq;(3OA-w7QMZ#qQ03R zk%pLs^NwKxB3#1}tTl?6MX(1~wnTh|W|vj<6Yy|afG6fa zhxKGOY@jaqg6_#6pxK|l=SxT}a?&2O&5YL|=SxCzrTiQBtN zLIS%((R7DlbB1aA@uIcru8yO9tJWyd>D%Vv41D|rF8Piht`LzZzHamR>=9~C^l@wD z-?gh<2kO$JZz6P^g&3(R$fIFzBz9W{cCmxRb-BPq$uguX*ys9LqWZ;ixnjnlAwCB= z^qG?_B_4r87Fj36zFA=wwXnsDgTeplBsP<%aE$8ZwXYK#BiXv-OfmhO7|t5m)}OL6 zzp|4)XMH$q37LJwD_;ADH=iW&s);w@4vuFE0?9Z~jQ5i;Tz@`U?c`Q#Zr=YdlwJ+C z`Hz|-5NPWEfyt_edMHS$x;)J;b_)_kfD@VFZgl@+x&HM`wV>@RkD{r9=w$s0n@a;}d$_#b3H@OLNu(~IpuAQvio@VI*N-~IUS;T&Wa zy#QhFe-1x)Ck~x+Sz$y*yxG@Ef`{Sf;8bLF!1)5a=om>X22@hCiXn;?%Wk-BGQ#X4B&sLq|nR zA%80{RR!1?t{E(q?koq+@#mxg6#dN~ooR{eqIpNK4tbue?>u?yAIu(${KOAuDR+*L zlJU)=P?4%PJSu5B%Ky`~H88d{BkyxK#tC}qkX#mnjU?tLYggXa`G60&5pRTdg5^kX zx>>M9UG-l3mw+qY)66o<6fgYv#M zfdx-hehS#XQlmdD!8H5vMzYPv#3#!d_;i`*=~2z7-IuBsgPDI2PK!@|+A$w$Fbg;{ zTTpQP(4UlWmKEmmrtrxqRJe7@{1nw`I2*MhIuh ze>jSv$&_uSitax?k+CF59-*fryUz#Is#D#iZVh_B-nmsVs}Z{cgP`!T*C(lOVJ<`v zltzHABp}Hu=@!C|%&DR}lRET+l%k%D9sg$9TPPtS(IfNnPu0~!gvt;Hs+L9h^-w*& zSsdrNyXaKJ8P~zM1f2ZG=tLKHlg-K%EwpYS!{)Zpz8G(ToH{ zRFWvqnC{B7z;|h;dy@JWPNFZ|lC7WOMZJUFMF|l?wKK5r;3YQ>M_EWvJQu8LPzMtk z*v1JdTstKeW{{05N=^4>J~iuUHsq$LxGkvpAi9%_z^2|vPh-`AT_cTp<@nmG{=Ibt zx-X1nH={i+N9H1V9)tiN1XXc|<1u98sP$~1KylvM5wDRe&~yE-~PAQU!v zz76(w6-PKs_q*0#>p8|7TK2x#Mz~g>r!+@n|Mx1SFn-SJOi6(&wBE39aEwy#sp5>l z=Gp5ZEzqZvb49&g2Bv??5>VlSk47WM;%|%L&=t?Fl1qU_o2EBQSFW;yaM(5&4JGJ4 z6{E?2^+5`H)3UwU-(5EM9&)C`{QD9&Z@<-BYI@GaLjfT=fJR477$($f305>}jq1A0 zko&48CwU!{*1G0j{WSORPSJ7*uv!aWuG2lI>KD?}2edsc!fzj45?8%CBgLXh9duda z!Rznw#=g@er1!~?VsoHcqPaUmZzpBeINMei*S}PdlWtVPX3(OVeh8Z4_pv^Sn>zw8 zG-4xlS!0IzYT$NPN&39V#e96cqCe+Y_ek(Ni}^DDE@!Fm#}CB&a-Q%-?F>b}Kty4- zv8MNlZx(%UP>cbA)*1Manb#dnbUNA+kMC`ItLc;4BJoP5SzR#sHlTJt-hQF#_ zeH#6Q%|t^90rz|~T|OpUjrL+``B8)toy)Mf>3C_Dvt4G$Q5i_{z)DCDR0-cZNyayy%m=9%|S$UuTy14Hm0Kw<#lcVc2X2UdCK1qFv;Oc7bijEFSTCXx31N9L|aw2pB z^jBRlo!;DP0l=8l|10H>C2p{qThKW<<7-KrsgpfY461fwh0d`5vzWF=6#Uz$h5U`^ z>_`_X`6mtpdjC(%!BLQHcg<-JnN~%}WzBFeC<+;u1d4D7fBwJ&IQnob;PhG#@QZ_L z$}AQNf(r!~ctFHaQQBYzZ7kPzQzTD^<7v{>8lg*y5>=w73wLAJb+5m2P5cnR#d?rW5mhulnA>rGtHoru6{PGH# zwx6%?mNuV%j=g{Q{g#9=5}?^S3`3EF5^qOpcFy`U9AI&L#LbTTK{@EM*dn(9d;MdY zg+?Y%p9y7v{`JRVkL#dk6X$L@qgbCRQy)Zta_fS&(CqFzSLjI`+w4os2%a39lQRfx z)qZCKU#_s;r#V}qT#!uBdW9qX}gp{+4U zE>>63WYd7HO7Nart$w-~^?JNqKH%Xq0L%iPW*9w5yG~3C#bPTrn zWt%X<0BPT!ClGA=9qxCgPFr;gb8+biB7S- zu;Uwu^Ud?h;}g#W6E(QqBA?JPliH`>I>+kvvL>pPZoQw)Q#bI(YCk<+8_;VIqCEcC z>41n@D6tW!JBHsaYxCHOmG$NHH(j%hd)&i#B_{&@`CCSEnDx_dH^FI}$>qQqaW}zB zlQgo76iK`lbPp4#^1pt1<>f;b;m##@3xM-;Rc%KuKTVHl&)o|EhS!SP2h?hv+3%L7 zd~OvJW@)@tanyQ5Ks`QjrzPJWK`^Zhg`w#k7JnpSdu204c0Z-1j%CK5?E>Gzy`P~E zG;4x$V($vR20F?t^KGkVRWnkAluEiB_iv=C zaArjD9Mja8Gd>c8=Xygu=c9?WK96kGah zLS>}!IcO}j7y<7Alk7fDn-1P8ErwbgTa>WWXl?RngWJQq9YX<|Y%#K!+-DzfmOY;R zTG0J!GtO$X1c`ijPm=nXcSuLcFWpQdMXePz-%h-(f=+|g&Qj4>nfc?Y9n3KS$7KCW zJ2*kK!=%$sBIPE{nDH0G*BlNFR_=;22t@nWz*{}4;DWcGnS4Sya(wi2AdIq%#ed?A zzF(G&9?$35FB57!L%3^T zChL>Lp#i)jOReL9MW;0i2@F*D9UWavRG2KD#_Lzq2~DZOz`7{-8$(Iagb;PN5d2QRE7x7{7AUZQzHS-#=HC5uqwS~L)68 zfPXH~XJ*)R=?96P$z8Z$v)i$PZ2;EW6!AlLl0H$tVYuvYorW*xa;stA>`CM{-8LV# z$+vI2!RB~WsHr>h<;nZ{Qfu#)#%|xL%)lhq_8SH2R`wt6dzc19weDlGb}HJQ*Q0)H zq&f;D__LnmJ678U*$9TkaaT>4t-hImc9%iy@0=r19OkO778iawtlWiGvpX~=PZ;3ES9b`hMu&h zF|>>jJaT-mY-;@Ev0^CtEar4P4()Fd%hy`FZ;ZYjLibh=@ul={SBT=mbJZJ^k99Z) z`;%kViDI42^RQ0CX^sJdAt3~^aDUAx^LREPhwq(tS|Y3IZd?Ukfw%0gV8V>B?Rw)0 z@Y3qk-O^@*pl$AqN2Rw1QAbjP7A>SBic0F6gph8Z?)}Pz@5Rp?7?6YXZ0oJv0l#!~ z`n0_@;^c)iqas!HIj$e5eYE(pmi!KGqO-UX=5}H?t*&}Lx+Alg?K{Iqb=R@`(R&BI z!7PfBy*@X>%=&7bMKRRxxNoU^-znXMes&oo(BD7(YV7$OYbCjpIKVdXq8{_J5dGQ! zd-K#rb|LI+TWiGDlu?RJYbk#1ngoa-Q7^r0uHK-Kb+LZ)`ZYRURDn2^-iI2Js|R|z zZHJ2kCeBAlG+n}zSSLw#JCAn2+9R=NTY^=Tg? zp}UtkA~w_e2c=%~e4ysO^3Qjs_w9Dh>#RKCGHcGB#wXD$j>2}EKZTuDg`NJQQ@j{PVLpHHMex6$;?s2p4X8@#p3&= zuW*iwQBaqwU@*n|p<*6jXB9{ZtmQLWQM+}`u;V2q*dABa$%ZDI7xJVk+bQ_8`8}-F zFK5ncN0cY1TKJ0b$eNGrBYl)D7U?>G~}??o(B!tt0TZ%}eM=G?#3S7dig1GP7TQ%lN*yDjvEag1|Ln9DS4 zRiB_C=5MAaeB5=2J=E72`G|87;=cn@ z(1P@13;DY2R<~b*Rj`THx#QMTEk>95TidPc($Ev;bQ_klPR~rQCA`?xzhykcA~U^_ z3l0lW3pfWOIeh4Tl%w1;O#6*cQ&m-MXj;`sS~(_F^$M=C|9Uf;?*s}+qQc-`WS2;1=@ zIC!6`b)B^b5NJhvJV_ADbVXH!)aDC>u8M8^S$=9;M!f(!7w(Yfz7`e&DgB_Il6Tj^BRk!3+H8^)G0qqCmnP975(r zqI`XNrSTaS=~me*JF_&RZOVYBHuSE#n(6{@)_?KEL|%VVj)87_zaf8G$XYYV% z_DId>V9@!(>)Fk&6{zbS3^RK2xIW+@es1~4Hjk#m;a7| z&_bdLJ9T$3O`kLW1Xb*)ecbzK3wh#Yi4?o=-nDyuuX&qYFAzaoy7Qhp&W@2;O-^6s zQQyB0CDb03C_Fd`PrKmYzPd|D@)FE9qpcWPX@pOWMWtk>c7>#CCtCm&07t_I7Dips z8#Y27k@ZJnY!Rt?yjCLJ&Fpls3mJQO=0j`CT-tceYpwTb|5qH-4vKSRm^Q2OO2Q1 z4bp4L`nvswd4J6F#(L7(`DxrXYtbie*YugL0S`C!A1Qav62;wVLH2T2s`8JozZ79P z86jgw$2FiQcSDKw?1R2zW8rzdRx3*LW`*&9b#6&4aBZO^xq_&O9p&RDEO;2t%JH)) zBKyEi;_X{GHJUZ;#pW_@s{37;yy6$-wSJy?9>0mS>B^JM-h~``M!_WP8hMw>}h$Waj`Cx&Wp(1PL_DVUFxzdf-nvsaC!|PeQ%gum)8e*iGT$3-VkM^k@zZ@;Yqlowg-PozXYV&`%09`%W`*#>r|(Me&8{9@ z`p_-N8NSJvkgHB@s?d`z$JNoFc&~}o1^GnV`*Dfw?(-X7@JWKUQ+iY`0Zi+

    DhdvKq|~3(-0a%1dW9Pxp?DsJ2NUoTc9) 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 diff --git a/docs/graphics/debugger_ram.png b/docs/graphics/debugger_ram.png index efdc8531ba9095ac41f742488ef9b8ab8e724809..a5711bf024306ce1668bc86b5307b723db90a853 100644 GIT binary patch literal 3163 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 B{p$b# literal 5185 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 GnEwE&IAneR diff --git a/docs/graphics/debugger_tiainfo.png b/docs/graphics/debugger_tiainfo.png index e19f4ea4abb68d1cea232ae1877fae2d3ade00eb..14ae847052ae310cfb64db3a54687a3fa0d774e5 100644 GIT binary patch delta 1381 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⋛Bg;R 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

    gnTa=93zH&Rb{}hy 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 delta 52066 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 fmDil=o^lyZ^B(hKKEU*b)B^x3K4T diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 78e59aa2a..c15c35eac 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -877,7 +877,7 @@ std::array Debugger::ourBuiltinFunctions = { { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Names are defined here, but processed in YaccParser -std::array Debugger::ourPseudoRegisters = { { +std::array Debugger::ourPseudoRegisters = { { // Debugger::PseudoRegister Debugger::ourPseudoRegisters[NUM_PSEUDO_REGS] = { { "_bank", "Currently selected bank" }, { "_cclocks", "Color clocks on current scanline" }, @@ -885,6 +885,7 @@ std::array Debugger::ourPseudoRegisters = { { { "_cycleslo", "Lower 32 bits of number of cycles since emulation started" }, { "_fcount", "Number of frames since emulation started" }, { "_fcycles", "Number of cycles since frame started" }, + { "_ftimreadcycles","Number of cycles used by timer reads since frame started" }, { "_fwsynccycles", "Number of cycles skipped by WSYNC since frame started" }, { "_icycles", "Number of cycles of last instruction" }, { "_scan", "Current scanline count" }, diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 8ba5c626f..91abdd879 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -363,7 +363,7 @@ class Debugger : public DialogContainer string name, help; }; static std::array ourBuiltinFunctions; - static std::array ourPseudoRegisters; + static std::array ourPseudoRegisters; private: // rewind/unwind n states diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx index 7d4bc6c0a..34a21b8cf 100644 --- a/src/debugger/RiotDebug.cxx +++ b/src/debugger/RiotDebug.cxx @@ -68,6 +68,8 @@ const DebuggerState& RiotDebug::getState() myState.INTIMCLKS = intimClocks(); myState.TIMDIV = timDivider(); + myState.timReadCycles = timReadCycles(); + return myState; } @@ -111,6 +113,8 @@ void RiotDebug::saveOldState() myOldState.TIMCLKS = timClocks(); myOldState.INTIMCLKS = intimClocks(); myOldState.TIMDIV = timDivider(); + + myOldState.timReadCycles = timReadCycles(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -247,6 +251,12 @@ int RiotDebug::timWrappedOnWrite() const return mySystem.m6532().myTimWrappedOnWrite; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int RiotDebug::timReadCycles() const +{ + return mySystem.m6532().myTimReadCycles; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool RiotDebug::diffP0(int newVal) { diff --git a/src/debugger/RiotDebug.hxx b/src/debugger/RiotDebug.hxx index 30f4defe8..999b3da3e 100644 --- a/src/debugger/RiotDebug.hxx +++ b/src/debugger/RiotDebug.hxx @@ -41,6 +41,7 @@ class RiotState : public DebuggerState uInt8 TIM1T{0}, TIM8T{0}, TIM64T{0}, T1024T{0}, INTIM{0}, TIMINT{0}; Int32 TIMCLKS{0}, INTIMCLKS{0}, TIMDIV{0}; + uInt16 timReadCycles; // These are actually from the TIA, but are I/O related uInt8 INPT0{0}, INPT1{0}, INPT2{0}, INPT3{0}, INPT4{0}, INPT5{0}; @@ -83,6 +84,8 @@ class RiotDebug : public DebuggerSystem int timWrappedOnRead() const; int timWrappedOnWrite() const; + int timReadCycles() const; + /* Console switches */ bool diffP0(int newVal = -1); bool diffP1(int newVal = -1); diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index d7855e2f5..b8c0662ee 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -478,20 +478,21 @@ void DebuggerDialog::addStatusArea() { const int lineHeight = myLFont->getLineHeight(); const Common::Rect& r = getStatusBounds(); + const int HBORDER = 10; + const int VGAP = lineHeight / 3; int xpos, ypos; - xpos = r.x(); ypos = r.y(); - myTiaInfo = new TiaInfoWidget(this, *myLFont, *myNFont, xpos, ypos, r.w()); + xpos = r.x() + HBORDER; ypos = r.y(); + myTiaInfo = new TiaInfoWidget(this, *myLFont, *myNFont, xpos, ypos, r.w() - HBORDER); - ypos += myTiaInfo->getHeight() + 8; - myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos + 10, ypos, - r.w() - 10, r.h() - lineHeight - ypos - 3); + ypos = myTiaInfo->getBottom() + VGAP; + myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos, ypos, + r.w() - HBORDER, r.h() - ypos - VGAP - lineHeight + 3); addToFocusList(myTiaZoom->getFocusList()); - xpos += 10; ypos += myTiaZoom->getHeight() + 6; - myMessageBox = new EditTextWidget(this, *myLFont, - xpos, ypos, myTiaZoom->getWidth(), - myLFont->getLineHeight(), ""); + ypos = myTiaZoom->getBottom() + VGAP; + myMessageBox = new EditTextWidget(this, *myLFont, xpos, ypos, + myTiaZoom->getWidth(), lineHeight); myMessageBox->setEditable(false, false); myMessageBox->clearFlags(Widget::FLAG_RETAIN_FOCUS); myMessageBox->setTextColor(kTextColorEm); diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index 35998d498..c892422c5 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -19,6 +19,7 @@ #include "Font.hxx" #include "OSystem.hxx" #include "Debugger.hxx" +#include "RiotDebug.hxx" #include "TIADebug.hxx" #include "TIA.hxx" #include "Widget.hxx" @@ -34,55 +35,71 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, : Widget(boss, lfont, x, y, 16, 16), CommandSender(boss) { - bool longstr = 11 + 32 * lfont.getMaxCharWidth() + 9 - + EditTextWidget::calcWidth(lfont) * 3 <= max_w; const int VGAP = lfont.getLineHeight() / 4; const int VBORDER = 5 + 1; - - x += 11; + const int COLUMN_GAP = _fontWidth * 1.25; + bool longstr = lfont.getStringWidth("Frame Cycle12345") + _fontWidth * 0.5 + + COLUMN_GAP + lfont.getStringWidth("Scanline262262") + + EditTextWidget::calcWidth(lfont) * 3 <= max_w; const int lineHeight = lfont.getLineHeight(); int xpos = x, ypos = y + VBORDER; - int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle" : "F. Cycle") + _fontWidth * 0.5; - int l2width = lwidth - lfont.getMaxCharWidth() * 3; + int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle" : "F. Cycle"); + int lwidth8 = lwidth - lfont.getMaxCharWidth() * 3; + int lwidthR = lfont.getStringWidth(longstr ? "Frame Cnt." : "Frame "); int fwidth = EditTextWidget::calcWidth(lfont, 5); - int twidth = EditTextWidget::calcWidth(lfont, 8); + const int twidth = EditTextWidget::calcWidth(lfont, 8); + const int LGAP = (max_w - lwidth - EditTextWidget::calcWidth(lfont, 5) + - lwidthR - EditTextWidget::calcWidth(lfont, 5)) / 4; + + lwidth += LGAP; + lwidth8 += LGAP; + lwidthR += LGAP; // Left column - // Left: Frame Count - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Count " : "Frame "); - myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); - myFrameCount->setEditable(false, true); - // Left: Frame Cycle - xpos = x; ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycle " : "F. Cycle "); + xpos = x; + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycle" : "F. Cycle"); myFrameCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myFrameCycles->setEditable(false, true); // Left: WSync Cycles ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycl. " : "WSync C. "); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycl." : "WSync C."); myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myWSyncCylces->setEditable(false, true); + // Left: Timer Cycles + ypos += lineHeight + VGAP; + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycl." : "Timer C."); + myTimerCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myTimerCylces->setEditable(false, true); + // Left: Total Cycles ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total "); - myTotalCycles = new EditTextWidget(boss, nfont, xpos + l2width, ypos - 1, twidth, lineHeight); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total"); + myTotalCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight); myTotalCycles->setEditable(false, true); // Left: Delta Cycles ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta "); - myDeltaCycles = new EditTextWidget(boss, nfont, xpos + l2width, ypos - 1, twidth, lineHeight); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta"); + myDeltaCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight); myDeltaCycles->setEditable(false, true); // Right column - xpos = myFrameCycles->getRight() + _fontWidth * 1.25; ypos = y + VBORDER; - lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos "); + xpos = x + max_w - lwidthR - EditTextWidget::calcWidth(lfont, 5); ypos = y + VBORDER; + //xpos = myDeltaCycles->getRight() + LGAP * 2; ypos = y + VBORDER; + + // Right: Frame Count + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cnt." : "Frame"); + myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidthR, ypos - 1, fwidth, lineHeight); + myFrameCount->setEditable(false, true); + + lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ") + LGAP; fwidth = EditTextWidget::calcWidth(lfont, 3); // Right: Scanline + ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scanline" : "Scn Ln"); myScanlineCountLast = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myScanlineCountLast->setEditable(false, true); @@ -93,25 +110,25 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, // Right: Scan Cycle ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle " : "Scn Cycle"); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle" : "Scn Cycle"); myScanlineCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myScanlineCycles->setEditable(false, true); // Right: Pixel Pos ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Pixel Pos "); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Pixel Pos"); myPixelPosition = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myPixelPosition->setEditable(false, true); // Right: Color Clock ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Color Clock " : "Color Clk "); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Color Clock" : "Color Clk"); myColorClocks = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myColorClocks->setEditable(false, true); // Calculate actual dimensions _w = myColorClocks->getRight() - x; - _h = myDeltaCycles->getBottom(); + _h = myColorClocks->getBottom(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -131,6 +148,8 @@ void TiaInfoWidget::loadConfig() Debugger& dbg = instance().debugger(); TIADebug& tia = dbg.tiaDebug(); const TiaState& oldTia = static_cast(tia.getOldState()); + RiotDebug& riot = dbg.riotDebug(); + const RiotState& oldRiot = static_cast(riot.getOldState()); myFrameCount->setText(Common::Base::toString(tia.frameCount(), Common::Base::Fmt::_10_5), tia.frameCount() != oldTia.info[0]); @@ -159,4 +178,7 @@ void TiaInfoWidget::loadConfig() myWSyncCylces->setText(Common::Base::toString(tia.frameWsyncCycles(), Common::Base::Fmt::_10_5), tia.frameWsyncCycles() != oldTia.info[7]); + + myTimerCylces->setText(Common::Base::toString(riot.timReadCycles(), Common::Base::Fmt::_10_5), + riot.timReadCycles() != oldRiot.timReadCycles); } diff --git a/src/debugger/gui/TiaInfoWidget.hxx b/src/debugger/gui/TiaInfoWidget.hxx index c0e029879..3b21a222b 100644 --- a/src/debugger/gui/TiaInfoWidget.hxx +++ b/src/debugger/gui/TiaInfoWidget.hxx @@ -41,6 +41,7 @@ class TiaInfoWidget : public Widget, public CommandSender EditTextWidget* myTotalCycles{nullptr}; EditTextWidget* myDeltaCycles{nullptr}; EditTextWidget* myWSyncCylces{nullptr}; + EditTextWidget* myTimerCylces{nullptr}; EditTextWidget* myScanlineCount{nullptr}; EditTextWidget* myScanlineCountLast{nullptr}; diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx index 64df91377..eaa43c61f 100644 --- a/src/emucore/M6532.cxx +++ b/src/emucore/M6532.cxx @@ -226,6 +226,7 @@ uInt8 M6532::peek(uInt16 addr) if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit; #ifdef DEBUGGER_SUPPORT myTimWrappedOnRead = myWrappedThisCycle; + myTimReadCycles += 7; #endif return myTimer; } @@ -236,6 +237,9 @@ uInt8 M6532::peek(uInt16 addr) // PA7 Flag is always cleared after accessing TIMINT uInt8 result = myInterruptFlag; myInterruptFlag &= ~PA7Bit; + #ifdef DEBUGGER_SUPPORT + myTimReadCycles += 7; + #endif return result; } @@ -376,6 +380,9 @@ bool M6532::save(Serializer& out) const out.putBool(myWrappedThisCycle); out.putLong(myLastCycle); out.putLong(mySetTimerCycle); + #ifdef DEBUGGER_SUPPORT + out.putInt(myTimReadCycles); + #endif out.putByte(myDDRA); out.putByte(myDDRB); @@ -408,6 +415,9 @@ bool M6532::load(Serializer& in) myWrappedThisCycle = in.getBool(); myLastCycle = in.getLong(); mySetTimerCycle = in.getLong(); + #ifdef DEBUGGER_SUPPORT + myTimReadCycles = in.getInt(); + #endif myDDRA = in.getByte(); myDDRB = in.getByte(); diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index 650745811..f0f802135 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -137,6 +137,11 @@ class M6532 : public Device @return The access counters as comma separated string */ string getAccessCounters() const override; + + /** + Reset the timer read CPU cycle counter + */ + void resetTimReadCylces() { myTimReadCycles = 0; } #endif private: @@ -254,6 +259,8 @@ class M6532 : public Device // Detect timer being accessed on wraparound bool myTimWrappedOnRead{false}; bool myTimWrappedOnWrite{false}; + // Timer read CPU cycles + uInt16 myTimReadCycles{0}; #endif // DEBUGGER_SUPPORT private: diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx index e0f6e2dda..3ae0713c3 100644 --- a/src/emucore/tia/TIA.cxx +++ b/src/emucore/tia/TIA.cxx @@ -17,6 +17,7 @@ #include "TIA.hxx" #include "M6502.hxx" +#include "M6532.hxx" #include "Control.hxx" #include "Paddles.hxx" #include "DelayQueueIteratorImpl.hxx" @@ -162,8 +163,10 @@ void TIA::initialize() myDelayQueue.reset(); +#ifdef DEBUGGER_SUPPORT myCyclesAtFrameStart = 0; myFrameWsyncCycles = 0; +#endif if (myFrameManager) myFrameManager->reset(); @@ -279,8 +282,10 @@ bool TIA::save(Serializer& out) const out.putByteArray(myShadowRegisters.data(), myShadowRegisters.size()); + #ifdef DEBUGGER_SUPPORT out.putLong(myCyclesAtFrameStart); out.putLong(myFrameWsyncCycles); + #endif out.putInt(myFrameBufferScanlines); out.putInt(myFrontBufferScanlines); @@ -352,8 +357,10 @@ bool TIA::load(Serializer& in) in.getByteArray(myShadowRegisters.data(), myShadowRegisters.size()); + #ifdef DEBUGGER_SUPPORT myCyclesAtFrameStart = in.getLong(); myFrameWsyncCycles = in.getLong(); + #endif myFrameBufferScanlines = in.getInt(); myFrontBufferScanlines = in.getInt(); @@ -1307,7 +1314,10 @@ void TIA::updateEmulation() void TIA::onFrameStart() { myXAtRenderingStart = 0; +#ifdef DEBUGGER_SUPPORT myFrameWsyncCycles = 0; + mySystem->m6532().resetTimReadCylces(); +#endif // Check for colour-loss emulation if (myColorLossEnabled) @@ -1333,7 +1343,9 @@ void TIA::onFrameStart() void TIA::onFrameComplete() { mySystem->m6502().stop(); +#ifdef DEBUGGER_SUPPORT myCyclesAtFrameStart = mySystem->cycles(); +#endif if (myXAtRenderingStart > 0) std::fill_n(myBackBuffer.begin(), myXAtRenderingStart, 0); @@ -1355,7 +1367,9 @@ void TIA::onHalt() { mySubClock += (TIAConstants::H_CLOCKS - myHctr) % TIAConstants::H_CLOCKS; mySystem->incrementCycles(mySubClock / TIAConstants::CYCLE_CLOCKS); - myFrameWsyncCycles += mySubClock / TIAConstants::CYCLE_CLOCKS; +#ifdef DEBUGGER_SUPPORT + myFrameWsyncCycles += 3 + mySubClock / TIAConstants::CYCLE_CLOCKS; +#endif mySubClock %= TIAConstants::CYCLE_CLOCKS; } diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index a7c262117..4d959e3b0 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -322,6 +322,7 @@ class TIA : public Device */ uInt64 cycles() const { return uInt64(mySystem->cycles()); } + #ifdef DEBUGGER_SUPPORT /** Answers the frame count from the start of the emulation. */ @@ -340,6 +341,7 @@ class TIA : public Device uInt32 frameWSyncCycles() const { return uInt32(myFrameWsyncCycles); } + #endif // DEBUGGER_SUPPORT /** * Get the CPU cycles since the last dump ports change. @@ -560,7 +562,7 @@ class TIA : public Device @return The access counters as comma separated string */ string getAccessCounters() const override; - #endif + #endif // DEBUGGER_SUPPORT private: /** @@ -941,6 +943,7 @@ class TIA : public Device std::array myColorCounts; + #ifdef DEBUGGER_SUPPORT /** * System cycles at the end of the previous frame / beginning of next frame. */ @@ -950,6 +953,7 @@ class TIA : public Device * System cycles used by WSYNC during current frame. */ uInt64 myFrameWsyncCycles{0}; + #endif // DEBUGGER_SUPPORT /** * The frame manager can change during our lifetime, so we buffer those two. diff --git a/src/yacc/YaccParser.cxx b/src/yacc/YaccParser.cxx index f55450ad1..ba74728dd 100644 --- a/src/yacc/YaccParser.cxx +++ b/src/yacc/YaccParser.cxx @@ -236,6 +236,8 @@ RiotMethod getRiotSpecial(char* ch) return &RiotDebug::timWrappedOnRead; else if(BSPF::equalsIgnoreCase(ch, "_timwrapwrite")) return &RiotDebug::timWrappedOnWrite; + else if(BSPF::equalsIgnoreCase(ch, "_ftimreadcycles")) + return &RiotDebug::timReadCycles; else return nullptr; } From 99d1370ccb645dbed2de5004e97fbc37daf7274a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 13 Oct 2020 10:47:37 -0230 Subject: [PATCH 078/263] Started cleanup of FrameBuffer class. - Moved Video mode stuff into separate class - Fix bug with aspect correction in fullscreen mode still giving graphical artifacts --- src/common/FrameBufferSDL2.cxx | 3 +- src/common/FrameBufferSDL2.hxx | 3 +- src/common/Version.hxx | 2 +- src/common/VideoModeHandler.cxx | 164 ++++++++++ src/common/VideoModeHandler.hxx | 111 +++++++ src/common/module.mk | 15 +- src/emucore/Console.cxx | 4 + src/emucore/EventHandler.cxx | 6 +- src/emucore/FrameBuffer.cxx | 443 +++++++-------------------- src/emucore/FrameBuffer.hxx | 142 +++------ src/emucore/TIASurface.cxx | 2 +- src/emucore/TIASurface.hxx | 2 +- src/libretro/FrameBufferLIBRETRO.hxx | 3 +- src/libretro/Makefile.common | 1 + 14 files changed, 439 insertions(+), 462 deletions(-) create mode 100644 src/common/VideoModeHandler.cxx create mode 100644 src/common/VideoModeHandler.hxx diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index 24b038d01..98f3ea36c 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -225,7 +225,8 @@ Int32 FrameBufferSDL2::getCurrentDisplayIndex() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) +bool FrameBufferSDL2::activateVideoMode(const string& title, + const VideoModeHandler::Mode& mode) { ASSERT_MAIN_THREAD; diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FrameBufferSDL2.hxx index 0b3386d08..20ae489e4 100644 --- a/src/common/FrameBufferSDL2.hxx +++ b/src/common/FrameBufferSDL2.hxx @@ -179,7 +179,8 @@ class FrameBufferSDL2 : public FrameBuffer @return False on any errors, else true */ - bool setVideoMode(const string& title, const VideoMode& mode) override; + bool activateVideoMode(const string& title, + const VideoModeHandler::Mode& mode) override; /** Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode diff --git a/src/common/Version.hxx b/src/common/Version.hxx index e84d6ece3..18bd4c76c 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.3" +#define STELLA_VERSION "6.4_pre" #define STELLA_BUILD "6180" #endif diff --git a/src/common/VideoModeHandler.cxx b/src/common/VideoModeHandler.cxx new file mode 100644 index 000000000..259f61caa --- /dev/null +++ b/src/common/VideoModeHandler.cxx @@ -0,0 +1,164 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "Settings.hxx" +#include "VideoModeHandler.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void VideoModeHandler::setImageSize(const Common::Size& image) +{ + myImage = image; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void VideoModeHandler::setDisplaySize(const Common::Size& display, Int32 fsIndex) +{ + myDisplay = display; + myFSIndex = fsIndex; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const VideoModeHandler::Mode& +VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode) +{ + const bool windowedRequested = myFSIndex == -1; + + // TIA mode allows zooming at non-integral factors in most cases + if(inTIAMode) + { + if(windowedRequested) + { + const float zoom = settings.getFloat("tia.zoom"); + ostringstream desc; + desc << (zoom * 100) << "%"; + + // Image and screen (aka window) dimensions are the same + // Overscan is not applicable in this mode + myMode = Mode(myImage.w * zoom, myImage.h * zoom, Mode::Stretch::Fill, + myFSIndex, desc.str(), zoom); + } + else + { + const float overscan = 1 - settings.getInt("tia.fs_overscan") / 100.0; + + // First calculate maximum zoom that keeps aspect ratio + const float scaleX = float(myImage.w) / myDisplay.w, + scaleY = float(myImage.h) / myDisplay.h; + float zoom = 1.F / std::max(scaleX, scaleY); + + // When aspect ratio correction is off, we want pixel-exact images, + // so we default to integer zooming + if(!settings.getBool("tia.correct_aspect")) + zoom = static_cast(zoom); + + if(!settings.getBool("tia.fs_stretch")) // preserve aspect, use all space + { + myMode = Mode(myImage.w * zoom, myImage.h * zoom, + myDisplay.w, myDisplay.h, + Mode::Stretch::Preserve, myFSIndex, + "Fullscreen: Preserve aspect, no stretch", zoom, overscan); + } + else // ignore aspect, use all space + { + myMode = Mode(myImage.w * zoom, myImage.h * zoom, + myDisplay.w, myDisplay.h, + Mode::Stretch::Fill, myFSIndex, + "Fullscreen: Ignore aspect, full stretch", zoom, overscan); + } + } + } + else // UI mode (no zooming) + { + if(windowedRequested) + myMode = Mode(myImage.w, myImage.h, Mode::Stretch::None); + else + myMode = Mode(myImage.w, myImage.h, myDisplay.w, myDisplay.h, + Mode::Stretch::None, myFSIndex); + } + + return myMode; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, Stretch smode, + Int32 fsindex, const string& desc, + float zoomLevel) + : Mode(iw, ih, iw, ih, smode, fsindex, desc, zoomLevel) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, + Stretch smode, Int32 fsindex, const string& desc, + float zoomLevel, float overscan) + : stretch(smode), + description(desc), + zoom(zoomLevel), + fsIndex(fsindex) +{ + // First set default size and positioning + screen = Common::Size(sw, sh); + + // Now resize based on windowed/fullscreen mode and stretch factor + if(fsIndex != -1) // fullscreen mode + { + switch(stretch) + { + case Stretch::Preserve: + { + iw *= overscan; + ih *= overscan; + break; + } + + case Stretch::Fill: + // Scale to all available space + iw = screen.w * overscan; + ih = screen.h * overscan; + break; + + case Stretch::None: + // Don't do any scaling at all + iw = std::min(iw, screen.w) * overscan; + ih = std::min(ih, screen.h) * overscan; + break; + } + } + else + { + // In windowed mode, currently the size is scaled to the screen + // TODO - this may be updated if/when we allow variable-sized windows + switch(stretch) + { + case Stretch::Preserve: + case Stretch::Fill: + screen.w = iw; + screen.h = ih; + break; + case Stretch::None: + break; // Do not change image or screen rects whatsoever + } + } + + // Now re-calculate the dimensions + iw = std::min(iw, screen.w); + ih = std::min(ih, screen.h); + + image.moveTo((screen.w - iw) >> 1, (screen.h - ih) >> 1); + image.setWidth(iw); + image.setHeight(ih); +} diff --git a/src/common/VideoModeHandler.hxx b/src/common/VideoModeHandler.hxx new file mode 100644 index 000000000..b91e34894 --- /dev/null +++ b/src/common/VideoModeHandler.hxx @@ -0,0 +1,111 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef VIDEO_MODE_HANDLER_HXX +#define VIDEO_MODE_HANDLER_HXX + +class Settings; + +#include "Rect.hxx" +#include "bspf.hxx" + +class VideoModeHandler +{ + public: + // Contains all relevant info for the dimensions of a video screen + // Also takes care of the case when the image should be 'centered' + // within the given screen: + // 'image' is the image dimensions into the screen + // 'screen' are the dimensions of the screen itself + struct Mode + { + enum class Stretch { + Preserve, // Stretch to fill all available space; preserve aspect ratio + Fill, // Stretch to fill all available space + None // No stretching (1x zoom) + }; + + Common::Rect image; + Common::Size screen; + Stretch stretch{Mode::Stretch::None}; + string description; + float zoom{1.F}; + Int32 fsIndex{-1}; // -1 indicates windowed mode + + Mode() = default; + Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode, + Int32 fsindex = -1, const string& desc = "", + float zoomLevel = 1.F, float overscan = 1.F); + Mode(uInt32 iw, uInt32 ih, Stretch smode, Int32 fsindex = -1, + const string& desc = "", float zoomLevel = 1.F); + + friend ostream& operator<<(ostream& os, const Mode& vm) + { + os << "image=" << vm.image << " screen=" << vm.screen + << " stretch=" << (vm.stretch == Stretch::Preserve ? "preserve" : + vm.stretch == Stretch::Fill ? "fill" : "none") + << " desc=" << vm.description << " zoom=" << vm.zoom + << " fsIndex= " << vm.fsIndex; + return os; + } + }; + + public: + VideoModeHandler() = default; + + /** + Set the base size of the image. Scaling can be applied to this, + which will change the effective size. + + @param image The base dimensions of the image + */ + void setImageSize(const Common::Size& image); + + /** + Set the size of the display. This could be either the desktop size, + or the size of the monitor currently active. + + @param display The dimensions of the enclosing display + @param fsIndex Fullscreen mode in use (-1 indicates windowed mode) + */ + void setDisplaySize(const Common::Size& display, Int32 fsIndex = -1); + + /** + Build a video mode based on the given parameters, assuming that + setImageSize and setDisplaySize have been previously called. + + @param settings Used to query various options that affect video mode + @param inTIAMode Whether the video mode is being used for TIA emulation + + @return A video mode based on the given criteria + */ + const VideoModeHandler::Mode& buildMode(const Settings& settings, bool inTIAMode); + + private: + Common::Size myImage, myDisplay; + Int32 myFSIndex{-1}; + + Mode myMode; + + private: + VideoModeHandler(const VideoModeHandler&) = delete; + VideoModeHandler(VideoModeHandler&&) = delete; + VideoModeHandler& operator=(const VideoModeHandler&) = delete; + VideoModeHandler& operator=(const VideoModeHandler&&) = delete; +}; + +#endif // VIDEO_MODE_HANDLER_HXX diff --git a/src/common/module.mk b/src/common/module.mk index 1aae6cd0a..46248b23e 100644 --- a/src/common/module.mk +++ b/src/common/module.mk @@ -1,9 +1,12 @@ MODULE := src/common MODULE_OBJS := \ + src/common/AudioQueue.o \ + src/common/AudioSettings.o \ src/common/Base.o \ src/common/EventHandlerSDL2.o \ src/common/FBSurfaceSDL2.o \ + src/common/FpsMeter.o \ src/common/FrameBufferSDL2.o \ src/common/FSNodeZIP.o \ src/common/JoyMap.o \ @@ -19,14 +22,12 @@ MODULE_OBJS := \ src/common/PNGLibrary.o \ src/common/RewindManager.o \ src/common/SoundSDL2.o \ - src/common/StateManager.o \ - src/common/TimerManager.o \ - src/common/ZipHandler.o \ - src/common/AudioQueue.o \ - src/common/AudioSettings.o \ - src/common/FpsMeter.o \ - src/common/ThreadDebugging.o \ src/common/StaggeredLogger.o \ + src/common/StateManager.o \ + src/common/ThreadDebugging.o \ + src/common/TimerManager.o \ + src/common/VideoModeHandler.o \ + src/common/ZipHandler.o \ src/common/repository/KeyValueRepositoryConfigfile.o \ src/common/sdl_blitter/BilinearBlitter.o \ src/common/sdl_blitter/QisBlitter.o \ diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index a0bd2a25a..2d4f0f5a6 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -622,6 +622,10 @@ FBInitStatus Console::initializeVideo(bool full) if(full) { + auto size = myOSystem.settings().getBool("tia.correct_aspect") ? + Common::Size(TIAConstants::viewableWidth, TIAConstants::viewableHeight) : + Common::Size(2 * myTIA->width(), myTIA->height()); + uInt32 width, height; if (!myOSystem.settings().getBool("tia.correct_aspect")) { width = 2 * myTIA->width(); diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 788cb73b9..a5b0d5b1f 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -411,7 +411,7 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) { // Audio & Video settings std::bind(&Sound::adjustVolume, &myOSystem.sound(), _1), - std::bind(&FrameBuffer::selectVidMode, &myOSystem.frameBuffer(), _1), + std::bind(&FrameBuffer::switchVideoMode, &myOSystem.frameBuffer(), _1), std::bind(&FrameBuffer::toggleFullscreen, &myOSystem.frameBuffer(), _1), #ifdef ADAPTABLE_REFRESH_SUPPORT std::bind(&FrameBuffer::toggleAdaptRefresh, &myOSystem.frameBuffer(), _1), @@ -693,7 +693,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) case Event::VidmodeDecrease: if(pressed) { - myOSystem.frameBuffer().selectVidMode(-1); + myOSystem.frameBuffer().switchVideoMode(-1); myAdjustSetting = AdjustSetting::ZOOM; myAdjustActive = true; } @@ -702,7 +702,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) case Event::VidmodeIncrease: if(pressed) { - myOSystem.frameBuffer().selectVidMode(+1); + myOSystem.frameBuffer().switchVideoMode(+1); myAdjustSetting = AdjustSetting::ZOOM; myAdjustActive = true; } diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index c3c9bfe02..420826bf3 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -104,9 +104,11 @@ bool FrameBuffer::initialize() #endif // Determine possible TIA windowed zoom levels - myTIAMaxZoom = maxZoomForScreen( - TIAConstants::viewableWidth, TIAConstants::viewableHeight, - myAbsDesktopSize.w, myAbsDesktopSize.h); + myTIAMaxZoom = maxWindowZoom(TIAConstants::viewableWidth, + TIAConstants::viewableHeight); + float currentTIAZoom = myOSystem.settings().getFloat("tia.zoom"); + myOSystem.settings().setValue("tia.zoom", + BSPF::clampw(currentTIAZoom, supportedTIAMinZoom(), myTIAMaxZoom)); setUIPalette(); @@ -173,13 +175,13 @@ void FrameBuffer::setupFonts() // However, we have to make sure all Dialogs are sized using the fontsize. int zoom_h = (fd.height * 4 * 2) / GUI::stellaMediumDesc.height; int zoom_w = (fd.maxwidth * 4 * 2) / GUI::stellaMediumDesc.maxwidth; - myTIAMinZoom = std::max(std::max(zoom_w, zoom_h) / 4.F, 2.F); // round to 25% steps, >= 200% + // round to 25% steps, >= 200% + myTIAMinZoom = std::max(std::max(zoom_w, zoom_h) / 4.F, 2.F); } // The font used by the ROM launcher const string& lf = myOSystem.settings().getString("launcherfont"); - myLauncherFont = make_unique(getFontDesc(lf)); // 8x13 } @@ -215,7 +217,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, ++myInitializedCount; myScreenTitle = title; - // In HiDPI mode, all created displays must be scaled by 2x + // In HiDPI mode, all created displays must be scaled appropriately if(honourHiDPI && hidpiEnabled()) { width *= hidpiScaleFactor(); @@ -232,7 +234,6 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, // If the WINDOWED_SUPPORT macro is defined, we treat the system as the // former type; if not, as the latter type - bool useFullscreen = false; #ifdef WINDOWED_SUPPORT // We assume that a desktop of at least minimum acceptable size means that // we're running on a 'large' system, and the window size requirements @@ -241,40 +242,37 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, if(myDesktopSize.w < FBMinimum::Width && myDesktopSize.h < FBMinimum::Height && (myDesktopSize.w < width || myDesktopSize.h < height)) return FBInitStatus::FailTooLarge; - - useFullscreen = myOSystem.settings().getBool("fullscreen"); #else // Make sure this mode is even possible // We only really need to worry about it in non-windowed environments, // where requesting a window that's too large will probably cause a crash if(myDesktopSize.w < width || myDesktopSize.h < height) return FBInitStatus::FailTooLarge; - - useFullscreen = true; #endif - // Set the available video modes for this framebuffer - setAvailableVidModes(width, height); + // Initialize video mode handler, so it can know what video modes are + // appropriate for this framebuffer + myVidModeHandler.setImageSize(Common::Size(width, height)); // Initialize video subsystem (make sure we get a valid mode) string pre_about = about(); - const FrameBuffer::VideoMode& mode = getSavedVidMode(useFullscreen); - if(width <= mode.screen.w && height <= mode.screen.h) + myActiveVidMode = buildVideoMode(); + if(width <= myActiveVidMode.screen.w && height <= myActiveVidMode.screen.h) { // Changing the video mode can take some time, during which the last // sound played may get 'stuck' // So we mute the sound until the operation completes bool oldMuteState = myOSystem.sound().mute(true); - if(setVideoMode(myScreenTitle, mode)) + if(activateVideoMode(myScreenTitle, myActiveVidMode)) { - myImageRect = mode.image; - myScreenSize = mode.screen; - myScreenRect = Common::Rect(mode.screen); + myImageRect = myActiveVidMode.image; + myScreenSize = myActiveVidMode.screen; + myScreenRect = Common::Rect(myActiveVidMode.screen); // Inform TIA surface about new mode if(myOSystem.eventHandler().state() != EventHandlerState::LAUNCHER && myOSystem.eventHandler().state() != EventHandlerState::DEBUGGER) - myTIASurface->initialize(myOSystem.console(), mode); + myTIASurface->initialize(myOSystem.console(), myActiveVidMode); // Did we get the requested fullscreen state? myOSystem.settings().setValue("fullscreen", fullScreen()); @@ -835,8 +833,9 @@ void FrameBuffer::setPauseDelay() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -shared_ptr FrameBuffer::allocateSurface(int w, int h, ScalingInterpolation interpolation, - const uInt32* data) +shared_ptr FrameBuffer::allocateSurface( + int w, int h, ScalingInterpolation interpolation, const uInt32* data +) { // Add new surface to the list mySurfaceList.push_back(createSurface(w, h, interpolation, data)); @@ -1011,17 +1010,18 @@ void FrameBuffer::setFullscreen(bool enable) // So we mute the sound until the operation completes bool oldMuteState = myOSystem.sound().mute(true); - const VideoMode& mode = getSavedVidMode(enable); - if(setVideoMode(myScreenTitle, mode)) + myOSystem.settings().setValue("fullscreen", enable); + myActiveVidMode = buildVideoMode(); + if(activateVideoMode(myScreenTitle, myActiveVidMode)) { - myImageRect = mode.image; - myScreenSize = mode.screen; - myScreenRect = Common::Rect(mode.screen); + myImageRect = myActiveVidMode.image; + myScreenSize = myActiveVidMode.screen; + myScreenRect = Common::Rect(myActiveVidMode.screen); // Inform TIA surface about new mode if(myOSystem.eventHandler().state() != EventHandlerState::LAUNCHER && myOSystem.eventHandler().state() != EventHandlerState::DEBUGGER) - myTIASurface->initialize(myOSystem.console(), mode); + myTIASurface->initialize(myOSystem.console(), myActiveVidMode); // Did we get the requested fullscreen state? myOSystem.settings().setValue("fullscreen", fullScreen()); @@ -1035,7 +1035,7 @@ void FrameBuffer::setFullscreen(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::toggleFullscreen(bool toggle) { - switch (myOSystem.eventHandler().state()) + switch(myOSystem.eventHandler().state()) { case EventHandlerState::LAUNCHER: case EventHandlerState::EMULATION: @@ -1043,20 +1043,17 @@ void FrameBuffer::toggleFullscreen(bool toggle) case EventHandlerState::DEBUGGER: { const bool isFullscreen = toggle ? !fullScreen() : fullScreen(); - setFullscreen(isFullscreen); - if (myBufferType != BufferType::Launcher) + if(myBufferType != BufferType::Launcher) { ostringstream msg; - const VideoMode& mode = getSavedVidMode(isFullscreen); - msg << "Fullscreen "; if(isFullscreen) msg << "enabled (" << refreshRate() << " Hz, "; else msg << "disabled ("; - msg << "Zoom " << mode.zoom * 100 << "%)"; + msg << "Zoom " << myActiveVidMode.zoom * 100 << "%)"; showMessage(msg.str()); } @@ -1122,7 +1119,7 @@ void FrameBuffer::changeOverscan(int direction) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::selectVidMode(int direction) +void FrameBuffer::switchVideoMode(int direction) { EventHandlerState state = myOSystem.eventHandler().state(); bool tiaMode = (state != EventHandlerState::DEBUGGER && @@ -1132,10 +1129,27 @@ void FrameBuffer::selectVidMode(int direction) if(!tiaMode) return; - if(direction == +1) - myCurrentModeList->next(); - else if(direction == -1) - myCurrentModeList->previous(); + if(!fullScreen()) + { + // Windowed TIA modes support variable zoom levels + float zoom = myOSystem.settings().getFloat("tia.zoom"); + if(direction == +1) zoom += ZOOM_STEPS; + else if(direction == -1) zoom -= ZOOM_STEPS; + + // Make sure the level is within the allowable desktop size + zoom = BSPF::clampw(zoom, supportedTIAMinZoom(), myTIAMaxZoom); + myOSystem.settings().setValue("tia.zoom", zoom); + } + else + { + // In fullscreen mode, there are only two modes, so direction + // is irrelevant + if(direction == +1 || direction == -1) + { + bool stretch = myOSystem.settings().getBool("tia.fs_stretch"); + myOSystem.settings().setValue("tia.fs_stretch", !stretch); + } + } saveCurrentWindowPosition(); @@ -1144,34 +1158,75 @@ void FrameBuffer::selectVidMode(int direction) // So we mute the sound until the operation completes bool oldMuteState = myOSystem.sound().mute(true); - const VideoMode& mode = myCurrentModeList->current(); - if(setVideoMode(myScreenTitle, mode)) + myActiveVidMode = buildVideoMode(); + if(activateVideoMode(myScreenTitle, myActiveVidMode)) { - myImageRect = mode.image; - myScreenSize = mode.screen; - myScreenRect = Common::Rect(mode.screen); + myImageRect = myActiveVidMode.image; + myScreenSize = myActiveVidMode.screen; + myScreenRect = Common::Rect(myActiveVidMode.screen); // Inform TIA surface about new mode - myTIASurface->initialize(myOSystem.console(), mode); + myTIASurface->initialize(myOSystem.console(), myActiveVidMode); resetSurfaces(); if(fullScreen()) - showMessage(mode.description); + showMessage(myActiveVidMode.description); else - showMessage("Zoom", mode.description, mode.zoom, supportedTIAMinZoom(), myTIAMaxZoom); + showMessage("Zoom", myActiveVidMode.description, myActiveVidMode.zoom, + supportedTIAMinZoom(), myTIAMaxZoom); myOSystem.sound().mute(oldMuteState); + // Error check: were the settings applied as requested? if(fullScreen()) myOSystem.settings().setValue("tia.fs_stretch", - mode.stretch == VideoMode::Stretch::Fill); + myActiveVidMode.stretch == VideoModeHandler::Mode::Stretch::Fill); else - myOSystem.settings().setValue("tia.zoom", mode.zoom); + myOSystem.settings().setValue("tia.zoom", myActiveVidMode.zoom); return; } myOSystem.sound().mute(oldMuteState); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const VideoModeHandler::Mode& FrameBuffer::buildVideoMode() +{ + // Update display size, in case windowed/fullscreen mode has changed + const Settings& s = myOSystem.settings(); + if(s.getBool("fullscreen")) + { + Int32 fsIndex = std::max(getCurrentDisplayIndex(), 0); + myVidModeHandler.setDisplaySize(myFullscreenDisplays[fsIndex], fsIndex); + } + else + myVidModeHandler.setDisplaySize(myAbsDesktopSize); + + // And now build the new mode based on current settings + const bool tiaMode = + myOSystem.eventHandler().state() != EventHandlerState::DEBUGGER && + myOSystem.eventHandler().state() != EventHandlerState::LAUNCHER; + + return myVidModeHandler.buildMode(s, tiaMode); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +float FrameBuffer::maxWindowZoom(uInt32 baseWidth, uInt32 baseHeight) const +{ + float multiplier = 1; + for(;;) + { + // Figure out the zoomed size of the window + uInt32 width = baseWidth * multiplier; + uInt32 height = baseHeight * multiplier; + + if((width > myAbsDesktopSize.w) || (height > myAbsDesktopSize.h)) + break; + + multiplier += ZOOM_STEPS; + } + return multiplier > 1 ? multiplier - ZOOM_STEPS : 1; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::setCursorState() { @@ -1234,296 +1289,6 @@ void FrameBuffer::toggleGrabMouse() : "Grab mouse not allowed while cursor shown"); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -float FrameBuffer::maxZoomForScreen(uInt32 baseWidth, uInt32 baseHeight, - uInt32 screenWidth, uInt32 screenHeight) const -{ - float multiplier = 1; - for(;;) - { - // Figure out the zoomed size of the window - uInt32 width = baseWidth * multiplier; - uInt32 height = baseHeight * multiplier; - - if((width > screenWidth) || (height > screenHeight)) - break; - - multiplier += ZOOM_STEPS; - } - return multiplier > 1 ? multiplier - ZOOM_STEPS : 1; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight) -{ - myWindowedModeList.clear(); - - for(auto& mode: myFullscreenModeLists) - mode.clear(); - for(size_t i = myFullscreenModeLists.size(); i < myFullscreenDisplays.size(); ++i) - myFullscreenModeLists.emplace_back(VideoModeList()); - - // Check if zooming is allowed for this state (currently only allowed - // for TIA screens) - EventHandlerState state = myOSystem.eventHandler().state(); - bool tiaMode = (state != EventHandlerState::DEBUGGER && - state != EventHandlerState::LAUNCHER); - float overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0; - - // TIA mode allows zooming at integral factors in windowed modes, - // and also non-integral factors in fullscreen mode - if(tiaMode) - { - // TIA windowed modes - float minZoom = supportedTIAMinZoom(); - myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight, - myAbsDesktopSize.w, myAbsDesktopSize.h); - // Determine all zoom levels - for(float zoom = minZoom; zoom <= myTIAMaxZoom; zoom += ZOOM_STEPS) - { - ostringstream desc; - desc << (zoom * 100) << "%"; - - VideoMode mode(baseWidth*zoom, baseHeight*zoom, baseWidth*zoom, baseHeight*zoom, - VideoMode::Stretch::Fill, 1.0, desc.str(), zoom); - myWindowedModeList.add(mode); - } - - // TIA fullscreen mode - for(uInt32 i = 0; i < myFullscreenDisplays.size(); ++i) - { - myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight, - myFullscreenDisplays[i].w * overscan, - myFullscreenDisplays[i].h * overscan); - - // Add both normal aspect and filled modes - // It's easier to define them both now, and simply switch between - // them when necessary - VideoMode mode1(baseWidth * myTIAMaxZoom, baseHeight * myTIAMaxZoom, - myFullscreenDisplays[i].w, myFullscreenDisplays[i].h, - VideoMode::Stretch::Preserve, overscan, - "Fullscreen: Preserve aspect, no stretch", myTIAMaxZoom, i); - myFullscreenModeLists[i].add(mode1); - VideoMode mode2(baseWidth * myTIAMaxZoom, baseHeight * myTIAMaxZoom, - myFullscreenDisplays[i].w, myFullscreenDisplays[i].h, - VideoMode::Stretch::Fill, overscan, - "Fullscreen: Ignore aspect, full stretch", myTIAMaxZoom, i); - myFullscreenModeLists[i].add(mode2); - } - } - else // UI mode - { - // Windowed and fullscreen mode differ only in screen size - myWindowedModeList.add( - VideoMode(baseWidth, baseHeight, baseWidth, baseHeight, - VideoMode::Stretch::None) - ); - for(uInt32 i = 0; i < myFullscreenDisplays.size(); ++i) - { - myFullscreenModeLists[i].add( - VideoMode(baseWidth, baseHeight, - myFullscreenDisplays[i].w, myFullscreenDisplays[i].h, - VideoMode::Stretch::None, 1.0, "", 1, i) - ); - } - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen) -{ - if(fullscreen) - { - Int32 i = getCurrentDisplayIndex(); - if(i < 0) - { - // default to the first display - i = 0; - } - myCurrentModeList = &myFullscreenModeLists[i]; - } - else - myCurrentModeList = &myWindowedModeList; - - // Now select the best resolution depending on the state - // UI modes (launcher and debugger) have only one supported resolution - // so the 'current' one is the only valid one - EventHandlerState state = myOSystem.eventHandler().state(); - if(state == EventHandlerState::DEBUGGER || state == EventHandlerState::LAUNCHER) - myCurrentModeList->setByZoom(1); - else // TIA mode - { - if(fullscreen) - myCurrentModeList->setByStretch(myOSystem.settings().getBool("tia.fs_stretch") - ? VideoMode::Stretch::Fill : VideoMode::Stretch::Preserve); - else - myCurrentModeList->setByZoom(myOSystem.settings().getFloat("tia.zoom")); - } - - return myCurrentModeList->current(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// -// VideoMode implementation -// -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, - Stretch smode, float overscan, const string& desc, - float zoomLevel, Int32 fsindex) - : stretch(smode), - description(desc), - zoom(zoomLevel), - fsIndex(fsindex) -{ - // First set default size and positioning - sw = std::max(sw, TIAConstants::viewableWidth); - sh = std::max(sh, TIAConstants::viewableHeight); - iw = std::min(iw, sw); - ih = std::min(ih, sh); - int ix = (sw - iw) >> 1; - int iy = (sh - ih) >> 1; - image = Common::Rect(ix, iy, ix+iw, iy+ih); - screen = Common::Size(sw, sh); - - // Now resize based on windowed/fullscreen mode and stretch factor - iw = image.w(); - ih = image.h(); - - if(fsIndex != -1) - { - switch(stretch) - { - case Stretch::Preserve: - { - float stretchFactor = 1.0; - float scaleX = float(iw) / screen.w; - float scaleY = float(ih) / screen.h; - - // Scale to all available space, keep aspect correct - if(scaleX > scaleY) - stretchFactor = float(screen.w) / iw; - else - stretchFactor = float(screen.h) / ih; - - iw = uInt32(stretchFactor * iw) * overscan; - ih = uInt32(stretchFactor * ih) * overscan; - break; - } - - case Stretch::Fill: - // Scale to all available space - iw = screen.w * overscan; - ih = screen.h * overscan; - break; - - case Stretch::None: - // Don't do any scaling at all, but obey overscan - iw = std::min(iw, screen.w) * overscan; - ih = std::min(ih, screen.h) * overscan; - break; - } - } - else - { - // In windowed mode, currently the size is scaled to the screen - // TODO - this may be updated if/when we allow variable-sized windows - switch(stretch) - { - case Stretch::Preserve: - case Stretch::Fill: - screen.w = iw; - screen.h = ih; - break; - case Stretch::None: - break; // Do not change image or screen rects whatsoever - } - } - - // Now re-calculate the dimensions - iw = std::min(iw, screen.w); - ih = std::min(ih, screen.h); - - image.moveTo((screen.w - iw) >> 1, (screen.h - ih) >> 1); - image.setWidth(iw); - image.setHeight(ih); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// -// VideoModeList implementation -// -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::VideoModeList::add(const VideoMode& mode) -{ - myModeList.emplace_back(mode); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::VideoModeList::clear() -{ - myModeList.clear(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FrameBuffer::VideoModeList::empty() const -{ - return myModeList.empty(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 FrameBuffer::VideoModeList::size() const -{ - return uInt32(myModeList.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::VideoModeList::previous() -{ - --myIdx; - if(myIdx < 0) myIdx = int(myModeList.size()) - 1; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const FrameBuffer::VideoMode& FrameBuffer::VideoModeList::current() const -{ - return myModeList[myIdx]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::VideoModeList::next() -{ - myIdx = (myIdx + 1) % myModeList.size(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::VideoModeList::setByZoom(float zoom) -{ - for(uInt32 i = 0; i < myModeList.size(); ++i) - { - if(myModeList[i].zoom == zoom) - { - myIdx = i; - return; - } - } - myIdx = 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::VideoModeList::setByStretch(FrameBuffer::VideoMode::Stretch stretch) -{ - for(uInt32 i = 0; i < myModeList.size(); ++i) - { - if(myModeList[i].stretch == stretch) - { - myIdx = i; - return; - } - } - myIdx = 0; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Palette is defined as follows: diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 58d61dfd3..ce9040795 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -35,6 +35,7 @@ class TIASurface; #include "TIAConstants.hxx" #include "FrameBufferConstants.hxx" #include "EventHandlerConstants.hxx" +#include "VideoModeHandler.hxx" #include "bspf.hxx" /** @@ -50,38 +51,7 @@ class TIASurface; class FrameBuffer { public: - // Contains all relevant info for the dimensions of a video screen - // Also takes care of the case when the image should be 'centered' - // within the given screen: - // 'image' is the image dimensions into the screen - // 'screen' are the dimensions of the screen itself - struct VideoMode - { - enum class Stretch { Preserve, Fill, None }; - - Common::Rect image; - Common::Size screen; - Stretch stretch{VideoMode::Stretch::None}; - string description; - float zoom{1.F}; - Int32 fsIndex{-1}; - - VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, - Stretch smode, float overscan = 1.F, - const string& desc = "", float zoomLevel = 1, Int32 fsindex = -1); - - friend ostream& operator<<(ostream& os, const VideoMode& vm) - { - os << "image=" << vm.image << " screen=" << vm.screen - << " stretch=" << (vm.stretch == Stretch::Preserve ? "preserve" : - vm.stretch == Stretch::Fill ? "fill" : "none") - << " desc=" << vm.description << " zoom=" << vm.zoom - << " fsIndex= " << vm.fsIndex; - return os; - } - }; - - struct DisplayMode + struct DisplayMode // FIXME - is this needed? { uInt32 display; Common::Size size; @@ -259,11 +229,6 @@ class FrameBuffer */ TIASurface& tiaSurface() const { return *myTIASurface; } - /** - Enables/disables fullscreen mode. - */ - void setFullscreen(bool enable); - /** Toggles between fullscreen and window mode. */ @@ -285,15 +250,15 @@ class FrameBuffer /** This method is called when the user wants to switch to the next - available video mode. In windowed mode, this typically means going to - the next/previous zoom level. In fullscreen mode, this typically means - switching between normal aspect and fully filling the screen. + available TIA video mode. In windowed mode, this typically means going + to the next/previous zoom level. In fullscreen mode, this typically + means switching between normal aspect and fully filling the screen. direction = -1 means go to the next lower video mode direction = +1 means go to the next higher video mode @param direction +1 indicates increase, -1 indicates decrease. */ - void selectVidMode(int direction = +1); + void switchVideoMode(int direction = +1); /** Sets the state of the cursor (hidden or grabbed) based on the @@ -453,7 +418,6 @@ class FrameBuffer virtual int scaleY(int y) const { return y; } protected: - /** This method is called to query and initialize the video hardware for desktop and fullscreen resolution information. Since several @@ -475,8 +439,8 @@ class FrameBuffer @return False on any errors, else true */ - virtual bool setVideoMode(const string& title, - const FrameBuffer::VideoMode& mode) = 0; + virtual bool activateVideoMode(const string& title, + const VideoModeHandler::Mode& mode) = 0; /** This method is called to create a surface with the given attributes. @@ -547,6 +511,28 @@ class FrameBuffer */ bool drawMessage(); + // Draws the frame stats overlay + void drawFrameStats(float framesPerSecond); + + /** + Build an applicable video mode based on the current settings in + effect, whether TIA mode is active, etc. + Note that this only creates the video mode definition itself; + to apply it, we need to call 'activateVideoMode()'. + */ + const VideoModeHandler::Mode& buildVideoMode(); + + /** + Calculate the maximum level by which the base window can be zoomed and + still fit in the desktop screen. + */ + float maxWindowZoom(uInt32 baseWidth, uInt32 baseHeight) const; + + /** + Enables/disables fullscreen mode. + */ + void setFullscreen(bool enable); + /** Frees and reloads all surfaces that the framebuffer knows about. */ @@ -559,60 +545,6 @@ class FrameBuffer void setupFonts(); #endif - /** - Calculate the maximum level by which the base window can be zoomed and - still fit in the given screen dimensions. - */ - float maxZoomForScreen(uInt32 baseWidth, uInt32 baseHeight, - uInt32 screenWidth, uInt32 screenHeight) const; - - /** - Set all possible video modes (both windowed and fullscreen) available for - this framebuffer based on given image dimensions and maximum window size. - */ - void setAvailableVidModes(uInt32 basewidth, uInt32 baseheight); - - /** - Returns an appropriate video mode based on the current eventhandler - state, taking into account the maximum size of the window. - - @param fullscreen Whether to use a windowed or fullscreen mode - @return A valid VideoMode for this framebuffer - */ - const FrameBuffer::VideoMode& getSavedVidMode(bool fullscreen); - - private: - /** - This class implements an iterator around an array of VideoMode objects. - */ - class VideoModeList - { - public: - void add(const FrameBuffer::VideoMode& mode); - void clear(); - - bool empty() const; - uInt32 size() const; - - void previous(); - const FrameBuffer::VideoMode& current() const; - void next(); - - void setByZoom(float zoom); - void setByStretch(FrameBuffer::VideoMode::Stretch stretch); - - friend ostream& operator<<(ostream& os, const VideoModeList& l) - { - for(const auto& vm: l.myModeList) - os << "-----\n" << vm << endl << "-----\n"; - return os; - } - - private: - vector myModeList; - int myIdx{-1}; - }; - protected: // Title of the main window/screen string myScreenTitle; @@ -629,9 +561,6 @@ class FrameBuffer vector myFullscreenDisplays; private: - // Draws the frame stats overlay - void drawFrameStats(float framesPerSecond); - // Indicates the number of times the framebuffer was initialized uInt32 myInitializedCount{0}; @@ -659,6 +588,10 @@ class FrameBuffer // Supported renderers VariantList myRenderers; + // The VideoModeHandler class takes responsibility for all video mode functionality + VideoModeHandler myVidModeHandler; + VideoModeHandler::Mode myActiveVidMode; + #ifdef GUI_SUPPORT // The font object to use for the normal in-game GUI unique_ptr myFont; @@ -699,11 +632,6 @@ class FrameBuffer bool myHiDPIAllowed{false}; bool myHiDPIEnabled{false}; - // The list of all available video modes for this framebuffer - VideoModeList* myCurrentModeList{nullptr}; - VideoModeList myWindowedModeList; - vector myFullscreenModeLists; - // Minimum TIA zoom level that can be used for this framebuffer float myTIAMinZoom{2.F}; // Maximum TIA zoom level that can be used for this framebuffer @@ -714,7 +642,7 @@ class FrameBuffer FullPaletteArray myFullPalette; // Holds UI palette data (for each variation) - static UIPaletteArray ourStandardUIPalette, ourClassicUIPalette, + static UIPaletteArray ourStandardUIPalette, ourClassicUIPalette, ourLightUIPalette, ourDarkUIPalette; private: diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx index 2a2cd0327..f3f4018d1 100644 --- a/src/emucore/TIASurface.cxx +++ b/src/emucore/TIASurface.cxx @@ -91,7 +91,7 @@ TIASurface::~TIASurface() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TIASurface::initialize(const Console& console, - const FrameBuffer::VideoMode& mode) + const VideoModeHandler::Mode& mode) { myTIA = &(console.tia()); diff --git a/src/emucore/TIASurface.hxx b/src/emucore/TIASurface.hxx index dd38b2de5..4c7a710d8 100644 --- a/src/emucore/TIASurface.hxx +++ b/src/emucore/TIASurface.hxx @@ -54,7 +54,7 @@ class TIASurface /** Set the TIA object, which is needed for actually rendering the TIA image. */ - void initialize(const Console& console, const FrameBuffer::VideoMode& mode); + void initialize(const Console& console, const VideoModeHandler::Mode& mode); /** Set the palette for TIA rendering. This currently consists of two diff --git a/src/libretro/FrameBufferLIBRETRO.hxx b/src/libretro/FrameBufferLIBRETRO.hxx index a57a218d2..8d097a25e 100644 --- a/src/libretro/FrameBufferLIBRETRO.hxx +++ b/src/libretro/FrameBufferLIBRETRO.hxx @@ -147,7 +147,8 @@ class FrameBufferLIBRETRO : public FrameBuffer @return False on any errors, else true */ - bool setVideoMode(const string& title, const VideoMode& mode) override { return true; } + bool activateVideoMode(const string& title, + const VideoModeHandler::Mode& mode) override { return true; } /** This method is called to create a surface with the given attributes. diff --git a/src/libretro/Makefile.common b/src/libretro/Makefile.common index 8f2bbf81a..ba98f0825 100644 --- a/src/libretro/Makefile.common +++ b/src/libretro/Makefile.common @@ -33,6 +33,7 @@ SOURCES_CXX := \ $(CORE_DIR)/common/StaggeredLogger.cxx \ $(CORE_DIR)/common/StateManager.cxx \ $(CORE_DIR)/common/TimerManager.cxx \ + $(CORE_DIR)/common/VideoModeHandler.cxx \ $(CORE_DIR)/common/tv_filters/AtariNTSC.cxx \ $(CORE_DIR)/common/tv_filters/NTSCFilter.cxx \ $(CORE_DIR)/emucore/AtariVox.cxx \ From 8333a805ba171db974f678b0c04a9c5150a26ed3 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 13 Oct 2020 10:53:39 -0230 Subject: [PATCH 079/263] Updated VS project for VideoModeHandler class. --- src/windows/Stella.vcxproj | 2 ++ src/windows/Stella.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 5d3085e71..5d7bef977 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -520,6 +520,7 @@ + true @@ -1542,6 +1543,7 @@ + true diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 2431ba04f..81d029742 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1026,6 +1026,9 @@ Source Files\debugger + + Source Files + @@ -2108,6 +2111,9 @@ Header Files\debugger + + Header Files + From 0b62b0112621e96e02acfad22e6be21223c076fb Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 13 Oct 2020 11:03:02 -0230 Subject: [PATCH 080/263] Updated Xcode for VideoModeHandler class. --- src/macos/stella.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index cfff52861..ded749874 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -517,6 +517,8 @@ DCB20EC71A0C506C0048F595 /* main.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB20EC61A0C506C0048F595 /* main.cxx */; }; DCB2ECAF1F0AECA3009738A6 /* CartDetector.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB2ECAC1F0AECA3009738A6 /* CartDetector.cxx */; }; DCB2ECB01F0AECA3009738A6 /* CartDetector.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB2ECAD1F0AECA3009738A6 /* CartDetector.hxx */; }; + DCB60AC92535E30600A5C1D2 /* VideoModeHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB60AC72535E30500A5C1D2 /* VideoModeHandler.cxx */; }; + DCB60ACA2535E30600A5C1D2 /* VideoModeHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB60AC82535E30600A5C1D2 /* VideoModeHandler.hxx */; }; DCB87E581A104C1E00BF2A3B /* MediaFactory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB87E571A104C1E00BF2A3B /* MediaFactory.hxx */; }; DCBD31E82299ADB400567357 /* KeyMap.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBD31E52299ADB400567357 /* KeyMap.hxx */; }; DCBD31E92299ADB400567357 /* Rect.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBD31E62299ADB400567357 /* Rect.hxx */; }; @@ -1277,6 +1279,8 @@ DCB20EC61A0C506C0048F595 /* main.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cxx; sourceTree = ""; }; DCB2ECAC1F0AECA3009738A6 /* CartDetector.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartDetector.cxx; sourceTree = ""; }; DCB2ECAD1F0AECA3009738A6 /* CartDetector.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartDetector.hxx; sourceTree = ""; }; + DCB60AC72535E30500A5C1D2 /* VideoModeHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoModeHandler.cxx; sourceTree = ""; }; + DCB60AC82535E30600A5C1D2 /* VideoModeHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = VideoModeHandler.hxx; sourceTree = ""; }; DCB87E571A104C1E00BF2A3B /* MediaFactory.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MediaFactory.hxx; sourceTree = ""; }; DCBA710010DED62E0077193B /* Stella.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stella.app; sourceTree = BUILT_PRODUCTS_DIR; }; DCBD31E52299ADB400567357 /* KeyMap.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KeyMap.hxx; sourceTree = ""; }; @@ -1817,6 +1821,8 @@ DC7A24D4173B1CF600B20FE9 /* Variant.hxx */, DCF490791A0ECE5B00A67AA9 /* Vec.hxx */, DCF467BC0F9399F500B25D7A /* Version.hxx */, + DCB60AC72535E30500A5C1D2 /* VideoModeHandler.cxx */, + DCB60AC82535E30600A5C1D2 /* VideoModeHandler.hxx */, DCE395ED16CB0B5F008DB1E5 /* ZipHandler.cxx */, DCE395EE16CB0B5F008DB1E5 /* ZipHandler.hxx */, ); @@ -2694,6 +2700,7 @@ DCAAE5D41715887B0080BB82 /* Cart2KWidget.hxx in Headers */, DCF7F129223D796000701A47 /* ProfilingRunner.hxx in Headers */, DCAAE5D61715887B0080BB82 /* Cart3FWidget.hxx in Headers */, + DCB60ACA2535E30600A5C1D2 /* VideoModeHandler.hxx in Headers */, DCAAE5D81715887B0080BB82 /* Cart4KWidget.hxx in Headers */, DCAAE5DA1715887B0080BB82 /* Cart0840Widget.hxx in Headers */, DCAAE5DC1715887B0080BB82 /* CartCVWidget.hxx in Headers */, @@ -2910,6 +2917,7 @@ 2D91748C09BA90380026E9FF /* Driving.cxx in Sources */, E0306E101F93E916003DDD52 /* FrameLayoutDetector.cxx in Sources */, 2D91748E09BA90380026E9FF /* Joystick.cxx in Sources */, + DCB60AC92535E30600A5C1D2 /* VideoModeHandler.cxx in Sources */, 2D91748F09BA90380026E9FF /* Keyboard.cxx in Sources */, 2D91749009BA90380026E9FF /* M6532.cxx in Sources */, 2D91749109BA90380026E9FF /* MD5.cxx in Sources */, From 951e72242c4f5c3aecf2d1011bb31214c5ed4cd4 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 13 Oct 2020 12:33:56 -0230 Subject: [PATCH 081/263] Updated changelog for aspect correction/pixel-exact snapshots. --- Changes.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Changes.txt b/Changes.txt index 76d711721..abb9c4ea8 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,9 +12,14 @@ Release History =========================================================================== -6.3 to 6.4 (XXXX XX, 202X) +6.3 to 6.4 (XXXX XX, 2020) - * Added basic (entire and single line only) text cut/copy and paste + * Added basic (entire and single line only) text cut/copy and paste. + + * Fixed bug with aspect correction and fullscreen mode; snapshots from + such a mode are now pixel-exact. + +-Have fun! 6.2.1 to 6.3 (October 7, 2020) @@ -70,8 +75,6 @@ * Fixed bug when taking fullscreen snapshots; the dimensions were sometimes cut off. --Have fun! - 6.2.1 to 6.2.2 (August 25, 2020) From ed75c68be85dc3a76f2ecd547f28264a2400181a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 13 Oct 2020 21:26:05 -0230 Subject: [PATCH 082/263] A few more cleanups relating to Common::Size vs. separate components. --- src/common/Rect.hxx | 11 ++++++++--- src/debugger/Debugger.cxx | 18 ++++++++---------- src/debugger/Debugger.hxx | 5 +++-- src/emucore/Console.cxx | 13 ++----------- src/emucore/FrameBuffer.cxx | 15 +++++++-------- src/emucore/FrameBuffer.hxx | 6 ++---- src/gui/Launcher.cxx | 25 +++++++++++-------------- src/gui/Launcher.hxx | 6 +++--- 8 files changed, 44 insertions(+), 55 deletions(-) diff --git a/src/common/Rect.hxx b/src/common/Rect.hxx index 5243740f2..faf6677b6 100644 --- a/src/common/Rect.hxx +++ b/src/common/Rect.hxx @@ -69,12 +69,17 @@ struct Size } bool valid() const { return w > 0 && h > 0; } + void clamp(uInt32 lower_w, uInt32 upper_w, uInt32 lower_h, uInt32 upper_h) { + w = BSPF::clamp(w, lower_w, upper_w); + h = BSPF::clamp(h, lower_h, upper_h); + } + bool operator==(const Size& s) const { return w == s.w && h == s.h; } bool operator!=(const Size& s) const { return w != s.w || h != s.h; } - bool operator<(const Size& s) const { return w < s.w && h < s.h; } + bool operator<(const Size& s) const { return w < s.w && h < s.h; } bool operator<=(const Size& s) const { return w <= s.w && h <= s.h; } - bool operator>(const Size& s) const { return w > s.w && h > s.h; } - bool operator>=(const Size& s) const { return w >= s.w && h >= s.h; } + bool operator>(const Size& s) const { return w > s.w || h > s.h; } + bool operator>=(const Size& s) const { return w >= s.w || h >= s.h; } friend ostream& operator<<(ostream& os, const Size& s) { os << s.w << "x" << s.h; diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index c15c35eac..0a4846c76 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -90,21 +90,18 @@ Debugger::~Debugger() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::initialize() { - const Common::Size& s = myOSystem.settings().getSize("dbg.res"); + mySize = myOSystem.settings().getSize("dbg.res"); const Common::Size& d = myOSystem.frameBuffer().desktopSize(); - myWidth = s.w; myHeight = s.h; // The debugger dialog is resizable, within certain bounds // We check those bounds now - myWidth = std::max(myWidth, uInt32(DebuggerDialog::kSmallFontMinW)); - myHeight = std::max(myHeight, uInt32(DebuggerDialog::kSmallFontMinH)); - myWidth = std::min(myWidth, uInt32(d.w)); - myHeight = std::min(myHeight, uInt32(d.h)); + mySize.clamp(uInt32(DebuggerDialog::kSmallFontMinW), d.w, + uInt32(DebuggerDialog::kSmallFontMinH), d.h); - myOSystem.settings().setValue("dbg.res", Common::Size(myWidth, myHeight)); + myOSystem.settings().setValue("dbg.res", mySize); delete myDialog; myDialog = nullptr; - myDialog = new DebuggerDialog(myOSystem, *this, 0, 0, myWidth, myHeight); + myDialog = new DebuggerDialog(myOSystem, *this, 0, 0, mySize.w, mySize.h); myCartDebug->setDebugWidget(&(myDialog->cartDebug())); @@ -115,8 +112,9 @@ void Debugger::initialize() FBInitStatus Debugger::initializeVideo() { string title = string("Stella ") + STELLA_VERSION + ": Debugger mode"; - return myOSystem.frameBuffer().createDisplay(title, FrameBuffer::BufferType::Debugger, - myWidth, myHeight); + return myOSystem.frameBuffer().createDisplay( + title, FrameBuffer::BufferType::Debugger, mySize + ); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 91abdd879..e7096cd4d 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -44,6 +44,7 @@ class RewindManager; #include #include "Base.hxx" +#include "Rect.hxx" #include "DialogContainer.hxx" #include "DebuggerDialog.hxx" #include "FrameBufferConstants.hxx" @@ -352,8 +353,8 @@ class Debugger : public DialogContainer FunctionDefMap myFunctionDefs; // Dimensions of the entire debugger window - uInt32 myWidth{DebuggerDialog::kSmallFontMinW}; - uInt32 myHeight{DebuggerDialog::kSmallFontMinH}; + Common::Size mySize{DebuggerDialog::kSmallFontMinW, + DebuggerDialog::kSmallFontMinH}; // Various builtin functions and operations struct BuiltinFunction { diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 2d4f0f5a6..f12592428 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -626,20 +626,11 @@ FBInitStatus Console::initializeVideo(bool full) Common::Size(TIAConstants::viewableWidth, TIAConstants::viewableHeight) : Common::Size(2 * myTIA->width(), myTIA->height()); - uInt32 width, height; - if (!myOSystem.settings().getBool("tia.correct_aspect")) { - width = 2 * myTIA->width(); - height = myTIA->height(); - } else { - width = TIAConstants::viewableWidth; - height = TIAConstants::viewableHeight; - } - bool devSettings = myOSystem.settings().getBool("dev.settings"); const string& title = string("Stella ") + STELLA_VERSION + ": \"" + myProperties.get(PropType::Cart_Name) + "\""; - fbstatus = myOSystem.frameBuffer().createDisplay(title, FrameBuffer::BufferType::Emulator, - width, height, false); + fbstatus = myOSystem.frameBuffer().createDisplay(title, + FrameBuffer::BufferType::Emulator, size, false); if(fbstatus != FBInitStatus::Success) return fbstatus; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 420826bf3..66fe8196a 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -207,8 +207,7 @@ FontDesc FrameBuffer::getFontDesc(const string& name) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, - uInt32 width, uInt32 height, - bool honourHiDPI) + Common::Size size, bool honourHiDPI) { // always save, maybe only the mode of the window has changed saveCurrentWindowPosition(); @@ -220,8 +219,8 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, // In HiDPI mode, all created displays must be scaled appropriately if(honourHiDPI && hidpiEnabled()) { - width *= hidpiScaleFactor(); - height *= hidpiScaleFactor(); + size.w *= hidpiScaleFactor(); + size.h *= hidpiScaleFactor(); } // A 'windowed' system is defined as one where the window size can be @@ -240,24 +239,24 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, // can be relaxed // Otherwise, we treat the system as if WINDOWED_SUPPORT is not defined if(myDesktopSize.w < FBMinimum::Width && myDesktopSize.h < FBMinimum::Height && - (myDesktopSize.w < width || myDesktopSize.h < height)) + size > myDesktopSize) return FBInitStatus::FailTooLarge; #else // Make sure this mode is even possible // We only really need to worry about it in non-windowed environments, // where requesting a window that's too large will probably cause a crash - if(myDesktopSize.w < width || myDesktopSize.h < height) + if(size > myDesktopSize) return FBInitStatus::FailTooLarge; #endif // Initialize video mode handler, so it can know what video modes are // appropriate for this framebuffer - myVidModeHandler.setImageSize(Common::Size(width, height)); + myVidModeHandler.setImageSize(size); // Initialize video subsystem (make sure we get a valid mode) string pre_about = about(); myActiveVidMode = buildVideoMode(); - if(width <= myActiveVidMode.screen.w && height <= myActiveVidMode.screen.h) + if(size <= myActiveVidMode.screen) { // Changing the video mode can take some time, during which the last // sound played may get 'stuck' diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index ce9040795..a2d55fe25 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -91,8 +91,7 @@ class FrameBuffer calls are made to derived methods. @param title The title of the application / window - @param width The width of the framebuffer - @param height The height of the framebuffer + @param size The dimensions of the display @param honourHiDPI If true, consult the 'hidpi' setting and enlarge the display size accordingly; if false, use the exact dimensions as given @@ -100,8 +99,7 @@ class FrameBuffer @return Status of initialization (see FBInitStatus 'enum') */ FBInitStatus createDisplay(const string& title, BufferType type, - uInt32 width, uInt32 height, - bool honourHiDPI = true); + Common::Size size, bool honourHiDPI = true); /** Updates the display, which depending on the current mode could mean diff --git a/src/gui/Launcher.cxx b/src/gui/Launcher.cxx index 315a14f41..6c88cd384 100644 --- a/src/gui/Launcher.cxx +++ b/src/gui/Launcher.cxx @@ -29,24 +29,20 @@ Launcher::Launcher(OSystem& osystem) : DialogContainer(osystem) { - const Common::Size& s = myOSystem.settings().getSize("launcherres"); + mySize = myOSystem.settings().getSize("launcherres"); const Common::Size& d = myOSystem.frameBuffer().desktopSize(); double overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0; - myWidth = s.w; myHeight = s.h; // The launcher dialog is resizable, within certain bounds // We check those bounds now - myWidth = std::max(myWidth, FBMinimum::Width); - myHeight = std::max(myHeight, FBMinimum::Height); - myWidth = std::min(myWidth, d.w); - myHeight = std::min(myHeight, d.h); - // do not include overscan when launcher saving size - myOSystem.settings().setValue("launcherres", Common::Size(myWidth, myHeight)); - // now make overscan effective - myWidth = std::min(myWidth, uInt32(d.w * overscan)); - myHeight = std::min(myHeight, uInt32(d.h * overscan)); + mySize.clamp(FBMinimum::Width, d.w, FBMinimum::Height, d.h); + // Do not include overscan when launcher saving size + myOSystem.settings().setValue("launcherres", mySize); + // Now make overscan effective + mySize.w = std::min(mySize.w, uInt32(d.w * overscan)); + mySize.h = std::min(mySize.h, uInt32(d.h * overscan)); - myBaseDialog = new LauncherDialog(myOSystem, *this, 0, 0, myWidth, myHeight); + myBaseDialog = new LauncherDialog(myOSystem, *this, 0, 0, mySize.w, mySize.h); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -59,8 +55,9 @@ Launcher::~Launcher() FBInitStatus Launcher::initializeVideo() { string title = string("Stella ") + STELLA_VERSION; - return myOSystem.frameBuffer().createDisplay(title, FrameBuffer::BufferType::Launcher, - myWidth, myHeight); + return myOSystem.frameBuffer().createDisplay( + title, FrameBuffer::BufferType::Launcher, mySize + ); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Launcher.hxx b/src/gui/Launcher.hxx index 4148db945..9f5cecaa4 100644 --- a/src/gui/Launcher.hxx +++ b/src/gui/Launcher.hxx @@ -22,6 +22,7 @@ class Properties; class OSystem; class FilesystemNode; +#include "Rect.hxx" #include "FrameBufferConstants.hxx" #include "DialogContainer.hxx" @@ -72,9 +73,8 @@ class Launcher : public DialogContainer private: Dialog* myBaseDialog{nullptr}; - // The width and height of this dialog - uInt32 myWidth{0}; - uInt32 myHeight{0}; + // The dimensions of this dialog + Common::Size mySize; private: // Following constructors and assignment operators not supported From d5d4955b125213be20ff6653be45893901103528 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 13 Oct 2020 21:27:22 -0230 Subject: [PATCH 083/263] Eliminate dead code. --- src/emucore/FrameBuffer.hxx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index a2d55fe25..ebc765c79 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -51,13 +51,6 @@ class TIASurface; class FrameBuffer { public: - struct DisplayMode // FIXME - is this needed? - { - uInt32 display; - Common::Size size; - uInt32 refresh_rate; - }; - enum class BufferType { None, Launcher, From 51416dd883afd203fa2c51b74697796d81c5cfe7 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 15 Oct 2020 08:30:50 +0200 Subject: [PATCH 084/263] updated debugger doc --- docs/debugger.html | 12 ++++++++++-- docs/graphics/debugger_bankcomplex.png | Bin 7177 -> 6084 bytes docs/graphics/debugger_banksimple.png | Bin 2887 -> 2101 bytes docs/graphics/debugger_iotab.png | Bin 5333 -> 5128 bytes docs/graphics/debugger_ram-dpc.png | Bin 9779 -> 8294 bytes docs/graphics/debugger_ram-f8sc.png | Bin 5036 -> 3590 bytes docs/graphics/debugger_ramsearch.png | Bin 3896 -> 2717 bytes src/debugger/gui/RamWidget.cxx | 8 ++++---- src/debugger/gui/RiotWidget.cxx | 8 ++++---- 9 files changed, 18 insertions(+), 10 deletions(-) diff --git a/docs/debugger.html b/docs/debugger.html index 4c0360a95..badd778cf 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -227,6 +227,14 @@ tabs from left-to-right, Shift + Control/Cmd + Tab cycles right-to-left. Pressing Tab (or Shift + Tab) cycles between widgets in the current tab (except for in the Prompt Tab, where 'tab' is used for something else).

    +

    Note for the GUI display: +

      +
    • Hexadecimal values are either not prefixed or with '$'.
    • +
    • Decimal values are prefixed with '#'.
    • +
    • Binary values are prefixed with '%'.
    • +
    +

    +

    You can also enter the debugger at emulator startup by use the 'debug' command on the command line, or alternatively within the ROM launcher in 'Power-on options': @@ -1135,7 +1143,7 @@ as illustrated:


    (F) TIA Information

    -

    To the right of the TIA Display area, TIA information is displayed:

    +

    To the right of the TIA Display area, TIA information is displayed (all values are decimal):

    The indicators are as follows (note that all these are read-only):

    Save continuous PNG snapshots
    (per interval defined in Snapshot Settings)
    Alt + sCmd + sControl-Alt + sControl-Cmd + s
    Save continuous PNG snapshots (every frame)Shift-Alt + sShift-Cmd + sShift-Control-Alt + sShift-Control-Cmd + s
    Set the palette to either normal Stella, the one used in the z26 emulator, a user-defined palette, or a custom palette generated - from user-defined phase shifts.
    Adjust phase shift of 'custom' PAL palette.
    -pal.red_scale <number>
    Adjust red scale of 'custom' palette (range -1.0 to 1.0).
    -pal.red_shift <number>
    Adjust red shift of 'custom' palette (range -22.5 to 22.5).
    -pal.green_scale <number>
    Adjust green scale of 'custom' palette (range -1.0 to 1.0).
    -pal.green_shift <number>
    Adjust green shift of 'custom' palette (range -22.5 to 22.5).
    -pal.blue_scale <number>
    Adjust blue scale of 'custom' palette (range -1.0 to 1.0).
    -pal.blue_shift <number>
    Adjust blue shift of 'custom' palette (range -22.5 to 22.5).
    -pal.hue <number>
    Adjust hue of current palette (range -1.0 to 1.0).
    - - + + + + + diff --git a/src/common/PaletteHandler.cxx b/src/common/PaletteHandler.cxx index 030ff4d9e..db6961af8 100644 --- a/src/common/PaletteHandler.cxx +++ b/src/common/PaletteHandler.cxx @@ -74,14 +74,38 @@ void PaletteHandler::cyclePalette(int direction) setPalette(palette); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool PaletteHandler::isCustomAdjustable() const +{ + return myCurrentAdjustable >= CUSTOM_START + && myCurrentAdjustable <= CUSTOM_END; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool PaletteHandler::isPhaseShift() const +{ + return myCurrentAdjustable == PHASE_SHIFT; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool PaletteHandler::isRGBScale() const +{ + return myCurrentAdjustable >= RED_SCALE && myCurrentAdjustable <= BLUE_SCALE; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool PaletteHandler::isRGBShift() const +{ + return myCurrentAdjustable >= RED_SHIFT && myCurrentAdjustable <= BLUE_SHIFT; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PaletteHandler::showAdjustableMessage() { - const bool isPhaseShift = myAdjustables[myCurrentAdjustable].value == nullptr; ostringstream msg, buf; msg << "Palette " << myAdjustables[myCurrentAdjustable].name; - if(isPhaseShift) + if(isPhaseShift()) { const ConsoleTiming timing = myOSystem.console().timing(); const bool isNTSC = timing == ConsoleTiming::ntsc; @@ -90,12 +114,22 @@ void PaletteHandler::showAdjustableMessage() buf << std::fixed << std::setprecision(1) << value << DEGREE; myOSystem.frameBuffer().showMessage( "Palette phase shift", buf.str(), value, - (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) - MAX_SHIFT, - (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) + MAX_SHIFT); + (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) - MAX_PHASE_SHIFT, + (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) + MAX_PHASE_SHIFT); + } + else if(isRGBShift()) + { + const float value = *myAdjustables[myCurrentAdjustable].value; + + buf << std::fixed << std::setprecision(1) << value << DEGREE; + myOSystem.frameBuffer().showMessage( + msg.str(), buf.str(), value, -MAX_RGB_SHIFT, +MAX_RGB_SHIFT); } else { - const int value = scaleTo100(*myAdjustables[myCurrentAdjustable].value); + const int value = isRGBScale() + ? scaleRGBTo100(*myAdjustables[myCurrentAdjustable].value) + : scaleTo100(*myAdjustables[myCurrentAdjustable].value); buf << value << "%"; myOSystem.frameBuffer().showMessage( msg.str(), buf.str(), value); @@ -106,15 +140,15 @@ void PaletteHandler::showAdjustableMessage() void PaletteHandler::cycleAdjustable(int direction) { const bool isCustomPalette = SETTING_CUSTOM == myOSystem.settings().getString("palette"); - bool isPhaseShift; + bool isCustomAdj; do { myCurrentAdjustable = BSPF::clampw(int(myCurrentAdjustable + direction), 0, NUM_ADJUSTABLES - 1); - isPhaseShift = myAdjustables[myCurrentAdjustable].value == nullptr; + isCustomAdj = isCustomAdjustable(); // skip phase shift when 'Custom' palette is not selected - if(!direction && isPhaseShift && !isCustomPalette) + if(!direction && isCustomAdj && !isCustomPalette) myCurrentAdjustable++; - } while(isPhaseShift && !isCustomPalette); + } while(isCustomAdj && !isCustomPalette); showAdjustableMessage(); } @@ -122,29 +156,38 @@ void PaletteHandler::cycleAdjustable(int direction) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PaletteHandler::changeAdjustable(int adjustable, int direction) { - const bool isCustomPalette = SETTING_CUSTOM == myOSystem.settings().getString("palette"); - const bool isPhaseShift = myAdjustables[adjustable].value == nullptr; - myCurrentAdjustable = adjustable; - if(isPhaseShift && !isCustomPalette) - myCurrentAdjustable++; - changeCurrentAdjustable(direction); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PaletteHandler::changeCurrentAdjustable(int direction) { - if(myAdjustables[myCurrentAdjustable].value == nullptr) + if(isPhaseShift()) changeColorPhaseShift(direction); else { - int newVal = scaleTo100(*myAdjustables[myCurrentAdjustable].value); + if(isRGBScale()) + { + int newVal = scaleRGBTo100(*myAdjustables[myCurrentAdjustable].value); - newVal = BSPF::clamp(newVal + direction * 1, 0, 100); + newVal = BSPF::clamp(newVal + direction * 1, 0, 100); + *myAdjustables[myCurrentAdjustable].value = scaleRGBFrom100(newVal); + } + else if(isRGBShift()) + { + float newShift = *myAdjustables[myCurrentAdjustable].value; - *myAdjustables[myCurrentAdjustable].value = scaleFrom100(newVal); + newShift = BSPF::clamp(newShift + direction * 0.5F, -MAX_RGB_SHIFT, MAX_RGB_SHIFT); + *myAdjustables[myCurrentAdjustable].value = newShift; + } + else + { + int newVal = scaleTo100(*myAdjustables[myCurrentAdjustable].value); + newVal = BSPF::clamp(newVal + direction * 1, 0, 100); + *myAdjustables[myCurrentAdjustable].value = scaleFrom100(newVal); + } showAdjustableMessage(); setPalette(); } @@ -162,7 +205,7 @@ void PaletteHandler::changeColorPhaseShift(int direction) const float shift = isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT; float newPhase = isNTSC ? myPhaseNTSC : myPhasePAL; - newPhase = BSPF::clamp(newPhase + direction * 0.3F, shift - MAX_SHIFT, shift + MAX_SHIFT); + newPhase = BSPF::clamp(newPhase + direction * 0.3F, shift - MAX_PHASE_SHIFT, shift + MAX_PHASE_SHIFT); if(isNTSC) myPhaseNTSC = newPhase; @@ -181,15 +224,21 @@ void PaletteHandler::loadConfig(const Settings& settings) { // Load adjustables myPhaseNTSC = BSPF::clamp(settings.getFloat("pal.phase_ntsc"), - DEF_NTSC_SHIFT - MAX_SHIFT, DEF_NTSC_SHIFT + MAX_SHIFT); + DEF_NTSC_SHIFT - MAX_PHASE_SHIFT, DEF_NTSC_SHIFT + MAX_PHASE_SHIFT); myPhasePAL = BSPF::clamp(settings.getFloat("pal.phase_pal"), - DEF_PAL_SHIFT - MAX_SHIFT, DEF_PAL_SHIFT + MAX_SHIFT); + DEF_PAL_SHIFT - MAX_PHASE_SHIFT, DEF_PAL_SHIFT + MAX_PHASE_SHIFT); + myRedScale = BSPF::clamp(settings.getFloat("pal.red_scale"), -1.0F, 1.0F) + 1.F; + myGreenScale = BSPF::clamp(settings.getFloat("pal.green_scale"), -1.0F, 1.0F) + 1.F; + myBlueScale = BSPF::clamp(settings.getFloat("pal.blue_scale"), -1.0F, 1.0F) + 1.F; + myRedShift = BSPF::clamp(settings.getFloat("pal.red_shift"), -MAX_RGB_SHIFT, MAX_RGB_SHIFT); + myGreenShift = BSPF::clamp(settings.getFloat("pal.green_shift"), -MAX_RGB_SHIFT, MAX_RGB_SHIFT); + myBlueShift = BSPF::clamp(settings.getFloat("pal.blue_shift"), -MAX_RGB_SHIFT, MAX_RGB_SHIFT); - myHue = BSPF::clamp(settings.getFloat("pal.hue"), -1.0F, 1.0F); - mySaturation = BSPF::clamp(settings.getFloat("pal.saturation"), -1.0F, 1.0F); - myContrast = BSPF::clamp(settings.getFloat("pal.contrast"), -1.0F, 1.0F); - myBrightness = BSPF::clamp(settings.getFloat("pal.brightness"), -1.0F, 1.0F); - myGamma = BSPF::clamp(settings.getFloat("pal.gamma"), -1.0F, 1.0F); + myHue = BSPF::clamp(settings.getFloat("pal.hue"), -1.0F, 1.0F); + mySaturation = BSPF::clamp(settings.getFloat("pal.saturation"), -1.0F, 1.0F); + myContrast = BSPF::clamp(settings.getFloat("pal.contrast"), -1.0F, 1.0F); + myBrightness = BSPF::clamp(settings.getFloat("pal.brightness"), -1.0F, 1.0F); + myGamma = BSPF::clamp(settings.getFloat("pal.gamma"), -1.0F, 1.0F); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -198,6 +247,12 @@ void PaletteHandler::saveConfig(Settings& settings) const // Save adjustables settings.setValue("pal.phase_ntsc", myPhaseNTSC); settings.setValue("pal.phase_pal", myPhasePAL); + settings.setValue("pal.red_scale", myRedScale - 1.F); + settings.setValue("pal.green_scale", myGreenScale - 1.F); + settings.setValue("pal.blue_scale", myBlueScale - 1.F); + settings.setValue("pal.red_shift", myRedShift); + settings.setValue("pal.green_shift", myGreenShift); + settings.setValue("pal.blue_shift", myBlueShift); settings.setValue("pal.hue", myHue); settings.setValue("pal.saturation", mySaturation); @@ -209,8 +264,14 @@ void PaletteHandler::saveConfig(Settings& settings) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PaletteHandler::setAdjustables(const Adjustable& adjustable) { - myPhaseNTSC = adjustable.phaseNtsc / 10.F; - myPhasePAL = adjustable.phasePal / 10.F; + myPhaseNTSC = scaleFromAngles(adjustable.phaseNtsc); + myPhasePAL = scaleFromAngles(adjustable.phasePal); + myRedScale = scaleRGBFrom100(adjustable.redScale); + myGreenScale = scaleRGBFrom100(adjustable.greenScale); + myBlueScale = scaleRGBFrom100(adjustable.blueScale); + myRedShift = scaleFromAngles(adjustable.redShift); + myGreenShift = scaleFromAngles(adjustable.greenShift); + myBlueShift = scaleFromAngles(adjustable.blueShift); myHue = scaleFrom100(adjustable.hue); mySaturation = scaleFrom100(adjustable.saturation); @@ -222,8 +283,14 @@ void PaletteHandler::setAdjustables(const Adjustable& adjustable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PaletteHandler::getAdjustables(Adjustable& adjustable) const { - adjustable.phaseNtsc = myPhaseNTSC * 10.F; - adjustable.phasePal = myPhasePAL * 10.F; + adjustable.phaseNtsc = scaleToAngles(myPhaseNTSC); + adjustable.phasePal = scaleToAngles(myPhasePAL); + adjustable.redScale = scaleRGBTo100(myRedScale); + adjustable.greenScale = scaleRGBTo100(myGreenScale); + adjustable.blueScale = scaleRGBTo100(myBlueScale); + adjustable.redShift = scaleToAngles(myRedShift); + adjustable.greenShift = scaleToAngles(myGreenShift); + adjustable.blueShift = scaleToAngles(myBlueShift); adjustable.hue = scaleTo100(myHue); adjustable.saturation = scaleTo100(mySaturation); @@ -371,10 +438,9 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) constexpr int NUM_LUMA = 8; constexpr float SATURATION = 0.25F; // default saturation - float color[NUM_CHROMA][2] = {{0.0F}}; - if(timing == ConsoleTiming::ntsc) { + vector2d IQ[NUM_CHROMA]; // YIQ is YUV shifted by 33° constexpr float offset = 33 * BSPF::PI_f / 180; const float shift = myPhaseNTSC * BSPF::PI_f / 180; @@ -382,22 +448,23 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) // color 0 is grayscale for(int chroma = 1; chroma < NUM_CHROMA; chroma++) { - color[chroma][0] = SATURATION * sinf(offset + shift * (chroma - 1)); - color[chroma][1] = SATURATION * cosf(offset + shift * (chroma - 1) - BSPF::PI_f); + IQ[chroma] = vector2d(SATURATION * sinf(offset + shift * (chroma - 1)), + SATURATION * cosf(offset + shift * (chroma - 1) - BSPF::PI_f)); } + const vector2d IQR = scale(rotate(vector2d(+0.956F, +0.621F), myRedShift), myRedScale); + const vector2d IQG = scale(rotate(vector2d(-0.272F, -0.647F), myGreenShift), myGreenScale); + const vector2d IQB = scale(rotate(vector2d(-1.106F, +1.703F), myBlueShift), myBlueScale); for(int chroma = 0; chroma < NUM_CHROMA; chroma++) { - const float I = color[chroma][0]; - const float Q = color[chroma][1]; - for(int luma = 0; luma < NUM_LUMA; luma++) { const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90 - float R = Y + 0.956F * I + 0.621F * Q; - float G = Y - 0.272F * I - 0.647F * Q; - float B = Y - 1.106F * I + 1.703F * Q; + float R = Y + dotProduct(IQ[chroma], IQR); + float G = Y + dotProduct(IQ[chroma], IQG); + float B = Y + dotProduct(IQ[chroma], IQB); + if(R < 0) R = 0; if(G < 0) G = 0; @@ -420,35 +487,37 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) constexpr float offset = BSPF::PI_f; const float shift = myPhasePAL * BSPF::PI_f / 180; constexpr float fixedShift = 22.5F * BSPF::PI_f / 180; + vector2d UV[NUM_CHROMA]; // colors 0, 1, 14 and 15 are grayscale for(int chroma = 2; chroma < NUM_CHROMA - 2; chroma++) { int idx = NUM_CHROMA - 1 - chroma; - color[idx][0] = SATURATION * sinf(offset - fixedShift * chroma); + + UV[idx].x = SATURATION * sinf(offset - fixedShift * chroma); if ((idx & 1) == 0) - color[idx][1] = SATURATION * sinf(offset - shift * (chroma - 3.5F) / 2.F); + UV[idx].y = SATURATION * sinf(offset - shift * (chroma - 3.5F) / 2.F); else - color[idx][1] = SATURATION * -sinf(offset - shift * chroma / 2.F); + UV[idx].y = SATURATION * -sinf(offset - shift * chroma / 2.F); } + // Most sources + const vector2d UVR = scale(rotate(vector2d( 0.000F, +1.403F), myRedShift), myRedScale); + const vector2d UVG = scale(rotate(vector2d(-0.344F, -0.714F), myGreenShift), myGreenScale); + const vector2d UVB = scale(rotate(vector2d(+0.714F, 0.000F), myBlueShift), myBlueScale); + // German Wikipedia, huh??? + //float R = Y + 1 / 0.877 * V; + //float B = Y + 1 / 0.493 * U; + //float G = 1.704 * Y - 0.590 * R - 0.194 * B; for(int chroma = 0; chroma < NUM_CHROMA; chroma++) { - const float U = color[chroma][0]; - const float V = color[chroma][1]; - for(int luma = 0; luma < NUM_LUMA; luma++) { const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90 - // Most sources - float R = Y + 1.403F * V; - float G = Y - 0.344F * U - 0.714F * V; - float B = Y + 1.770F * U; - // German Wikipedia, huh??? - //float B = Y + 1 / 0.493 * U; - //float R = Y + 1 / 0.877 * V; - //float G = 1.704 * Y - 0.590 * R - 0.194 * B; + float R = Y + dotProduct(UV[chroma], UVR); + float G = Y + dotProduct(UV[chroma], UVG); + float B = Y + dotProduct(UV[chroma], UVB); if(R < 0) R = 0.0; if(G < 0) G = 0.0; @@ -491,6 +560,28 @@ void PaletteHandler::adjustHueSaturation(int& R, int& G, int& B, float H, float B = BSPF::clamp(b, 0.F, 255.F); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +PaletteHandler::vector2d PaletteHandler::rotate(const PaletteHandler::vector2d& vec, float angle) const +{ + const float r = angle * BSPF::PI_f / 180; + + return PaletteHandler::vector2d(vec.x * cosf(r) - vec.y * sinf(r), + vec.x * sinf(r) + vec.y * cosf(r)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +PaletteHandler::vector2d PaletteHandler::scale(const PaletteHandler::vector2d& vec, float factor) const +{ + return PaletteHandler::vector2d(vec.x * factor, vec.y * factor); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +float PaletteHandler::dotProduct(const PaletteHandler::vector2d& vec1, + const PaletteHandler::vector2d& vec2) const +{ + return vec1.x * vec2.x + vec1.y * vec2.y; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const PaletteArray PaletteHandler::ourNTSCPalette = { 0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0, diff --git a/src/common/PaletteHandler.hxx b/src/common/PaletteHandler.hxx index 956fcf9b3..66da36715 100644 --- a/src/common/PaletteHandler.hxx +++ b/src/common/PaletteHandler.hxx @@ -35,20 +35,32 @@ class PaletteHandler // Phase shift default and limits static constexpr float DEF_NTSC_SHIFT = 26.2F; static constexpr float DEF_PAL_SHIFT = 31.3F; // ~= 360 / 11.5 - static constexpr float MAX_SHIFT = 4.5F; + static constexpr float MAX_PHASE_SHIFT = 4.5F; + static constexpr float DEF_RGB_SHIFT = 0.0F; + static constexpr float MAX_RGB_SHIFT = 22.5F; enum Adjustables { PHASE_SHIFT, + RED_SCALE, + GREEN_SCALE, + BLUE_SCALE, + RED_SHIFT, + GREEN_SHIFT, + BLUE_SHIFT, HUE, SATURATION, CONTRAST, BRIGHTNESS, - GAMMA + GAMMA, + CUSTOM_START = PHASE_SHIFT, + CUSTOM_END = BLUE_SHIFT, }; // Externally used adjustment parameters struct Adjustable { - float phaseNtsc{0.F}, phasePal{0.F}; + float phaseNtsc{0.F}, phasePal{0.F}, + redScale{0.F}, greenScale{0.F}, blueScale{0.F}, + redShift{0.F}, greenShift{0.F}, blueShift{0.F}; uInt32 hue{0}, saturation{0}, contrast{0}, brightness{0}, gamma{0}; }; @@ -108,6 +120,7 @@ class PaletteHandler */ void setPalette(); + private: static constexpr char DEGREE = 0x1c; @@ -121,12 +134,45 @@ class PaletteHandler MaxType = Custom }; + struct vector2d { + float x; + float y; + + explicit vector2d() + : x(0.F), y(0.F) { } + explicit vector2d(float _x, float _y) + : x(_x), y(_y) { } + }; + + /** + Convert RGB adjustables from/to 100% scale + */ + static constexpr float scaleRGBFrom100(float x) { return x / 50.F; } + static constexpr uInt32 scaleRGBTo100(float x) { return uInt32(50.0001F * (x - 0.F)); } + + /** + Convert angles + */ + static constexpr float scaleFromAngles(float x) { return x / 10.F; } + static constexpr Int32 scaleToAngles(float x) { return uInt32(10.F * x); } + /** Convert adjustables from/to 100% scale */ static constexpr float scaleFrom100(float x) { return (x / 50.F) - 1.F; } static constexpr uInt32 scaleTo100(float x) { return uInt32(50.0001F * (x + 1.F)); } + /** + Check for 'Custom' palette only adjustables + */ + bool isCustomAdjustable() const; + + bool isPhaseShift() const; + + bool isRGBScale() const; + + bool isRGBShift() const; + /** Convert palette settings name to enumeration. @@ -186,6 +232,21 @@ class PaletteHandler */ void adjustHueSaturation(int& R, int& G, int& B, float H, float S); + /** + Rotate a 2D vector. + */ + vector2d rotate(const vector2d& vec, float angle) const; + + /** + Scale a 2D vector. + */ + vector2d scale(const vector2d& vec, float factor) const; + + /** + Get the dot product of two 2D vectors. + */ + float dotProduct(const vector2d& vec1, const vector2d& vec2) const; + /** Loads a user-defined palette file (from OSystem::paletteFile), filling the appropriate user-defined palette arrays. @@ -193,7 +254,7 @@ class PaletteHandler void loadUserPalette(); private: - static constexpr int NUM_ADJUSTABLES = 6; + static constexpr int NUM_ADJUSTABLES = 12; OSystem& myOSystem; @@ -207,6 +268,12 @@ class PaletteHandler const std::array myAdjustables = { { { "phase shift", nullptr }, + { "red scale", &myRedScale }, + { "green scale", &myGreenScale }, + { "blue scale", &myBlueScale }, + { "red shift", &myRedShift }, + { "green shift", &myGreenShift }, + { "blue shift", &myBlueShift }, { "hue", &myHue }, { "saturation", &mySaturation }, { "contrast", &myContrast }, @@ -217,6 +284,14 @@ class PaletteHandler // NTSC and PAL color phase shifts float myPhaseNTSC{DEF_NTSC_SHIFT}; float myPhasePAL{DEF_PAL_SHIFT}; + // Color intensities + float myRedScale{1.0F}; + float myGreenScale{1.0F}; + float myBlueScale{1.0F}; + // Color shifts + float myRedShift{0.0F}; + float myGreenShift{0.0F}; + float myBlueShift{0.0F}; // range -1.0 to +1.0 (as in AtariNTSC) // Basic parameters float myHue{0.0F}; // -1 = -180 degrees +1 = +180 degrees diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index a5b0d5b1f..f0da1226c 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -377,7 +377,9 @@ AdjustFunction EventHandler::cycleAdjustSetting(int direction) #ifdef ADAPTABLE_REFRESH_SUPPORT || (myAdjustSetting == AdjustSetting::ADAPT_REFRESH && !isFullScreen) #endif - || (myAdjustSetting == AdjustSetting::PALETTE_PHASE && !isCustomPalette) + || (myAdjustSetting >= AdjustSetting::PALETTE_PHASE + && myAdjustSetting <= AdjustSetting::PALETTE_BLUE_SHIFT + && !isCustomPalette) || (myAdjustSetting >= AdjustSetting::NTSC_SHARPNESS && myAdjustSetting <= AdjustSetting::NTSC_BLEEDING && !isCustomFilter); @@ -425,6 +427,18 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting) std::bind(&PaletteHandler::cyclePalette, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), _1), std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), PaletteHandler::PHASE_SHIFT, _1), + std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), + PaletteHandler::RED_SCALE, _1), + std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), + PaletteHandler::RED_SHIFT, _1), + std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), + PaletteHandler::GREEN_SCALE, _1), + std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), + PaletteHandler::GREEN_SHIFT, _1), + std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), + PaletteHandler::BLUE_SCALE, _1), + std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), + PaletteHandler::BLUE_SHIFT, _1), std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), PaletteHandler::HUE, _1), std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index e437de7b4..4e591b869 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -431,6 +431,12 @@ class EventHandler // Palette adjustables PALETTE, PALETTE_PHASE, + PALETTE_RED_SCALE, + PALETTE_RED_SHIFT, + PALETTE_GREEN_SCALE, + PALETTE_GREEN_SHIFT, + PALETTE_BLUE_SCALE, + PALETTE_BLUE_SHIFT, PALETTE_HUE, PALETTE_SATURATION, PALETTE_CONTRAST, diff --git a/src/emucore/PointingDevice.cxx b/src/emucore/PointingDevice.cxx index accf00a04..cbd7f89c9 100644 --- a/src/emucore/PointingDevice.cxx +++ b/src/emucore/PointingDevice.cxx @@ -81,6 +81,7 @@ void PointingDevice::update() return; // Update horizontal direction + cerr << myEvent.get(Event::MouseAxisXMove) << ", " << myHCounterRemainder << endl; updateDirection( myEvent.get(Event::MouseAxisXMove), myHCounterRemainder, myTrackBallLeft, myTrackBallLinesH, myScanCountH, myFirstScanOffsetH); diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 08898c428..f7fa27ae8 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -62,6 +62,13 @@ Settings::Settings() setPermanent("palette", PaletteHandler::SETTING_STANDARD); setPermanent("pal.phase_ntsc", "26.2"); setPermanent("pal.phase_pal", "31.3"); + setPermanent("pal.red_scale", "0.0"); + setPermanent("pal.green_scale", "0.0"); + setPermanent("pal.blue_scale", "0.0"); + setPermanent("pal.red_shift", "0.0"); + setPermanent("pal.green_shift", "0.0"); + setPermanent("pal.blue_shift", "0.0"); + setPermanent("pal.contrast", "0.0"); setPermanent("pal.brightness", "0.0"); setPermanent("pal.hue", "0.0"); @@ -415,16 +422,24 @@ void Settings::usage() const << " -center <1|0> Centers game window in windowed modes\n" << " -windowedpos Sets the window position in windowed emulator mode\n" << " -display Sets the display for Stella's emulator\n" - << " -palette \n" - << " -pal.phase_ntsc Phase shift for NTSC 'custom' palette\n" - << " -pal.phase_pal Phase shift for PAL 'custom' palette\n" - << " -pal.hue <-1.0 - 1.0> Adjust hue for current palette\n" - << " -pal.saturation <-1.0 - 1.0> Adjust saturation of current palette\n" - << " -pal.contrast <-1.0 - 1.0> Adjust contrast of current palette\n" - << " -pal.brightness <-1.0 - 1.0> Adjust brightness of current palette\n" - << " -pal.gamma <-1.0 - 1.0> Adjust gamma of current palette\n" + << endl + << " -palette \n" + << " -pal.phase_ntsc Phase shift for NTSC 'custom' palette\n" + << " -pal.phase_pal Phase shift for PAL 'custom' palette\n" + << " -pal.red_scale <-1.0 - 1.0> Adjust red scale for 'custom' palette\n" + << " -pal.red_shift <-1.0 - 1.0> Adjust red shift for 'custom' palette\n" + << " -pal.green_scale <-1.0 - 1.0> Adjust green scale for 'custom' palette\n" + << " -pal.green_shift <-1.0 - 1.0> Adjust green shift for 'custom' palette\n" + << " -pal.blue_scale <-1.0 - 1.0> Adjust blue scale for 'custom' palette\n" + << " -pal.blue_shift <-1.0 - 1.0> Adjust blue shift for 'custom' palette\n" + << " -pal.hue <-1.0 - 1.0> Adjust hue for current palette\n" + << " -pal.saturation <-1.0 - 1.0> Adjust saturation of current palette\n" + << " -pal.contrast <-1.0 - 1.0> Adjust contrast of current palette\n" + << " -pal.brightness <-1.0 - 1.0> Adjust brightness of current palette\n" + << " -pal.gamma <-1.0 - 1.0> Adjust gamma of current palette\n" + << endl << " -speed Run emulation at the given speed\n" << " -turbo <1|0> Enable 'Turbo' mode for maximum emulation speed\n" << " -uimessages <1|0> Show onscreen UI messages for different events\n" diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index be08f83f8..01297b62b 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -223,25 +223,82 @@ void VideoAudioDialog::addPaletteTab() const int swidth = myTIAPalette->getWidth() - lwidth; const int plWidth = _font.getStringWidth("NTSC phase "); const int pswidth = swidth - INDENT + lwidth - plWidth; + xpos += INDENT; myPhaseShiftNtsc = - new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight, + new SliderWidget(myTab, _font, xpos, ypos - 1, pswidth, lineHeight, "NTSC phase", plWidth, kNtscShiftChanged, fontWidth * 5); - myPhaseShiftNtsc->setMinValue((PaletteHandler::DEF_NTSC_SHIFT - PaletteHandler::MAX_SHIFT) * 10); - myPhaseShiftNtsc->setMaxValue((PaletteHandler::DEF_NTSC_SHIFT + PaletteHandler::MAX_SHIFT) * 10); + myPhaseShiftNtsc->setMinValue((PaletteHandler::DEF_NTSC_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10); + myPhaseShiftNtsc->setMaxValue((PaletteHandler::DEF_NTSC_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10); myPhaseShiftNtsc->setTickmarkIntervals(4); wid.push_back(myPhaseShiftNtsc); ypos += lineHeight + VGAP; myPhaseShiftPal = - new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight, + new SliderWidget(myTab, _font, xpos, ypos - 1, pswidth, lineHeight, "PAL phase", plWidth, kPalShiftChanged, fontWidth * 5); - myPhaseShiftPal->setMinValue((PaletteHandler::DEF_PAL_SHIFT - PaletteHandler::MAX_SHIFT) * 10); - myPhaseShiftPal->setMaxValue((PaletteHandler::DEF_PAL_SHIFT + PaletteHandler::MAX_SHIFT) * 10); + myPhaseShiftPal->setMinValue((PaletteHandler::DEF_PAL_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10); + myPhaseShiftPal->setMaxValue((PaletteHandler::DEF_PAL_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10); myPhaseShiftPal->setTickmarkIntervals(4); wid.push_back(myPhaseShiftPal); ypos += lineHeight + VGAP; + const int rgblWidth = _font.getStringWidth("R "); + const int rgbsWidth = (myTIAPalette->getWidth() - INDENT - rgblWidth - fontWidth * 5) / 2; + + myTVRedScale = + new SliderWidget(myTab, _font, xpos, ypos - 1, rgbsWidth, lineHeight, + "R", rgblWidth, kPaletteUpdated, fontWidth * 4, "%"); + myTVRedScale->setMinValue(0); + myTVRedScale->setMaxValue(100); + myTVRedScale->setTickmarkIntervals(2); + wid.push_back(myTVRedScale); + + const int xposr = myTIAPalette->getRight() - rgbsWidth; + myTVRedShift = + new SliderWidget(myTab, _font, xposr, ypos - 1, rgbsWidth, lineHeight, + "", 0, kRedShiftChanged, fontWidth * 6); + myTVRedShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10); + myTVRedShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10); + myTVRedShift->setTickmarkIntervals(2); + wid.push_back(myTVRedShift); + ypos += lineHeight + VGAP; + + myTVGreenScale = + new SliderWidget(myTab, _font, xpos, ypos - 1, rgbsWidth, lineHeight, + "G", rgblWidth, kPaletteUpdated, fontWidth * 4, "%"); + myTVGreenScale->setMinValue(0); + myTVGreenScale->setMaxValue(100); + myTVGreenScale->setTickmarkIntervals(2); + wid.push_back(myTVGreenScale); + + myTVGreenShift = + new SliderWidget(myTab, _font, xposr, ypos - 1, rgbsWidth, lineHeight, + "", 0, kGreenShiftChanged, fontWidth * 6); + myTVGreenShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10); + myTVGreenShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10); + myTVGreenShift->setTickmarkIntervals(2); + wid.push_back(myTVGreenShift); + ypos += lineHeight + VGAP; + + myTVBlueScale = + new SliderWidget(myTab, _font, xpos, ypos - 1, rgbsWidth, lineHeight, + "B", rgblWidth, kPaletteUpdated, fontWidth * 4, "%"); + myTVBlueScale->setMinValue(0); + myTVBlueScale->setMaxValue(100); + myTVBlueScale->setTickmarkIntervals(2); + wid.push_back(myTVBlueScale); + + myTVBlueShift = + new SliderWidget(myTab, _font, xposr, ypos - 1, rgbsWidth, lineHeight, + "", 0, kBlueShiftChanged, fontWidth * 6); + myTVBlueShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10); + myTVBlueShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10); + myTVBlueShift->setTickmarkIntervals(2); + wid.push_back(myTVBlueShift); + ypos += lineHeight + VGAP; + xpos -= INDENT; + CREATE_CUSTOM_SLIDERS(Hue, "Hue ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Satur, "Saturation ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", kPaletteUpdated) @@ -524,6 +581,12 @@ void VideoAudioDialog::loadConfig() instance().frameBuffer().tiaSurface().paletteHandler().getAdjustables(myPaletteAdj); myPhaseShiftNtsc->setValue(myPaletteAdj.phaseNtsc); myPhaseShiftPal->setValue(myPaletteAdj.phasePal); + myTVRedScale->setValue(myPaletteAdj.redScale); + myTVRedShift->setValue(myPaletteAdj.redShift); + myTVGreenScale->setValue(myPaletteAdj.greenScale); + myTVGreenShift->setValue(myPaletteAdj.greenShift); + myTVBlueScale->setValue(myPaletteAdj.blueScale); + myTVBlueShift->setValue(myPaletteAdj.blueShift); myTVHue->setValue(myPaletteAdj.hue); myTVBright->setValue(myPaletteAdj.brightness); myTVContrast->setValue(myPaletteAdj.contrast); @@ -760,6 +823,12 @@ void VideoAudioDialog::setDefaults() myTIAPalette->setSelected(PaletteHandler::SETTING_STANDARD); myPhaseShiftNtsc->setValue(PaletteHandler::DEF_NTSC_SHIFT * 10); myPhaseShiftPal->setValue(PaletteHandler::DEF_PAL_SHIFT * 10); + myTVRedScale->setValue(50); + myTVRedShift->setValue(PaletteHandler::DEF_RGB_SHIFT); + myTVGreenScale->setValue(50); + myTVGreenShift->setValue(PaletteHandler::DEF_RGB_SHIFT); + myTVBlueScale->setValue(50); + myTVBlueShift->setValue(PaletteHandler::DEF_RGB_SHIFT); myTVHue->setValue(50); myTVSatur->setValue(50); myTVContrast->setValue(50); @@ -847,6 +916,23 @@ void VideoAudioDialog::handlePaletteChange() myPhaseShiftNtsc->setEnabled(enable); myPhaseShiftPal->setEnabled(enable); + myTVRedScale->setEnabled(enable); + myTVRedShift->setEnabled(enable); + myTVGreenScale->setEnabled(enable); + myTVGreenShift->setEnabled(enable); + myTVBlueScale->setEnabled(enable); + myTVBlueShift->setEnabled(enable); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void VideoAudioDialog::handleShiftChanged(SliderWidget* widget) +{ + std::ostringstream ss; + + ss << std::setw(4) << std::fixed << std::setprecision(1) + << (0.1 * (widget->getValue())) << DEGREE; + widget->setValueLabel(ss.str()); + handlePaletteUpdate(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -859,6 +945,12 @@ void VideoAudioDialog::handlePaletteUpdate() PaletteHandler::Adjustable paletteAdj; paletteAdj.phaseNtsc = myPhaseShiftNtsc->getValue(); paletteAdj.phasePal = myPhaseShiftPal->getValue(); + paletteAdj.redScale = myTVRedScale->getValue(); + paletteAdj.redShift = myTVRedShift->getValue(); + paletteAdj.greenScale = myTVGreenScale->getValue(); + paletteAdj.greenShift = myTVGreenShift->getValue(); + paletteAdj.blueScale = myTVBlueScale->getValue(); + paletteAdj.blueShift = myTVBlueShift->getValue(); paletteAdj.hue = myTVHue->getValue(); paletteAdj.saturation = myTVSatur->getValue(); paletteAdj.contrast = myTVContrast->getValue(); @@ -931,25 +1023,25 @@ void VideoAudioDialog::handleCommand(CommandSender* sender, int cmd, break; case kNtscShiftChanged: - { - std::ostringstream ss; - - ss << std::setw(4) << std::fixed << std::setprecision(1) - << (0.1 * abs(myPhaseShiftNtsc->getValue())) << DEGREE; - myPhaseShiftNtsc->setValueLabel(ss.str()); - handlePaletteUpdate(); + handleShiftChanged(myPhaseShiftNtsc); break; - } + case kPalShiftChanged: - { - std::ostringstream ss; - - ss << std::setw(4) << std::fixed << std::setprecision(1) - << (0.1 * abs(myPhaseShiftPal->getValue())) << DEGREE; - myPhaseShiftPal->setValueLabel(ss.str()); - handlePaletteUpdate(); + handleShiftChanged(myPhaseShiftPal); break; - } + + case kRedShiftChanged: + handleShiftChanged(myTVRedShift); + break; + + case kGreenShiftChanged: + handleShiftChanged(myTVGreenShift); + break; + + case kBlueShiftChanged: + handleShiftChanged(myTVBlueShift); + break; + case kVSizeChanged: { int adjust = myVSizeAdjust->getValue(); diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index 3581635b4..1d0e8a637 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -53,6 +53,7 @@ class VideoAudioDialog : public Dialog void handleTVModeChange(NTSCFilter::Preset); void loadTVAdjustables(NTSCFilter::Preset preset); void handlePaletteChange(); + void handleShiftChanged(SliderWidget* widget); void handlePaletteUpdate(); void handleFullScreenChange(); void handleOverscanChange(); @@ -105,6 +106,12 @@ class VideoAudioDialog : public Dialog PopUpWidget* myTIAPalette{nullptr}; SliderWidget* myPhaseShiftNtsc{nullptr}; SliderWidget* myPhaseShiftPal{nullptr}; + SliderWidget* myTVRedScale{nullptr}; + SliderWidget* myTVRedShift{nullptr}; + SliderWidget* myTVGreenScale{nullptr}; + SliderWidget* myTVGreenShift{nullptr}; + SliderWidget* myTVBlueScale{nullptr}; + SliderWidget* myTVBlueShift{nullptr}; SliderWidget* myTVHue{nullptr}; SliderWidget* myTVSatur{nullptr}; SliderWidget* myTVBright{nullptr}; @@ -138,6 +145,9 @@ class VideoAudioDialog : public Dialog kPaletteChanged = 'VDpl', kNtscShiftChanged = 'VDns', kPalShiftChanged = 'VDps', + kRedShiftChanged = 'VDrs', + kGreenShiftChanged = 'VDgs', + kBlueShiftChanged = 'VDbs', kPaletteUpdated = 'VDpu', kTVModeChanged = 'VDtv', diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index 9c37701d2..e40d8e622 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -47,8 +47,9 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const add(ypos, "fixed bug with launcher not remembering last selected ROM"); #else add(ypos, "added basic text cut/copy/paste to UI"); - add(ypos, "fixed fullscreen mode, aspect correction and pixel-exact snapshots"); + add(ypos, "added color parameters to 'Custom' palette"); add(ypos, "improved AVox-USB adaptor autodetection"); + add(ypos, "fixed fullscreen mode, aspect correction and pixel-exact snapshots"); add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); add(ypos, "fixed bug with launcher not remembering last selected ROM"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); From b1007c40a677cfebfddc820c6dd5e9090f630b76 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 31 Oct 2020 22:53:19 +0100 Subject: [PATCH 112/263] updated changes/WhatsNewDialog --- Changes.txt | 6 +++++- src/gui/WhatsNewDialog.cxx | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Changes.txt b/Changes.txt index 0a08e446b..7f14c7906 100644 --- a/Changes.txt +++ b/Changes.txt @@ -18,14 +18,18 @@ * Added color parameters to 'Custom' palette - * Some improvements to AVox-USB adaptor functionality: + * Some improvements to AtariVox-USB adaptor functionality: - Made serial port used for an AtariVox-USB adaptor editable. - Autodetection of serial ports no longer messes up devices plugged into other serial ports. + * Added CPU load stats to debugger + * Fixed bug with aspect correction and fullscreen mode; snapshots from such a mode are now pixel-exact. + * Fixed Atari mouse autodetection. + * Fixed crash with missing or incorrectly sized SaveKey data file, and with certain functions not working (erase pages, erase entire EEPROM). diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index e40d8e622..baaf88d5a 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -46,10 +46,11 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); add(ypos, "fixed bug with launcher not remembering last selected ROM"); #else - add(ypos, "added basic text cut/copy/paste to UI"); + add(ypos, "added basic text cut/copy/paste from/to UI"); add(ypos, "added color parameters to 'Custom' palette"); - add(ypos, "improved AVox-USB adaptor autodetection"); + add(ypos, "improved AtariVox-USB adaptor autodetection"); add(ypos, "fixed fullscreen mode, aspect correction and pixel-exact snapshots"); + add(ypos, "fixed Atari mouse autodetection"); add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); add(ypos, "fixed bug with launcher not remembering last selected ROM"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); From 3ece2cd26bc452f33d8750e9837edbec3a4fbf9e Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 31 Oct 2020 22:38:45 -0230 Subject: [PATCH 113/263] Updated various files for upcoming 6.4 release. --- Announce.txt | 20 ++++++++++---------- Changes.txt | 6 +++--- debian/changelog | 7 +++++++ docs/debugger.html | 2 +- docs/index.html | 6 +++--- docs/index_r77.html | 2 +- src/common/Version.hxx | 4 ++-- src/macos/Info-Stella.plist | 4 ++-- src/unix/stella.spec | 5 ++++- src/windows/stella.rc | 8 ++++---- 10 files changed, 37 insertions(+), 27 deletions(-) diff --git a/Announce.txt b/Announce.txt index 525c19736..60eb2f147 100644 --- a/Announce.txt +++ b/Announce.txt @@ -9,7 +9,7 @@ SSSS ttt eeeee llll llll aaaaa =========================================================================== - Release 6.3 for Linux, macOS and Windows + Release 6.4 for Linux, macOS and Windows =========================================================================== The Atari 2600 Video Computer System (VCS), introduced in 1977, was the @@ -21,25 +21,25 @@ all of your favourite Atari 2600 games again! Stella was originally developed for Linux by Bradford W. Mott, however, it has been ported to a number of other platforms and is currently maintained by Stephen Anthony. -This is the 6.3 release of Stella for Linux, macOS and Windows. The +This is the 6.4 release of Stella for Linux, macOS and Windows. The distributions currently available are: - * Binaries for Windows Vista/7/8/10 : - Stella-6.3-win32.exe (32-bit EXE installer) - Stella-6.3-x64.exe (64-bit EXE installer) - Stella-6.3-windows.zip (32/64 bit versions) + * Binaries for Windows 7/8/10 : + Stella-6.4-win32.exe (32-bit EXE installer) + Stella-6.4-x64.exe (64-bit EXE installer) + Stella-6.4-windows.zip (32/64 bit versions) * Binary distribution for macOS 10.7 and above : - Stella-6.3-macos.dmg (64-bit Intel) + Stella-6.4-macos.dmg (64-bit Intel) * Binary distribution for 64-bit Ubuntu : - stella_6.3-1_amd64.deb + stella_6.4-1_amd64.deb * Binary distribution for 64-bit Redhat : - stella-6.3-2.x86_64.rpm + stella-6.4-2.x86_64.rpm * Source code distribution for all platforms : - stella-6.3-src.tar.xz + stella-6.4-src.tar.xz Distribution Site diff --git a/Changes.txt b/Changes.txt index 7f14c7906..c0cef015d 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,18 +12,18 @@ Release History =========================================================================== -6.3 to 6.3.1 (November 2, 2020) +6.3 to 6.4 (November 2, 2020) * Added basic (entire and single line only) text cut/copy and paste. - * Added color parameters to 'Custom' palette + * Added color parameters to 'Custom' palette. * Some improvements to AtariVox-USB adaptor functionality: - Made serial port used for an AtariVox-USB adaptor editable. - Autodetection of serial ports no longer messes up devices plugged into other serial ports. - * Added CPU load stats to debugger + * Added CPU load stats to debugger. * Fixed bug with aspect correction and fullscreen mode; snapshots from such a mode are now pixel-exact. diff --git a/debian/changelog b/debian/changelog index 099657a51..424a4e46c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +stella (6.4-1) stable; urgency=high + + * Version 6.4 release + + -- Stephen Anthony Mon, 2 Nov 2020 17:09:59 -0230 + + stella (6.3-1) stable; urgency=high * Version 6.3 release diff --git a/docs/debugger.html b/docs/debugger.html index badd778cf..6b262e02c 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -15,7 +15,7 @@
    Stella
    -

    Release 6.3

    +

    Release 6.4

    Integrated Debugger

    (a work in progress)


    diff --git a/docs/index.html b/docs/index.html index 53f5b9e0f..969d3a084 100644 --- a/docs/index.html +++ b/docs/index.html @@ -19,7 +19,7 @@

    A multi-platform Atari 2600 VCS emulator

    -

    Release 6.3

    +

    Release 6.4



    User's Guide

    @@ -70,7 +70,7 @@


    -
    February 1999 - June 2020
    +
    February 1999 - November 2020
    The Stella Team
    Stella Homepage
    @@ -368,7 +368,7 @@

    Windows

    -

    The Windows version of Stella is designed to work on Windows Vista/7/8/10 +

    The Windows version of Stella is designed to work on Windows 7/8/10 with the following:

      diff --git a/docs/index_r77.html b/docs/index_r77.html index 6f3fad5e3..ed6e9bc84 100644 --- a/docs/index_r77.html +++ b/docs/index_r77.html @@ -58,7 +58,7 @@

      Stella for RetroN 77

      Atari 2600 VCS emulator

      -
      Release 6.3
      +
      Release 6.4

      Quick Navigation Guide


      diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 18bd4c76c..2d54ff139 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.4_pre" -#define STELLA_BUILD "6180" +#define STELLA_VERSION "6.4" +#define STELLA_BUILD "6231" #endif diff --git a/src/macos/Info-Stella.plist b/src/macos/Info-Stella.plist index 87f4e5681..02d53466d 100644 --- a/src/macos/Info-Stella.plist +++ b/src/macos/Info-Stella.plist @@ -45,7 +45,7 @@ CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion - 6.3 + 6.4 CFBundleName Stella CFBundlePackageType @@ -53,7 +53,7 @@ CFBundleSignature StLa CFBundleVersion - 6.3 + 6.4 LSApplicationCategoryType public.app-category.games LSMinimumSystemVersionByArchitecture diff --git a/src/unix/stella.spec b/src/unix/stella.spec index 2818841ac..49be7f97b 100644 --- a/src/unix/stella.spec +++ b/src/unix/stella.spec @@ -1,5 +1,5 @@ %define name stella -%define version 6.3 +%define version 6.4 %define rel 1 %define enable_sound 1 @@ -100,6 +100,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version} %_datadir/icons/large/%{name}.png %changelog +* Mon Nov 2 2020 Stephen Anthony 6.4-1 +- Version 6.4 release + * Wed Oct 7 2020 Stephen Anthony 6.3-1 - Version 6.3 release diff --git a/src/windows/stella.rc b/src/windows/stella.rc index 4640920a0..6b99a297c 100755 --- a/src/windows/stella.rc +++ b/src/windows/stella.rc @@ -36,8 +36,8 @@ IDI_ICON ICON "stella.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 6,3,0,0 - PRODUCTVERSION 6,3,0,0 + FILEVERSION 6,4,0,0 + PRODUCTVERSION 6,4,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -55,12 +55,12 @@ BEGIN VALUE "Comments", "The multi-platform Atari 2600 emulator. Stella is released under the GPLv2." VALUE "CompanyName", "The Stella Team (https://stella-emu.github.io)" VALUE "FileDescription", "Stella" - VALUE "FileVersion", "6.3" + VALUE "FileVersion", "6.4" VALUE "InternalName", "Stella" VALUE "LegalCopyright", "Copyright (c) 1995-2020 The Stella Team" VALUE "OriginalFilename", "Stella.exe" VALUE "ProductName", "Stella" - VALUE "ProductVersion", "6.3" + VALUE "ProductVersion", "6.4" END END BLOCK "VarFileInfo" From 7657fc7d418221620e89a0624bc333a9008d1c46 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 1 Nov 2020 11:42:35 +0100 Subject: [PATCH 114/263] fixed DeveloperDialog default settings of CPU register (fixes #717) --- src/gui/DeveloperDialog.cxx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index 6406e33d5..bf681f6e0 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -751,9 +751,11 @@ void DeveloperDialog::getWidgetStates(SettingsSet set) myRandomBank[set] = myRandomBankWidget->getState(); myRandomizeRAM[set] = myRandomizeRAMWidget->getState(); string cpurandom; + const std::array cpuregs = {"S", "A", "X", "Y", "P"}; + for(int i = 0; i < 5; ++i) if(myRandomizeCPUWidget[i]->getState()) - cpurandom += ourCPUregs[i]; + cpurandom += cpuregs[i]; myRandomizeCPU[set] = cpurandom; // Undriven TIA pins myUndrivenPins[set] = myUndrivenPinsWidget->getState(); @@ -805,8 +807,10 @@ void DeveloperDialog::setWidgetStates(SettingsSet set) myRandomizeRAMWidget->setState(myRandomizeRAM[set]); const string& cpurandom = myRandomizeCPU[set]; + const std::array cpuregs = {"S", "A", "X", "Y", "P"}; + for(int i = 0; i < 5; ++i) - myRandomizeCPUWidget[i]->setState(BSPF::containsIgnoreCase(cpurandom, ourCPUregs[i])); + myRandomizeCPUWidget[i]->setState(BSPF::containsIgnoreCase(cpurandom, cpuregs[i])); // Undriven TIA pins myUndrivenPinsWidget->setState(myUndrivenPins[set]); #ifdef DEBUGGER_SUPPORT From e9b30c7fee37661777da478891dc332a72adb2c2 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 1 Nov 2020 09:51:57 -0330 Subject: [PATCH 115/263] Slight refactor of label array in DeveloperDialog. - This is a followup to the last commit for this class - We don't need this to be a static in the header file itself --- src/gui/DeveloperDialog.cxx | 8 ++------ src/gui/DeveloperDialog.hxx | 2 -- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index bf681f6e0..6c877351a 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -154,11 +154,12 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) myRandomizeCPULabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Randomize CPU "); wid.push_back(myRandomizeCPULabel); + const std::array cpuregsLabels = {"SP", "A", "X", "Y", "PS"}; int xpos = myRandomizeCPULabel->getRight() + fontWidth * 1.25; for(int i = 0; i < 5; ++i) { myRandomizeCPUWidget[i] = new CheckboxWidget(myTab, font, xpos, ypos + 1, - ourCPUregs[i], kRandCPUID); + cpuregsLabels[i], kRandCPUID); wid.push_back(myRandomizeCPUWidget[i]); xpos += CheckboxWidget::boxSize(font) + font.getStringWidth("XX") + fontWidth * 2.5; } @@ -1535,8 +1536,3 @@ void DeveloperDialog::handleFontSize() myDebuggerHeightSlider->setValue(minH); #endif } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const std::array DeveloperDialog::ourCPUregs = { - "SP", "A", "X", "Y", "PS" -}; diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx index f66d58378..e3d31ecfd 100644 --- a/src/gui/DeveloperDialog.hxx +++ b/src/gui/DeveloperDialog.hxx @@ -184,8 +184,6 @@ class DeveloperDialog : public Dialog std::array myStateInterval; std::array myStateHorizon; - static const std::array ourCPUregs; - private: void addEmulationTab(const GUI::Font& font); void addTimeMachineTab(const GUI::Font& font); From 0a7a665016957cefd25743a7d031435278865715 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sun, 1 Nov 2020 15:07:42 +0100 Subject: [PATCH 116/263] Changelog. --- Changes.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changes.txt b/Changes.txt index c0cef015d..85f230597 100644 --- a/Changes.txt +++ b/Changes.txt @@ -30,6 +30,10 @@ * Fixed Atari mouse autodetection. + * Fixed a bug in 6.3 that caused CDF cartridges to crash on the Retron77 + and that causes reduced ARM emulation performance for CDF cartridges on + other platforms. + * Fixed crash with missing or incorrectly sized SaveKey data file, and with certain functions not working (erase pages, erase entire EEPROM). From 6d861dfe6ed6ac0c5d748468d6111100a2664a23 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 1 Nov 2020 15:43:54 +0100 Subject: [PATCH 117/263] updated WhatsNewDialog, reordered Changes.txt --- Changes.txt | 9 ++++----- src/gui/WhatsNewDialog.cxx | 4 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Changes.txt b/Changes.txt index 85f230597..40acf140a 100644 --- a/Changes.txt +++ b/Changes.txt @@ -28,15 +28,14 @@ * Fixed bug with aspect correction and fullscreen mode; snapshots from such a mode are now pixel-exact. - * Fixed Atari mouse autodetection. - - * Fixed a bug in 6.3 that caused CDF cartridges to crash on the Retron77 - and that causes reduced ARM emulation performance for CDF cartridges on - other platforms. + * Fixed a bug that caused CDF cartridges to crash on the Retron77 and + reduced ARM emulation performance for CDF cartridges on other platforms. * Fixed crash with missing or incorrectly sized SaveKey data file, and with certain functions not working (erase pages, erase entire EEPROM). + * Fixed Atari mouse autodetection. + * Fixed bug in ROM launcher, with last ROM selected not being remembered when exiting and re-entering a directory. diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index baaf88d5a..c15474e1e 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -43,6 +43,7 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const max_w, max_h); #if defined(RETRON77) + add(ypos, "fixed CDF cartridges crash"); add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); add(ypos, "fixed bug with launcher not remembering last selected ROM"); #else @@ -50,8 +51,9 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const add(ypos, "added color parameters to 'Custom' palette"); add(ypos, "improved AtariVox-USB adaptor autodetection"); add(ypos, "fixed fullscreen mode, aspect correction and pixel-exact snapshots"); - add(ypos, "fixed Atari mouse autodetection"); + add(ypos, "fixed reduced ARM emulation performance for CDF cartridges"); add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); + add(ypos, "fixed Atari mouse autodetection"); add(ypos, "fixed bug with launcher not remembering last selected ROM"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); #endif From de4dd018839ee02c91a0100c3c535b7ea76b6f1d Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 1 Nov 2020 15:19:50 -0330 Subject: [PATCH 118/263] Updated git commit ID for last commit before the 6.4 release (we hope). Changed changelog slightly, since Stella loads ROMs, not cartridges. --- Changes.txt | 4 ++-- src/common/Version.hxx | 2 +- src/gui/WhatsNewDialog.cxx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Changes.txt b/Changes.txt index 40acf140a..60049604f 100644 --- a/Changes.txt +++ b/Changes.txt @@ -28,8 +28,8 @@ * Fixed bug with aspect correction and fullscreen mode; snapshots from such a mode are now pixel-exact. - * Fixed a bug that caused CDF cartridges to crash on the Retron77 and - reduced ARM emulation performance for CDF cartridges on other platforms. + * Fixed a bug that caused CDF ROMs to crash on the Retron77 and reduced + ARM emulation performance for CDF ROMs on other platforms. * Fixed crash with missing or incorrectly sized SaveKey data file, and with certain functions not working (erase pages, erase entire EEPROM). diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 2d54ff139..3106dd6c7 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -19,6 +19,6 @@ #define VERSION_HXX #define STELLA_VERSION "6.4" -#define STELLA_BUILD "6231" +#define STELLA_BUILD "6236" #endif diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index c15474e1e..825ed43fe 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -51,7 +51,7 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const add(ypos, "added color parameters to 'Custom' palette"); add(ypos, "improved AtariVox-USB adaptor autodetection"); add(ypos, "fixed fullscreen mode, aspect correction and pixel-exact snapshots"); - add(ypos, "fixed reduced ARM emulation performance for CDF cartridges"); + add(ypos, "fixed reduced ARM emulation performance for CDF ROMs"); add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); add(ypos, "fixed Atari mouse autodetection"); add(ypos, "fixed bug with launcher not remembering last selected ROM"); From 0b45bc0a2d293463450f821d7913e41952215f37 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 1 Nov 2020 18:27:41 -0330 Subject: [PATCH 119/263] Added new debugger pseudo-registers to the changelog. Changed string "Cycl." to "Cycle", since there was no point using a '.' with a fixed-width font. --- Changes.txt | 5 ++++- docs/debugger.html | 4 ++-- src/common/Version.hxx | 2 +- src/debugger/gui/TiaInfoWidget.cxx | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Changes.txt b/Changes.txt index 60049604f..84e4996ad 100644 --- a/Changes.txt +++ b/Changes.txt @@ -23,7 +23,10 @@ - Autodetection of serial ports no longer messes up devices plugged into other serial ports. - * Added CPU load stats to debugger. + * Added CPU load stats to debugger. Related to this, added debugger + pseudo-registers '_ftimreadcycles' and '_fwsynccycles' to show the + number of cycles since the start of frame under certain circumstances + (see manual for more details). * Fixed bug with aspect correction and fullscreen mode; snapshots from such a mode are now pixel-exact. diff --git a/docs/debugger.html b/docs/debugger.html index 6b262e02c..7f4c108bc 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -1149,9 +1149,9 @@ as illustrated:

      • Frame Cycle: The number of CPU cycles that have been executed this frame since VSYNC was cleared at scanline 0.
      • -
      • WSync Cycl.: The number of CPU cycles that have been skipped by WSYNC this frame since +
      • WSync Cycle: The number of CPU cycles that have been skipped by WSYNC this frame since VSYNC was cleared at scanline 0.
      • -
      • Timer Cycl.: The number of CPU cycles (approximately) that have been used by timer read loops since +
      • Timer Cycle: The number of CPU cycles (approximately) that have been used by timer read loops since VSYNC was cleared at scanline 0.
      • Total: The total number of CPU cycles since this ROM was loaded or reset.
      • Delta: The number of CPU cycles that have been executed since the last debugger diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 3106dd6c7..c6c81ab47 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -19,6 +19,6 @@ #define VERSION_HXX #define STELLA_VERSION "6.4" -#define STELLA_BUILD "6236" +#define STELLA_BUILD "6237" #endif diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index c892422c5..3a0a3b27f 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -64,13 +64,13 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, // Left: WSync Cycles ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycl." : "WSync C."); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycle" : "WSync C."); myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myWSyncCylces->setEditable(false, true); // Left: Timer Cycles ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycl." : "Timer C."); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycle" : "Timer C."); myTimerCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myTimerCylces->setEditable(false, true); From b7f80e552c3e0199106c091b91cc537a46d7a7e2 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 1 Nov 2020 19:07:39 -0330 Subject: [PATCH 120/263] More syntax fixes; indicate plural of "Cycle" as "Cycls" in the debugger (we really need more room here :) ) --- docs/debugger.html | 6 +++--- src/common/Version.hxx | 2 +- src/debugger/gui/TiaInfoWidget.cxx | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/debugger.html b/docs/debugger.html index 7f4c108bc..bc0329c0f 100644 --- a/docs/debugger.html +++ b/docs/debugger.html @@ -1147,11 +1147,11 @@ as illustrated:

        The indicators are as follows (note that all these are read-only):

          -
        • Frame Cycle: The number of CPU cycles that have been executed this frame since +
        • Frame Cycls: The number of CPU cycles that have been executed this frame since VSYNC was cleared at scanline 0.
        • -
        • WSync Cycle: The number of CPU cycles that have been skipped by WSYNC this frame since +
        • WSync Cycls: The number of CPU cycles that have been skipped by WSYNC this frame since VSYNC was cleared at scanline 0.
        • -
        • Timer Cycle: The number of CPU cycles (approximately) that have been used by timer read loops since +
        • Timer Cycls: The number of CPU cycles (approximately) that have been used by timer read loops since VSYNC was cleared at scanline 0.
        • Total: The total number of CPU cycles since this ROM was loaded or reset.
        • Delta: The number of CPU cycles that have been executed since the last debugger diff --git a/src/common/Version.hxx b/src/common/Version.hxx index c6c81ab47..a0eb84a14 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -19,6 +19,6 @@ #define VERSION_HXX #define STELLA_VERSION "6.4" -#define STELLA_BUILD "6237" +#define STELLA_BUILD "6238" #endif diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index 3a0a3b27f..08d4b2008 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -43,7 +43,7 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, + EditTextWidget::calcWidth(lfont) * 3 <= max_w; const int lineHeight = lfont.getLineHeight(); int xpos = x, ypos = y + VBORDER; - int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle" : "F. Cycle"); + int lwidth = lfont.getStringWidth(longstr ? "Frame Cycls" : "F. Cycls"); int lwidth8 = lwidth - lfont.getMaxCharWidth() * 3; int lwidthR = lfont.getStringWidth(longstr ? "Frame Cnt." : "Frame "); int fwidth = EditTextWidget::calcWidth(lfont, 5); @@ -58,19 +58,19 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, // Left column // Left: Frame Cycle xpos = x; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycle" : "F. Cycle"); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycls" : "F. Cycls"); myFrameCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myFrameCycles->setEditable(false, true); // Left: WSync Cycles ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycle" : "WSync C."); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycls" : "WSync C."); myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myWSyncCylces->setEditable(false, true); // Left: Timer Cycles ypos += lineHeight + VGAP; - new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycle" : "Timer C."); + new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycls" : "Timer C."); myTimerCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); myTimerCylces->setEditable(false, true); From c986f2687e4cf975598f54ff55537e6c18d420db Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 2 Nov 2020 09:08:34 +0100 Subject: [PATCH 121/263] updated debugger screenshot for "Frame Cycls" --- docs/graphics/debugger_tiainfo.png | Bin 1394 -> 1396 bytes src/debugger/gui/TiaInfoWidget.cxx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/graphics/debugger_tiainfo.png b/docs/graphics/debugger_tiainfo.png index 14ae847052ae310cfb64db3a54687a3fa0d774e5..3ef48b425218b72e827474e9891cd25a821fd846 100644 GIT binary patch delta 1228 zcmV;-1T*{c3iJw)WDddr01mqUgeE`uSs)_t z+Wb%e@=2ltf|$KFLJ^%;^mt==v3!AEa}4CkHz41f6^aokY+!-6AIK-Z8a4M0c_4*< zggXJ!aSnMPP$)Uy1>`OxT(m*Wbv&mC#0W*5`v*!l?gvu1rwfqj0O3Kq1Q75-G4$FS zfFz-4AiY{J2`GB>X9!btF6?P@0jPw%VuhmK{-swJp?$fA1N;gJ5 z6pFo9PVab@nX3Wm-aE^cevIsTKvzqD@|S&_z5FG?yM10I%IMh^g^My6G*2-vQ>KffEb~ea$;X< zL35zrLq7F~n5AoYp-{|ef2oc&K-La`j5^RmybSX54C2uO5UosBKmb1qR9^dk(6G0i z9#TKrL&f1V5bB|mLNPZV&7o&AWI9N?_!^`H=sBU7oBR1*Rq}BURg-$k4nI01arLfe znZ6p3_#9a2$I#(fpsOYM%Ra%r=j@>O19Rxtea3zt1={at0WF|OAZROr&;|0kE^a-m zWrO6|j^4i;325{6+ze6LwnR!A@$t3^MPcl{g0!gTrz|R@#Sg8vt!id~~$SmxHcT=|us5o)on3Rl?p6 zyp@3PmGyz{?0Ra{Ly7@Xj4oq=;v7P&mODU?XB;wS#kn+xlsJdt;B!%yLoMDa#U8RT z%BnT_DhSRJWkBlxe3ZF+>#R^*&$0#d&jDR7$zS$ycDXt9HRo6zvjb7KfJU}}qGc6V z3&t@}wPX}{KjBvz_|k%ZZ7PaTXPWasq_j}#hYgT6xwKFNxg4*mm!V3)P9UkG*Z_5k zFIE6bx(-()X68^06czx-4O*GhhG^;l^my_>B_|I(`n delta 1226 zcmV;*1U38g3i1k&WDdgs01m?e$8V@)000E+k#Z}4!Jk30^;@i3w(Kw3?OU?<^rLQf z!G7=TXZMZ;w19R40e~sL*Z2!SALwBb5bb9MNSk;L4FrfZ0P=kRWFJoiq-G2QxeEwT z+ou4eO@-G3+HmX%AU_!pP6}Nh@Q0+s!%PT1Q~_zT9jv!m@bjkudO&Vm(%A_RaiIj{ zsonp7urUMVufRmE?SHs18OZOAXYY@Y>rBVv`aq2jLF{E7C{5Zt5P%FsqAY!EEg}#T zcP&tyxIH7JB%p187$7Jk)EW!qHYy+u`5X9nobsV%ySK*EOc*zS9Bj8%vitmS!S*Vq|L>DfY{>~(5R!UCHc!f&d$z#-RkRhRw(Y? zLG7#lemmCB`1l1hI{rTZDjK7;lF+c{B?7O_en0?n=W;+A6fYE$#%NDy@`IlRA_A|? z4+S8fBsw67*=r*d(RsxlZ!9mCFVJg_fjs#Ja99nUgzH6Y!4XSvdkkzEhyYDxZovX8Tuza)6KP;A?sd#$s8#_f0S7QiaG5s)v*T1+5wPJ2S$jOLEg_G9xVXT%47uu@S{NGwGRz{d)pZy z^`j$HI-CYVBXm+I=H??GdNxz0gQSbEK}vw06NM1+?=#a$KyPjqG zYCz(1V5J|!4$lHzEy-W@3HCi_2YWx@L%;4b_WLN%{(ctF0-6MZwh{Nn`!H_+lrbyLB_C3v55>vnqAZ76yj6-LWMh<7 zYw}ePoF&SD)c^S?bNAL+p}3x93+SH%x?GaK?BncmKJ+!$u{vf4qHF<;Yym~fDy|lc zW1wouDDeG+Uuob=3%03$C_5q#)G5AL z0VwG@T#=aZp&BSG0FE29GN}#G)B))6wH+z8?*ePp(u&zUYTR0K+ oN>yP`eTY^jIj0UjlP(1^6s@~7Rk?(4VgLXD07*qoM6N<$f&yAOQUCw| diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index 08d4b2008..a02b2365d 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -38,7 +38,7 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, const int VGAP = lfont.getLineHeight() / 4; const int VBORDER = 5 + 1; const int COLUMN_GAP = _fontWidth * 1.25; - bool longstr = lfont.getStringWidth("Frame Cycle12345") + _fontWidth * 0.5 + bool longstr = lfont.getStringWidth("Frame Cycls12345") + _fontWidth * 0.5 + COLUMN_GAP + lfont.getStringWidth("Scanline262262") + EditTextWidget::calcWidth(lfont) * 3 <= max_w; const int lineHeight = lfont.getLineHeight(); From 55c74116a2e82a0668d924938837ce6e57429a12 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 2 Nov 2020 14:20:42 -0330 Subject: [PATCH 122/263] And so it begins again; bump version number to 6.5_pre Move some serial port code directly into portNames(); meant to do this for 6.4, oh well. --- src/common/Version.hxx | 2 +- src/macos/SerialPortMACOS.cxx | 24 ++++++++++-------------- src/macos/SerialPortMACOS.hxx | 9 --------- src/unix/SerialPortUNIX.cxx | 24 ++++++++++-------------- src/unix/SerialPortUNIX.hxx | 9 --------- 5 files changed, 21 insertions(+), 47 deletions(-) diff --git a/src/common/Version.hxx b/src/common/Version.hxx index a0eb84a14..2d6bf8db8 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -18,7 +18,7 @@ #ifndef VERSION_HXX #define VERSION_HXX -#define STELLA_VERSION "6.4" +#define STELLA_VERSION "6.5_pre" #define STELLA_BUILD "6238" #endif diff --git a/src/macos/SerialPortMACOS.cxx b/src/macos/SerialPortMACOS.cxx index 745fdc8fc..85fba0032 100644 --- a/src/macos/SerialPortMACOS.cxx +++ b/src/macos/SerialPortMACOS.cxx @@ -99,32 +99,28 @@ StringList SerialPortMACOS::portNames() { StringList ports; + // Check if port is valid; for now that means if it can be opened + // Eventually we may extend this to do more intensive checks + auto isPortValid = [](const string& port) { + int handle = open(port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); + if(handle > 0) close(handle); + return handle > 0; + }; + // Get all possible devices in the '/dev' directory FilesystemNode::NameFilter filter = [](const FilesystemNode& node) { return BSPF::startsWithIgnoreCase(node.getPath(), "/dev/cu.usb"); }; FSList portList; - portList.reserve(16); + portList.reserve(5); FilesystemNode dev("/dev/"); dev.getChildren(portList, FilesystemNode::ListMode::All, filter, false); // Add only those that can be opened for(const auto& port: portList) - if(isValid(port.getPath())) + if(isPortValid(port.getPath())) ports.emplace_back(port.getPath()); return ports; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool SerialPortMACOS::isValid(const string& port) const -{ - // For now, we can only detect whether the port could be opened - // Eventually we may extend this to do more intensive checks - int handle = open(port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); - if(handle > 0) - close(handle); - - return handle > 0; -} diff --git a/src/macos/SerialPortMACOS.hxx b/src/macos/SerialPortMACOS.hxx index f16d9ddcd..ea55ddc3d 100644 --- a/src/macos/SerialPortMACOS.hxx +++ b/src/macos/SerialPortMACOS.hxx @@ -69,15 +69,6 @@ class SerialPortMACOS : public SerialPort */ StringList portNames() override; - private: - /** - Tests whether this port can be opened, and is a valid - serial port. - - @return True if valid, else false - */ - bool isValid(const string& port) const; - private: // File descriptor for serial connection int myHandle{0}; diff --git a/src/unix/SerialPortUNIX.cxx b/src/unix/SerialPortUNIX.cxx index 1f7449cec..4ecc11a25 100644 --- a/src/unix/SerialPortUNIX.cxx +++ b/src/unix/SerialPortUNIX.cxx @@ -102,33 +102,29 @@ StringList SerialPortUNIX::portNames() { StringList ports; + // Check if port is valid; for now that means if it can be opened + // Eventually we may extend this to do more intensive checks + auto isPortValid = [](const string& port) { + int handle = open(port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); + if(handle > 0) close(handle); + return handle > 0; + }; + // Get all possible devices in the '/dev' directory FilesystemNode::NameFilter filter = [](const FilesystemNode& node) { return BSPF::startsWithIgnoreCase(node.getPath(), "/dev/ttyACM") || BSPF::startsWithIgnoreCase(node.getPath(), "/dev/ttyUSB"); }; FSList portList; - portList.reserve(16); + portList.reserve(5); FilesystemNode dev("/dev/"); dev.getChildren(portList, FilesystemNode::ListMode::All, filter, false); // Add only those that can be opened for(const auto& port: portList) - if(isValid(port.getPath())) + if(isPortValid(port.getPath())) ports.emplace_back(port.getPath()); return ports; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool SerialPortUNIX::isValid(const string& port) const -{ - // For now, we can only detect whether the port could be opened - // Eventually we may extend this to do more intensive checks - int handle = open(port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); - if(handle > 0) - close(handle); - - return handle > 0; -} diff --git a/src/unix/SerialPortUNIX.hxx b/src/unix/SerialPortUNIX.hxx index 44b508b94..640ee9b85 100644 --- a/src/unix/SerialPortUNIX.hxx +++ b/src/unix/SerialPortUNIX.hxx @@ -70,15 +70,6 @@ class SerialPortUNIX : public SerialPort */ StringList portNames() override; - private: - /** - Tests whether this port can be opened, and is a valid - serial port. - - @return True if valid, else false - */ - bool isValid(const string& port) const; - private: // File descriptor for serial connection int myHandle{0}; From f3ab1d56c68ba25e41520418a8f1f8cbd5357e19 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 3 Nov 2020 16:52:01 +0100 Subject: [PATCH 123/263] Some refactoring of EditableWidget --- src/debugger/gui/DataGridWidget.cxx | 4 - src/gui/EditableWidget.cxx | 232 +++++++++++++++------------- src/gui/EditableWidget.hxx | 11 +- 3 files changed, 127 insertions(+), 120 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 719eebef2..ad918f65f 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -46,10 +46,6 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font, { _flags = Widget::FLAG_ENABLED | Widget::FLAG_RETAIN_FOCUS | Widget::FLAG_WANTS_RAWDATA; - // The item is selected, thus _bgcolor is used to draw the caret and - // _textcolorhi to erase it - _caretInverse = true; - // Make sure all lists contain some default values _hiliteList.clear(); int size = _rows * _cols; diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 77bcd58a8..edfa99f44 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -112,8 +112,19 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) if(StellaModTest::isAlt(mod)) return true; + if(StellaModTest::isShift(mod) && handleShiftKeys(key)) + return true; + + if(StellaModTest::isControl(mod) && handleControlKeys(key)) + return true; + + return handleNormalKeys(key); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::handleNormalKeys(StellaKey key) +{ bool handled = true; - bool dirty = false; switch(key) { @@ -122,79 +133,146 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) // confirm edit and exit editmode endEditMode(); sendCommand(EditableWidget::kAcceptCmd, 0, _id); - dirty = true; break; case KBDK_ESCAPE: abortEditMode(); sendCommand(EditableWidget::kCancelCmd, 0, _id); - dirty = true; break; case KBDK_BACKSPACE: - dirty = killChar(-1); - if(dirty) sendCommand(EditableWidget::kChangedCmd, key, _id); + handled = killChar(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_DELETE: case KBDK_KP_PERIOD: - if(StellaModTest::isShift(mod)) - { - cutSelectedText(); - dirty = true; - } - else - dirty = killChar(+1); - if(dirty) sendCommand(EditableWidget::kChangedCmd, key, _id); + handled = killChar(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_LEFT: - if(StellaModTest::isControl(mod)) - dirty = specialKeys(key); - else if(_caretPos > 0) - dirty = setCaretPos(_caretPos - 1); + if(_caretPos > 0) + handled = setCaretPos(_caretPos - 1); break; case KBDK_RIGHT: - if(StellaModTest::isControl(mod)) - dirty = specialKeys(key); - else if(_caretPos < int(_editString.size())) - dirty = setCaretPos(_caretPos + 1); + if(_caretPos < int(_editString.size())) + handled = setCaretPos(_caretPos + 1); break; case KBDK_HOME: - dirty = setCaretPos(0); + handled = setCaretPos(0); break; case KBDK_END: - dirty = setCaretPos(int(_editString.size())); - break; - - case KBDK_INSERT: - if(StellaModTest::isControl(mod)) - { - copySelectedText(); - dirty = true; - } - else if(StellaModTest::isShift(mod)) - { - pasteSelectedText(); - dirty = true; - } - else - handled = false; + handled = setCaretPos(int(_editString.size())); break; default: - if (StellaModTest::isControl(mod)) - { - dirty = specialKeys(key); - } - else - handled = false; + handled = false; } - if (dirty) + if(handled) + setDirty(); + + return handled; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::handleShiftKeys(StellaKey key) +{ + bool handled = true; + + switch(key) + { + case KBDK_DELETE: + case KBDK_KP_PERIOD: + cutSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_INSERT: + pasteSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + default: + handled = false; + } + + if(handled) + setDirty(); + + return handled; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::handleControlKeys(StellaKey key) +{ + bool handled = true; + + switch(key) + { + case KBDK_A: + setCaretPos(0); + break; + + case KBDK_C: + copySelectedText(); + break; + + case KBDK_E: + setCaretPos(int(_editString.size())); + break; + + case KBDK_D: + handled = killChar(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_K: + handled = killLine(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_U: + handled = killLine(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_V: + pasteSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_W: + handled = killLastWord(); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_X: + cutSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_LEFT: + handled = moveWord(-1); + break; + + case KBDK_RIGHT: + handled = moveWord(+1); + break; + + case KBDK_INSERT: + copySelectedText(); + break; + + default: + handled = false; + } + + if(handled) setDirty(); return handled; @@ -278,70 +356,6 @@ bool EditableWidget::adjustOffset() return true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::specialKeys(StellaKey key) -{ - bool handled = true; - - switch(key) - { - case KBDK_A: - setCaretPos(0); - break; - - case KBDK_C: - copySelectedText(); - break; - - case KBDK_E: - setCaretPos(int(_editString.size())); - break; - - case KBDK_D: - handled = killChar(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_K: - handled = killLine(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_U: - handled = killLine(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_V: - pasteSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_W: - handled = killLastWord(); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_X: - cutSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_LEFT: - handled = moveWord(-1); - break; - - case KBDK_RIGHT: - handled = moveWord(+1); - break; - - default: - handled = false; - } - - return handled; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::killChar(int direction) { diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 748f6074f..f2e4595fb 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -80,7 +80,9 @@ class EditableWidget : public Widget, public CommandSender private: // Line editing - bool specialKeys(StellaKey key); + bool handleControlKeys(StellaKey key); + bool handleShiftKeys(StellaKey key); + bool handleNormalKeys(StellaKey key); bool killChar(int direction); bool killLine(int direction); bool killLastWord(); @@ -98,14 +100,9 @@ class EditableWidget : public Widget, public CommandSender private: bool _editable{true}; string _editString; - -// bool _caretVisible{false}; -// int _caretTime{0}; - int _caretPos{0}; + int _caretPos{0}; protected: - bool _caretInverse{false}; - int _editScrollOffset{0}; private: From fa8e21cf4be8441f628d19dfc63587ccde2353b8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 4 Nov 2020 12:36:18 +0100 Subject: [PATCH 124/263] added keyboard copy/paste selection in EditableWidget (addresses #105) increased width of edit cursor --- src/common/EventHandlerSDL2.cxx | 7 - src/common/EventHandlerSDL2.hxx | 1 - src/debugger/gui/PromptWidget.cxx | 2 +- src/emucore/EventHandler.hxx | 1 - src/gui/EditTextWidget.cxx | 6 +- src/gui/EditableWidget.cxx | 404 +++++++++++++++++++++--------- src/gui/EditableWidget.hxx | 14 +- 7 files changed, 297 insertions(+), 138 deletions(-) diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index fa19303bc..45d31ce9e 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -64,13 +64,6 @@ void EventHandlerSDL2::copyText(const string& text) const SDL_SetClipboardText(text.c_str()); }; -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandlerSDL2::cutText(string& text) const -{ - copyText(text); - text = ""; -}; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string EventHandlerSDL2::pasteText(string& text) const { diff --git a/src/common/EventHandlerSDL2.hxx b/src/common/EventHandlerSDL2.hxx index c7f9c4a2f..2654cd132 100644 --- a/src/common/EventHandlerSDL2.hxx +++ b/src/common/EventHandlerSDL2.hxx @@ -48,7 +48,6 @@ private: Clipboard methods. */ void copyText(const string& text) const override; - void cutText(string& text) const override; string pasteText(string& text) const override; /** diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 75fede786..4f5a0abae 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -718,7 +718,7 @@ void PromptWidget::textCut() #if defined(PSEUDO_CUT_COPY_PASTE) string text = getLine(); - instance().eventHandler().cutText(text); + instance().eventHandler().copyText(text); // Remove the current line _currentPos = _promptStartPos; diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 4e591b869..8649bd9e0 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -342,7 +342,6 @@ class EventHandler Clipboard methods. */ virtual void copyText(const string& text) const = 0; - virtual void cutText(string& text) const = 0; virtual string pasteText(string& text) const = 0; #endif diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index ff53ced5a..35e6eaf04 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -68,6 +68,7 @@ void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount if(!isEditable()) return; + resetSelection(); x += _editScrollOffset; int width = 0; @@ -105,8 +106,10 @@ void EditTextWidget::drawWidget(bool hilite) _changed && onTop && isEnabled() ? kDbgChangedTextColor : onTop && isEnabled() ? _textcolor : kColor, - TextAlign::Left, isEditable() ? -_editScrollOffset : 0, !isEditable()); + TextAlign::Left, scrollOffset(), !isEditable()); + // Draw selected text + drawSelection(); // Draw the caret drawCaret(); } @@ -120,6 +123,7 @@ Common::Rect EditTextWidget::getEditRect() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditTextWidget::lostFocusWidget() { + EditableWidget::lostFocusWidget(); // If we loose focus, 'commit' the user changes _backupString = editString(); } diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index edfa99f44..b6120c8ac 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -75,6 +75,12 @@ void EditableWidget::setEditable(bool editable, bool hiliteBG) } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EditableWidget::lostFocusWidget() +{ + _selectSize = 0; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::tryInsertChar(char c, int pos) { @@ -112,15 +118,142 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) if(StellaModTest::isAlt(mod)) return true; + if(StellaModTest::isControl(mod) && handleControlKeys(key, mod)) + return true; + if(StellaModTest::isShift(mod) && handleShiftKeys(key)) return true; - if(StellaModTest::isControl(mod) && handleControlKeys(key)) - return true; - return handleNormalKeys(key); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) +{ + bool shift = StellaModTest::isShift(mod); + bool handled = true; + bool dirty = true; + + switch(key) + { + case KBDK_A: + setCaretPos(0); + _selectSize = -int(_editString.size()); + break; + + case KBDK_C: + case KBDK_INSERT: + copySelectedText(); + break; + + case KBDK_E: + if(shift) + _selectSize += _caretPos - int(_editString.size()); + else + _selectSize = 0; + setCaretPos(int(_editString.size())); + break; + + case KBDK_D: + handled = killChar(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_K: // TODO + handled = killLine(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_U: // TODO + handled = killLine(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_V: + pasteSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_W: // TODO + handled = killLastWord(); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_X: + cutSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_LEFT: + handled = moveWord(-1, shift); + if(!shift) + _selectSize = 0; + break; + + case KBDK_RIGHT: + handled = moveWord(+1, shift); + if(!shift) + _selectSize = 0; + break; + + default: + handled = false; + dirty = false; + } + + if(dirty) + setDirty(); + + return handled; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::handleShiftKeys(StellaKey key) +{ + bool handled = true; + + switch(key) + { + case KBDK_DELETE: + case KBDK_KP_PERIOD: + cutSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_INSERT: + pasteSelectedText(); + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case KBDK_LEFT: + if(_caretPos > 0) + handled = moveCaretPos(-1); + break; + + case KBDK_RIGHT: + if(_caretPos < int(_editString.size())) + handled = moveCaretPos(+1); + break; + + case KBDK_HOME: + handled = moveCaretPos(-_caretPos); + break; + + case KBDK_END: + handled = moveCaretPos(int(_editString.size()) - _caretPos); + break; + + + default: + handled = false; + } + + if(handled) + setDirty(); + + return handled; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::handleNormalKeys(StellaKey key) { @@ -128,6 +261,12 @@ bool EditableWidget::handleNormalKeys(StellaKey key) switch(key) { + case KBDK_LSHIFT: + case KBDK_RSHIFT: + // stay in select mode + handled = false; + break; + case KBDK_RETURN: case KBDK_KP_ENTER: // confirm edit and exit editmode @@ -174,120 +313,24 @@ bool EditableWidget::handleNormalKeys(StellaKey key) } if(handled) - setDirty(); - - return handled; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleShiftKeys(StellaKey key) -{ - bool handled = true; - - switch(key) { - case KBDK_DELETE: - case KBDK_KP_PERIOD: - cutSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_INSERT: - pasteSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - default: - handled = false; - } - - if(handled) setDirty(); - - return handled; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleControlKeys(StellaKey key) -{ - bool handled = true; - - switch(key) - { - case KBDK_A: - setCaretPos(0); - break; - - case KBDK_C: - copySelectedText(); - break; - - case KBDK_E: - setCaretPos(int(_editString.size())); - break; - - case KBDK_D: - handled = killChar(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_K: - handled = killLine(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_U: - handled = killLine(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_V: - pasteSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_W: - handled = killLastWord(); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_X: - cutSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_LEFT: - handled = moveWord(-1); - break; - - case KBDK_RIGHT: - handled = moveWord(+1); - break; - - case KBDK_INSERT: - copySelectedText(); - break; - - default: - handled = false; + _selectSize = 0; } - if(handled) - setDirty(); - return handled; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int EditableWidget::getCaretOffset() const { - int caretpos = 0; + int caretOfs = 0; for (int i = 0; i < _caretPos; i++) - caretpos += _font.getCharWidth(_editString[i]); + caretOfs += _font.getCharWidth(_editString[i]); - caretpos -= _editScrollOffset; + caretOfs -= _editScrollOffset; - return caretpos; + return caretOfs; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -307,7 +350,46 @@ void EditableWidget::drawCaret() y += _y; FBSurface& s = _boss->dialog().surface(); - s.vLine(x, y+2, y + editRect.h() - 2, kTextColorHi); + s.vLine(x, y + 2, y + editRect.h() - 2, kTextColorHi); + s.vLine(x-1, y + 2, y + editRect.h() - 2, kTextColorHi); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EditableWidget::drawSelection() +{ + // Only draw if item is visible + if(!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus + || !_selectSize) + return; + + FBSurface& s = _boss->dialog().surface(); + string text = selectString(); + const Common::Rect& editRect = getEditRect(); + int x = editRect.x(); + int y = editRect.y(); + int w = editRect.w(); + int h = editRect.h(); + int wt = int(text.length()) * _font.getMaxCharWidth() + 1; + int dx = selectPos() * _font.getMaxCharWidth() - _editScrollOffset; + + if(dx < 0) + { + // selected text starts left of displayed rect + text = text.substr(-(dx - 1) / _font.getMaxCharWidth()); + wt += dx; + dx = 0; + } + else + x += dx; + // limit selection to the right of displayed rect + w = std::min(w - dx + 1, wt); + + x += _x; + y += _y; + + s.fillRect(x - 1, y + 1, w + 1, h - 3, kTextColorHi); + s.drawString(_font, text, x, y + 1, w, h, + kTextColorInv, TextAlign::Left, 0, false); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -319,6 +401,17 @@ bool EditableWidget::setCaretPos(int newPos) return adjustOffset(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::moveCaretPos(int direction) +{ + if(setCaretPos(_caretPos + direction)) + { + _selectSize -= direction; + return true; + } + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::adjustOffset() { @@ -328,18 +421,18 @@ bool EditableWidget::adjustOffset() // For some reason (differences in ScummVM event handling??), // this method should always return true. - int caretpos = getCaretOffset(); + int caretOfs = getCaretOffset(); const int editWidth = getEditRect().w(); - if (caretpos < 0) + if (caretOfs < 0) { // scroll left - _editScrollOffset += caretpos; + _editScrollOffset += caretOfs; } - else if (caretpos >= editWidth) + else if (caretOfs >= editWidth) { // scroll right - _editScrollOffset -= (editWidth - caretpos); + _editScrollOffset -= (editWidth - caretOfs); } else if (_editScrollOffset > 0) { @@ -356,25 +449,34 @@ bool EditableWidget::adjustOffset() return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int EditableWidget::scrollOffset() +{ + return _editable ? -_editScrollOffset : 0; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::killChar(int direction) { - bool handled = false; + bool handled = killSelectedText(); - if(direction == -1) // Delete previous character (backspace) + if(!handled) { - if(_caretPos > 0) + if(direction == -1) // Delete previous character (backspace) + { + if(_caretPos > 0) + { + _caretPos--; + _editString.erase(_caretPos, 1); + handled = true; + } + } + else if(direction == 1) // Delete next character (delete) { - _caretPos--; _editString.erase(_caretPos, 1); handled = true; } } - else if(direction == 1) // Delete next character (delete) - { - _editString.erase(_caretPos, 1); - handled = true; - } return handled; } @@ -442,7 +544,7 @@ bool EditableWidget::killLastWord() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::moveWord(int direction) +bool EditableWidget::moveWord(int direction, bool select) { bool handled = false; bool space = true; @@ -461,6 +563,8 @@ bool EditableWidget::moveWord(int direction) space = false; currentPos--; + if(select) + _selectSize++; } _caretPos = currentPos; handled = true; @@ -478,6 +582,8 @@ bool EditableWidget::moveWord(int direction) space = false; currentPos++; + if(select) + _selectSize--; } _caretPos = currentPos; handled = true; @@ -486,12 +592,56 @@ bool EditableWidget::moveWord(int direction) return handled; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const string EditableWidget::selectString() const +{ + if(_selectSize) + { + int caretPos = _caretPos; + int selectSize = _selectSize; + + if(selectSize < 0) + { + caretPos += selectSize; + selectSize = -selectSize; + } + return _editString.substr(caretPos, selectSize); + } + return EmptyString; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int EditableWidget::selectPos() +{ + if(_selectSize < 0) + return _caretPos + _selectSize; + else + return _caretPos; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::killSelectedText() +{ + if(_selectSize) + { + if(_selectSize < 0) + { + _caretPos += _selectSize; + _selectSize = -_selectSize; + } + _editString.erase(_caretPos, _selectSize); + _selectSize = 0; + return true; + } + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::cutSelectedText() { #if defined(PSEUDO_CUT_COPY_PASTE) - instance().eventHandler().cutText(_editString); - _caretPos = 0; + instance().eventHandler().copyText(selectString()); + killSelectedText(); #endif } @@ -499,7 +649,7 @@ void EditableWidget::cutSelectedText() void EditableWidget::copySelectedText() { #if defined(PSEUDO_CUT_COPY_PASTE) - instance().eventHandler().copyText(_editString); + instance().eventHandler().copyText(selectString()); #endif } @@ -507,7 +657,11 @@ void EditableWidget::copySelectedText() void EditableWidget::pasteSelectedText() { #if defined(PSEUDO_CUT_COPY_PASTE) - instance().eventHandler().pasteText(_editString); - _caretPos = int(_editString.length()); + string text; + + instance().eventHandler().pasteText(text); + killSelectedText(); + _editString.insert(_caretPos, text); + _caretPos += int(text.length()); #endif } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index f2e4595fb..9dd047327 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -64,6 +64,8 @@ class EditableWidget : public Widget, public CommandSender void setTextFilter(const TextFilter& filter) { _filter = filter; } protected: + void lostFocusWidget() override; + virtual void startEditMode() { setFlags(Widget::FLAG_WANTS_RAWDATA); } virtual void endEditMode() { clearFlags(Widget::FLAG_WANTS_RAWDATA); } virtual void abortEditMode() { clearFlags(Widget::FLAG_WANTS_RAWDATA); } @@ -72,22 +74,29 @@ class EditableWidget : public Widget, public CommandSender virtual int getCaretOffset() const; void drawCaret(); bool setCaretPos(int newPos); + bool moveCaretPos(int direction); bool adjustOffset(); // This method is used internally by child classes wanting to // access/edit the internal buffer string& editString() { return _editString; } + const string selectString() const; + void resetSelection() { _selectSize = 0; } + void drawSelection(); + int scrollOffset(); private: // Line editing - bool handleControlKeys(StellaKey key); + bool handleControlKeys(StellaKey key, StellaMod mod); bool handleShiftKeys(StellaKey key); bool handleNormalKeys(StellaKey key); bool killChar(int direction); bool killLine(int direction); bool killLastWord(); - bool moveWord(int direction); + bool moveWord(int direction, bool select); + bool killSelectedText(); + int selectPos(); // Clipboard void cutSelectedText(); void copySelectedText(); @@ -101,6 +110,7 @@ class EditableWidget : public Widget, public CommandSender bool _editable{true}; string _editString; int _caretPos{0}; + int _selectSize{0}; protected: int _editScrollOffset{0}; From 0aa078c6103d9e92e63c80aee0a02b40bb6337d2 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 4 Nov 2020 14:31:21 +0100 Subject: [PATCH 125/263] improved keyboard copy/paste selection --- src/gui/EditableWidget.cxx | 29 ++++++++++++++++++++++------- src/gui/EditableWidget.hxx | 3 ++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index b6120c8ac..706e6e243 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -257,6 +257,7 @@ bool EditableWidget::handleShiftKeys(StellaKey key) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::handleNormalKeys(StellaKey key) { + bool selectMode = false; bool handled = true; switch(key) @@ -264,7 +265,7 @@ bool EditableWidget::handleNormalKeys(StellaKey key) case KBDK_LSHIFT: case KBDK_RSHIFT: // stay in select mode - handled = false; + selectMode = _selectSize; break; case KBDK_RETURN: @@ -291,12 +292,16 @@ bool EditableWidget::handleNormalKeys(StellaKey key) break; case KBDK_LEFT: - if(_caretPos > 0) + if (_selectSize) + handled = setCaretPos(selectStartPos()); + else if(_caretPos > 0) handled = setCaretPos(_caretPos - 1); break; case KBDK_RIGHT: - if(_caretPos < int(_editString.size())) + if(_selectSize) + handled = setCaretPos(selectEndPos()); + else if(_caretPos < int(_editString.size())) handled = setCaretPos(_caretPos + 1); break; @@ -309,14 +314,14 @@ bool EditableWidget::handleNormalKeys(StellaKey key) break; default: + killSelectedText(); handled = false; } if(handled) - { setDirty(); + if(!selectMode) _selectSize = 0; - } return handled; } @@ -370,7 +375,7 @@ void EditableWidget::drawSelection() int w = editRect.w(); int h = editRect.h(); int wt = int(text.length()) * _font.getMaxCharWidth() + 1; - int dx = selectPos() * _font.getMaxCharWidth() - _editScrollOffset; + int dx = selectStartPos() * _font.getMaxCharWidth() - _editScrollOffset; if(dx < 0) { @@ -611,7 +616,7 @@ const string EditableWidget::selectString() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int EditableWidget::selectPos() +int EditableWidget::selectStartPos() { if(_selectSize < 0) return _caretPos + _selectSize; @@ -619,6 +624,16 @@ int EditableWidget::selectPos() return _caretPos; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int EditableWidget::selectEndPos() +{ + if(_selectSize > 0) + return _caretPos + _selectSize; + else + return _caretPos; +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::killSelectedText() { diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 9dd047327..46cfb1855 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -96,7 +96,8 @@ class EditableWidget : public Widget, public CommandSender bool moveWord(int direction, bool select); bool killSelectedText(); - int selectPos(); + int selectStartPos(); + int selectEndPos(); // Clipboard void cutSelectedText(); void copySelectedText(); From 8c5b47346f753b6dad699baffc5af18da90a5df0 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 4 Nov 2020 15:29:21 +0100 Subject: [PATCH 126/263] fixed copy/paste bug --- src/gui/EditableWidget.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 706e6e243..6c0efaa68 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -264,8 +264,11 @@ bool EditableWidget::handleNormalKeys(StellaKey key) { case KBDK_LSHIFT: case KBDK_RSHIFT: + case KBDK_LCTRL: + case KBDK_RCTRL: // stay in select mode selectMode = _selectSize; + handled = false; break; case KBDK_RETURN: From 9b95063fbcd16d0c191fba734788be3ffcc6046d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 4 Nov 2020 20:18:41 +0100 Subject: [PATCH 127/263] finalized EditableWidget enabled selection drawing on all derived widgets --- src/debugger/gui/DataGridWidget.cxx | 2 +- src/debugger/gui/RomListWidget.cxx | 2 +- src/gui/CheckListWidget.cxx | 2 +- src/gui/EditTextWidget.cxx | 6 +- src/gui/EditableWidget.cxx | 106 ++++++++++++++-------------- src/gui/EditableWidget.hxx | 3 +- src/gui/PopUpWidget.cxx | 2 +- src/gui/StringListWidget.cxx | 2 +- 8 files changed, 62 insertions(+), 63 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index ad918f65f..ad7548594 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -646,7 +646,7 @@ void DataGridWidget::drawWidget(bool hilite) // Only draw the caret while editing, and if it's in the current viewport if(_editMode) - drawCaret(); + drawCaretSelection(); // Draw the scrollbar if(_scrollBar) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 07bbbf668..2964e4990 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -547,7 +547,7 @@ void RomListWidget::drawWidget(bool hilite) s.drawString(_font, editString(), _x + r.x(), ypos, r.w(), textColor, TextAlign::Left, -_editScrollOffset, false); - drawCaret(); + drawCaretSelection(); } else { diff --git a/src/gui/CheckListWidget.cxx b/src/gui/CheckListWidget.cxx index 08852a4f8..079989376 100644 --- a/src/gui/CheckListWidget.cxx +++ b/src/gui/CheckListWidget.cxx @@ -145,7 +145,7 @@ void CheckListWidget::drawWidget(bool hilite) (!_useScrollbar || ((_selectedItem >= _scrollBar->_currentPos) && (_selectedItem < _scrollBar->_currentPos + _rows)))) - drawCaret(); + drawCaretSelection(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index 35e6eaf04..6105e70d3 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -108,10 +108,8 @@ void EditTextWidget::drawWidget(bool hilite) : onTop && isEnabled() ? _textcolor : kColor, TextAlign::Left, scrollOffset(), !isEditable()); - // Draw selected text - drawSelection(); - // Draw the caret - drawCaret(); + // Draw the caret and selection + drawCaretSelection(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 6c0efaa68..57514dc99 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -159,12 +159,12 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_K: // TODO + case KBDK_K: handled = killLine(+1); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_U: // TODO + case KBDK_U: handled = killLine(-1); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; @@ -284,13 +284,17 @@ bool EditableWidget::handleNormalKeys(StellaKey key) break; case KBDK_BACKSPACE: - handled = killChar(-1); + handled = killSelectedText(); + if(!handled) + handled = killChar(-1); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_DELETE: case KBDK_KP_PERIOD: - handled = killChar(+1); + handled = killSelectedText(); + if(!handled) + handled = killChar(+1); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; @@ -342,7 +346,7 @@ int EditableWidget::getCaretOffset() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::drawCaret() +void EditableWidget::drawCaretSelection() { // Only draw if item is visible if (!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus) @@ -360,44 +364,36 @@ void EditableWidget::drawCaret() FBSurface& s = _boss->dialog().surface(); s.vLine(x, y + 2, y + editRect.h() - 2, kTextColorHi); s.vLine(x-1, y + 2, y + editRect.h() - 2, kTextColorHi); -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::drawSelection() -{ - // Only draw if item is visible - if(!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus - || !_selectSize) - return; - - FBSurface& s = _boss->dialog().surface(); - string text = selectString(); - const Common::Rect& editRect = getEditRect(); - int x = editRect.x(); - int y = editRect.y(); - int w = editRect.w(); - int h = editRect.h(); - int wt = int(text.length()) * _font.getMaxCharWidth() + 1; - int dx = selectStartPos() * _font.getMaxCharWidth() - _editScrollOffset; - - if(dx < 0) + if(_selectSize) { - // selected text starts left of displayed rect - text = text.substr(-(dx - 1) / _font.getMaxCharWidth()); - wt += dx; - dx = 0; + string text = selectString(); + x = editRect.x(); + y = editRect.y(); + int w = editRect.w(); + int h = editRect.h(); + int wt = int(text.length()) * _font.getMaxCharWidth() + 1; + int dx = selectStartPos() * _font.getMaxCharWidth() - _editScrollOffset; + + if(dx < 0) + { + // selected text starts left of displayed rect + text = text.substr(-(dx - 1) / _font.getMaxCharWidth()); + wt += dx; + dx = 0; + } + else + x += dx; + // limit selection to the right of displayed rect + w = std::min(w - dx + 1, wt); + + x += _x; + y += _y; + + s.fillRect(x - 1, y + 1, w + 1, h - 3, kTextColorHi); + s.drawString(_font, text, x, y + 1, w, h, + kTextColorInv, TextAlign::Left, 0, false); } - else - x += dx; - // limit selection to the right of displayed rect - w = std::min(w - dx + 1, wt); - - x += _x; - y += _y; - - s.fillRect(x - 1, y + 1, w + 1, h - 3, kTextColorHi); - s.drawString(_font, text, x, y + 1, w, h, - kTextColorInv, TextAlign::Left, 0, false); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -466,25 +462,22 @@ int EditableWidget::scrollOffset() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::killChar(int direction) { - bool handled = killSelectedText(); + bool handled = false; - if(!handled) + if(direction == -1) // Delete previous character (backspace) { - if(direction == -1) // Delete previous character (backspace) - { - if(_caretPos > 0) - { - _caretPos--; - _editString.erase(_caretPos, 1); - handled = true; - } - } - else if(direction == 1) // Delete next character (delete) + if(_caretPos > 0) { + _caretPos--; _editString.erase(_caretPos, 1); handled = true; } } + else if(direction == 1) // Delete next character (delete) + { + _editString.erase(_caretPos, 1); + handled = true; + } return handled; } @@ -503,6 +496,9 @@ bool EditableWidget::killLine(int direction) killChar(-1); handled = true; + // remove selection for removed text + if(_selectSize < 0) + _selectSize = 0; } } else if(direction == 1) // erase from current position to end of line @@ -514,6 +510,9 @@ bool EditableWidget::killLine(int direction) killChar(+1); handled = true; + // remove selection for removed text + if(_selectSize > 0) + _selectSize = 0; } } @@ -546,6 +545,9 @@ bool EditableWidget::killLastWord() killChar(-1); handled = true; + // remove selection for removed word + if(_selectSize < 0) + _selectSize = std::min(_selectSize + count, 0); } return handled; diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 46cfb1855..95427582f 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -72,7 +72,7 @@ class EditableWidget : public Widget, public CommandSender virtual Common::Rect getEditRect() const = 0; virtual int getCaretOffset() const; - void drawCaret(); + void drawCaretSelection(); bool setCaretPos(int newPos); bool moveCaretPos(int direction); bool adjustOffset(); @@ -82,7 +82,6 @@ class EditableWidget : public Widget, public CommandSender string& editString() { return _editString; } const string selectString() const; void resetSelection() { _selectSize = 0; } - void drawSelection(); int scrollOffset(); private: diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index c41cfdc00..95f2ac46b 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -297,7 +297,7 @@ void PopUpWidget::drawWidget(bool hilite) align, editable ? -_editScrollOffset : 0, !editable); if(editable) - drawCaret(); + drawCaretSelection(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index f388aaeff..4171632cb 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -112,7 +112,7 @@ void StringListWidget::drawWidget(bool hilite) (!_useScrollbar || ((_selectedItem >= _scrollBar->_currentPos) && (_selectedItem < _scrollBar->_currentPos + _rows)))) - drawCaret(); + drawCaretSelection(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From f5922c6bc910a097a32f4b034bac3093421c8a54 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 4 Nov 2020 20:19:53 +0100 Subject: [PATCH 128/263] removed forgotten TODO --- src/gui/EditableWidget.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 57514dc99..5e1b312eb 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -174,7 +174,7 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_W: // TODO + case KBDK_W: handled = killLastWord(); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; From ed39615077a69cf2ad55e6f3edc8782647f8f1d1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 4 Nov 2020 22:44:41 +0100 Subject: [PATCH 129/263] added selection reset for all widgets derived from EditableWidget --- src/debugger/gui/DataGridWidget.cxx | 1 + src/debugger/gui/RomListWidget.cxx | 1 + src/gui/EditableWidget.cxx | 3 +++ src/gui/EditableWidget.hxx | 4 ++++ src/gui/ListWidget.cxx | 1 + src/gui/PopUpWidget.cxx | 1 + 6 files changed, 11 insertions(+) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index ad7548594..f3b81676c 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -259,6 +259,7 @@ void DataGridWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount if (!isEnabled()) return; + resetSelection(); // First check whether the selection changed int newSelectedItem; newSelectedItem = findItem(x, y); diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 2964e4990..48885f734 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -235,6 +235,7 @@ void RomListWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) if (!isEnabled()) return; + resetSelection(); // Grab right mouse button for context menu, left for selection/edit mode if(b == MouseButton::RIGHT) { diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 5e1b312eb..cf69fbe64 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -118,12 +118,15 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) if(StellaModTest::isAlt(mod)) return true; + // Handle Control and Control-Shift keys if(StellaModTest::isControl(mod) && handleControlKeys(key, mod)) return true; + // Handle Shift keys if(StellaModTest::isShift(mod) && handleShiftKeys(key)) return true; + // Handle keys without modifiers return handleNormalKeys(key); } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 95427582f..b30e3ac59 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -110,6 +110,10 @@ class EditableWidget : public Widget, public CommandSender bool _editable{true}; string _editString; int _caretPos{0}; + // Size of current selected text + // 0 = no selection + // <0 = selected left of caret + // >0 = selected right of caret int _selectSize{0}; protected: diff --git a/src/gui/ListWidget.cxx b/src/gui/ListWidget.cxx index 1d9d8ee3c..d8b0bc458 100644 --- a/src/gui/ListWidget.cxx +++ b/src/gui/ListWidget.cxx @@ -205,6 +205,7 @@ void ListWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) if (!isEnabled()) return; + resetSelection(); // First check whether the selection changed int newSelectedItem; newSelectedItem = findItem(x, y); diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 95f2ac46b..8540f2df3 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -117,6 +117,7 @@ const Variant& PopUpWidget::getSelectedTag() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) { + resetSelection(); if(!isEditable() || x > _w - dropDownWidth(_font)) { if(isEnabled() && !myMenu->isVisible()) From 4cb502ff8cdb06f3fa4abebbb14a6c50e3cb06e2 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 5 Nov 2020 08:26:59 +0100 Subject: [PATCH 130/263] selection bug fix attempt --- src/gui/EditableWidget.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index cf69fbe64..20ded2dfc 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -52,6 +52,7 @@ void EditableWidget::setText(const string& str, bool) _editString.push_back(c); _caretPos = int(_editString.size()); + _selectSize = 0; _editScrollOffset = (_font.getStringWidth(_editString) - (getEditRect().w())); if (_editScrollOffset < 0) @@ -101,6 +102,7 @@ bool EditableWidget::handleText(char text) if(tryInsertChar(text, _caretPos)) { _caretPos++; + _selectSize = 0; sendCommand(EditableWidget::kChangedCmd, 0, _id); setDirty(); return true; From 67d1a898e0bbe3dedf1800cfa72eaed98071f1f6 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 5 Nov 2020 11:22:52 +0100 Subject: [PATCH 131/263] some minor EditableWidget enhancements and code cosmetics --- Changes.txt | 9 ++++- src/gui/EditableWidget.cxx | 75 +++++++++++++++++++++++--------------- src/gui/EditableWidget.hxx | 6 +-- 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/Changes.txt b/Changes.txt index 84e4996ad..5ae5b0460 100644 --- a/Changes.txt +++ b/Changes.txt @@ -12,6 +12,13 @@ Release History =========================================================================== +6.4 to 6.5 (December XX, 2020) + + * Enhanced cut/copy/paste to allow selecting text (TODO: PromptWidget, doc) + +-Have fun! + + 6.3 to 6.4 (November 2, 2020) * Added basic (entire and single line only) text cut/copy and paste. @@ -42,8 +49,6 @@ * Fixed bug in ROM launcher, with last ROM selected not being remembered when exiting and re-entering a directory. --Have fun! - 6.2.1 to 6.3 (October 7, 2020) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 20ded2dfc..e4a6750be 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -23,10 +23,6 @@ #include "EventHandler.hxx" #include "EditableWidget.hxx" -// Uncomment the following to give full-line cut/copy/paste -// Note that this will be removed eventually, when we implement proper cut/copy/paste -#define PSEUDO_CUT_COPY_PASTE - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h, const string& str) @@ -148,7 +144,7 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) case KBDK_C: case KBDK_INSERT: - copySelectedText(); + handled = copySelectedText(); break; case KBDK_E: @@ -175,8 +171,9 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) break; case KBDK_V: - pasteSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); + handled = pasteSelectedText(); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_W: @@ -185,8 +182,9 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) break; case KBDK_X: - cutSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); + handled = cutSelectedText(); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_LEFT: @@ -221,13 +219,15 @@ bool EditableWidget::handleShiftKeys(StellaKey key) { case KBDK_DELETE: case KBDK_KP_PERIOD: - cutSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); + handled = cutSelectedText(); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_INSERT: - pasteSelectedText(); - sendCommand(EditableWidget::kChangedCmd, key, _id); + handled = pasteSelectedText(); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case KBDK_LEFT: @@ -662,31 +662,48 @@ bool EditableWidget::killSelectedText() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::cutSelectedText() +bool EditableWidget::cutSelectedText() { -#if defined(PSEUDO_CUT_COPY_PASTE) - instance().eventHandler().copyText(selectString()); - killSelectedText(); -#endif + string selected = selectString(); + + // only cut and copy if anything is selected, else keep old cut text + if(!selected.empty()) + { + instance().eventHandler().copyText(selected); + killSelectedText(); + return true; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::copySelectedText() +bool EditableWidget::copySelectedText() { -#if defined(PSEUDO_CUT_COPY_PASTE) - instance().eventHandler().copyText(selectString()); -#endif + string selected = selectString(); + + // only copy if anything is selected, else keep old copied text + if(!selected.empty()) + { + instance().eventHandler().copyText(selected); + return true; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::pasteSelectedText() +bool EditableWidget::pasteSelectedText() { -#if defined(PSEUDO_CUT_COPY_PASTE) - string text; + bool selected = !selectString().empty(); + string pasted; - instance().eventHandler().pasteText(text); + // retrieve the pasted text + instance().eventHandler().pasteText(pasted); + // remove the currently selected text killSelectedText(); - _editString.insert(_caretPos, text); - _caretPos += int(text.length()); -#endif + // insert paste text instead + _editString.insert(_caretPos, pasted); + // position cursor at the end of pasted text + _caretPos += int(pasted.length()); + + return selected || !pasted.empty(); } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index b30e3ac59..f6ef9dd9e 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -98,9 +98,9 @@ class EditableWidget : public Widget, public CommandSender int selectStartPos(); int selectEndPos(); // Clipboard - void cutSelectedText(); - void copySelectedText(); - void pasteSelectedText(); + bool cutSelectedText(); + bool copySelectedText(); + bool pasteSelectedText(); // Use the current TextFilter to insert a character into the // internal buffer From 12b0e871cb222e10d7aca3ba82d49dbeea232a66 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 5 Nov 2020 11:52:15 +0100 Subject: [PATCH 132/263] fixed tab bug in VideoAudioDialog --- src/gui/VideoAudioDialog.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 01297b62b..47c955b94 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -167,7 +167,7 @@ void VideoAudioDialog::addDisplayTab() // Aspect ratio correction ypos += lineHeight + VGAP * 4; myCorrectAspect = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Correct aspect ratio (*)"); - wid.push_back(myUseStretch); + wid.push_back(myCorrectAspect); // Vertical size ypos += lineHeight + VGAP; From 558a3d999c089541b03c3cba0c4db4788a692843 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 5 Nov 2020 12:50:56 +0100 Subject: [PATCH 133/263] updated HelpDialog added 'Space' for selecting UI elements --- src/common/PKeyboardHandler.cxx | 1 + src/gui/HelpDialog.cxx | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index a1ee45b0e..5151fe191 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -593,6 +593,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuM {Event::UILeft, KBDK_LEFT}, {Event::UIRight, KBDK_RIGHT}, {Event::UISelect, KBDK_RETURN}, + {Event::UISelect, KBDK_SPACE}, {Event::UIHome, KBDK_HOME}, {Event::UIEnd, KBDK_END}, diff --git a/src/gui/HelpDialog.cxx b/src/gui/HelpDialog.cxx index 77c01f174..0b08ca0cc 100644 --- a/src/gui/HelpDialog.cxx +++ b/src/gui/HelpDialog.cxx @@ -134,16 +134,16 @@ void HelpDialog::updateStrings(uInt8 page, uInt8 lines, string& title) case 3: title = "TV effects"; - ADD_EVENT(Event::VidmodeStd, "Disable TV effects"); - ADD_EVENT(Event::VidmodeRGB, "Enable 'RGB' mode"); - ADD_EVENT(Event::VidmodeSVideo, "Enable 'S-Video' mode"); - ADD_EVENT(Event::VidModeComposite, "Enable 'Composite' mode"); - ADD_EVENT(Event::VidModeBad, "Enable 'Badly adjusted' mode"); - ADD_EVENT(Event::VidModeCustom, "Enable 'Custom' mode"); - ADD_EVENT(Event::NextAttribute, "Select 'Custom' attribute"); - ADD_EVENT(Event::IncreaseAttribute, "Modify 'Custom' attribute"); - ADD_EVENT(Event::PhosphorIncrease, "Adjust phosphor blend"); - ADD_EVENT(Event::ScanlinesIncrease, "Adjust scanline intensity"); + ADD_EVENT(Event::NextVideoMode, "Select next TV effect mode"); + ADD_EVENT(Event::PreviousVideoMode, "Select previous TV effect mode"); + ADD_EVENT(Event::NextAttribute, "Select next 'Custom' attribute"); + ADD_EVENT(Event::PreviousAttribute, "Select previous 'Custom' attr."); + ADD_EVENT(Event::IncreaseAttribute, "Increase 'Custom' attribute"); + ADD_EVENT(Event::DecreaseAttribute, "Decrease 'Custom' attribute"); + ADD_EVENT(Event::PhosphorIncrease, "Increase phosphor blend"); + ADD_EVENT(Event::PhosphorDecrease, "Decrease phosphor blend"); + ADD_EVENT(Event::ScanlinesIncrease, "Increase scanline intensity"); + ADD_EVENT(Event::ScanlinesDecrease, "Decrease scanline intensity"); break; case 4: From 3b64e55304e0b8fae4496765753bbb995d7f23b6 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 5 Nov 2020 12:56:36 +0100 Subject: [PATCH 134/263] fixed Ctrl+A in EditableWidget --- src/gui/EditableWidget.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index e4a6750be..e5808ece8 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -138,8 +138,8 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) switch(key) { case KBDK_A: - setCaretPos(0); - _selectSize = -int(_editString.size()); + if(setCaretPos(int(_editString.size()))) + _selectSize = -int(_editString.size()); break; case KBDK_C: From ecb42a5b517a409bbdc9bf52d12ef74b83595f40 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 5 Nov 2020 15:19:33 +0100 Subject: [PATCH 135/263] added filtering to text pasted to EditableWidget updated doc for UI keys (TODO: UI edit keys) --- docs/index.html | 131 +++++++++++++++++++++++++++++++++++-- src/gui/EditableWidget.cxx | 26 +++++++- 2 files changed, 147 insertions(+), 10 deletions(-) diff --git a/docs/index.html b/docs/index.html index 969d3a084..0ac22e5dd 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1364,8 +1364,8 @@
    - - + + - - - - - @@ -1867,8 +1862,129 @@
    ItemBrief descriptionFor more information,
    see Command Line
    PalettePalette used for emulation mode-palette
    NTSC phaseAdjust phase shift for 'Custom' NTSC palette-pal.phase_ntsc
    PAL phaseAdjust phase shift for 'Custom' PAL palette-pal.phase_pal
    NTSC phaseAdjust phase shift of 'Custom' NTSC palette-pal.phase_ntsc
    PAL phaseAdjust phase shift of 'Custom' PAL palette-pal.phase_pal
    RAdjust red scale and shift of 'Custom' palette-pal.red_scale, -pal.red_shift
    GAdjust green scale and shift of 'Custom' palette-pal.green_scale, -pal.green_shift
    BAdjust blue scale and shift of 'Custom' palette-pal.blue_scale, -pal.blue_shift
    HueAdjust hue of currently selected palette-pal.hue
    SaturationAdjust saturation of currently selected palette-pal.saturation
    ContrastAdjust contrast of currently selected palette-pal.contrast
    Toggle windowed/fullscreen modeAlt + EnterCmd + EnterAlt + ReturnCmd + Return
    Toggle adapting display refresh rate to game frame rate @@ -1757,11 +1757,6 @@ Backspace Backspace
    Go to parent directory (UI mode)BackspaceBackspace
    Decrease emulation speed (disables 'Turbo' mode) Shift-Control + s
    +

    UI Keys (can be remapped)

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FunctionKey (Standard)Key (macOS)
    Move UpUp arrowUp arrow
    Move DownDown arrowDown arrow
    Move LeftLeft arrowLeft arrow
    Move RightRight arrowRight arrow
    Move HomeHomeHome
    Move EndEndEnd
    Move Page UpPage UpPage Up
    Move Page DownPage DownPage Down
    OK--
    CancelEscapeEscape
    Select itemReturn/Enter/SpaceReturn/Enter/Space
    Move to previous objectShift + TabShift + Tab
    Move to next objectTabTab
    Move to previous tabShift-Control + TabShift-Control + Tab
    Move to next tabControl + TabControl + Tab
    Go to parent directoryBackspaceBackspace
    Toggle windowed/fullscreen modeAlt + ReturnCmd + Return
    Exit emulatorControl + qCmd + q
    +

    UI Keys in Text Editing areas (cannot be remapped)

    + *** TODO!!! *** + + + + + + + + + + + + + + + + + +
    FunctionKey (Standard)Key (macOS)
    Move cursor to beginning of lineHome, Control + aHome, Control + a
    .........
    +
    + @@ -1884,6 +2000,7 @@
    KeyEditor Function
    Home, Control + aMove cursor to beginning of line
    Control + v, Shift + InsertPaste clipboard contents
    Control + x, Shift + DeleteCut entire line to clipboard
    +

    Controller Map

    diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index e5808ece8..f58da8c7f 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -187,6 +187,10 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) sendCommand(EditableWidget::kChangedCmd, key, _id); break; + case KBDK_Z: + // TODO: undo + break; + case KBDK_LEFT: handled = moveWord(-1, shift); if(!shift) @@ -700,10 +704,26 @@ bool EditableWidget::pasteSelectedText() instance().eventHandler().pasteText(pasted); // remove the currently selected text killSelectedText(); - // insert paste text instead - _editString.insert(_caretPos, pasted); + // insert filtered paste text instead + ostringstream buf; + bool lastOk = true; // only one filler char per invalid character (block) + + for(char c : pasted) + if(_filter(tolower(c))) + { + buf << c; + lastOk = true; + } + else + { + if(lastOk) + buf << '_'; + lastOk = false; + } + + _editString.insert(_caretPos, buf.str()); // position cursor at the end of pasted text - _caretPos += int(pasted.length()); + _caretPos += int(buf.str().length()); return selected || !pasted.empty(); } From 251661331e9c51bf97c0b34e2956511730a365bd Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 5 Nov 2020 13:20:45 -0330 Subject: [PATCH 136/263] Fix avoxport popup not selecting correct device in InputDialog. Incidentally, I think we should change VarList::push_back() to not allow this type of error to happen. Having to pass two parameters with the same value seems to be very hacky. --- src/gui/InputDialog.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index e48a1fe61..d5d847f1b 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -365,7 +365,7 @@ void InputDialog::loadConfig() VariantList items; for(const auto& port: ports) - VarList::push_back(items, port); + VarList::push_back(items, port, port); if(avoxport != EmptyString && !BSPF::contains(ports, avoxport)) VarList::push_back(items, avoxport, avoxport); if(items.size() == 0) From 06813747f558cd2ec8d00f7777ce4eb7bce4701b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 5 Nov 2020 22:16:58 +0100 Subject: [PATCH 137/263] added undo/redo to EditableWidget --- src/common/EventHandlerSDL2.cxx | 9 ++++ src/emucore/EventHandler.hxx | 10 ++++ src/gui/EditableWidget.cxx | 93 ++++++++++++++++++++++++++++++--- src/gui/EditableWidget.hxx | 13 ++++- 4 files changed, 115 insertions(+), 10 deletions(-) diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index 45d31ce9e..e5900cfba 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -27,6 +27,15 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem) { ASSERT_MAIN_THREAD; +#ifdef GUI_SUPPORT + { + ostringstream buf; + myQwertz = int('y') == int(SDL_GetKeyFromScancode(SDL_Scancode(KBDK_Z))); + buf << "Keyboard: " << (myQwertz ? "QWERTZ" : "QWERTY"); + Logger::debug(buf.str()); + } +#endif + #ifdef JOYSTICK_SUPPORT if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) { diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 8649bd9e0..3833f7bec 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -338,6 +338,11 @@ class EventHandler virtual void enableTextEvents(bool enable) = 0; #ifdef GUI_SUPPORT + /** + Check for QWERTZ keyboard layout + */ + bool isQwertz() { return myQwertz; } + /** Clipboard methods. */ @@ -359,6 +364,11 @@ class EventHandler // Global OSystem object OSystem& myOSystem; + #ifdef GUI_SUPPORT + // Keyboard layout + bool myQwertz{false}; + #endif + /** Methods which are called by derived classes to handle specific types of input. diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index f58da8c7f..76b592516 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -47,6 +47,9 @@ void EditableWidget::setText(const string& str, bool) if(_filter(tolower(c))) _editString.push_back(c); + clearEdits(); + doEdit(); + _caretPos = int(_editString.size()); _selectSize = 0; @@ -78,12 +81,64 @@ void EditableWidget::lostFocusWidget() _selectSize = 0; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EditableWidget::clearEdits() +{ + _editBuffer.clear(); + _redoCount = 0; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EditableWidget::doEdit() +{ + constexpr size_t UNDO_SIZE = 100; + + // clear redos + for(; _redoCount; _redoCount--) + _editBuffer.pop_back(); + + if(_editBuffer.size() == UNDO_SIZE) + _editBuffer.pop_front(); + _editBuffer.push_back(_editString); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::undoEdit() +{ + if(_editBuffer.size() - _redoCount - 1) + { + _redoCount++; + _editString = _editBuffer[_editBuffer.size() - _redoCount - 1]; + _caretPos = int(_editString.size()); // TODO: put at last difference + _selectSize = 0; + + return true; + } + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::redoEdit() +{ + if(_redoCount) + { + _redoCount--; + _editString = _editBuffer[_editBuffer.size() - _redoCount - 1]; + _caretPos = int(_editString.size()); // TODO: put at last difference + _selectSize = 0; + + return true; + } + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::tryInsertChar(char c, int pos) { if(_filter(tolower(c))) { _editString.insert(pos, 1, c); + doEdit(); return true; } return false; @@ -187,8 +242,12 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) sendCommand(EditableWidget::kChangedCmd, key, _id); break; + case KBDK_Y: case KBDK_Z: - // TODO: undo + if(key == KBDK_Y != instance().eventHandler().isQwertz()) + dirty = redoEdit(); + else + dirty = undoEdit(); break; case KBDK_LEFT: @@ -469,7 +528,7 @@ int EditableWidget::scrollOffset() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::killChar(int direction) +bool EditableWidget::killChar(int direction, bool addEdit) { bool handled = false; @@ -480,12 +539,20 @@ bool EditableWidget::killChar(int direction) _caretPos--; _editString.erase(_caretPos, 1); handled = true; + if(_selectSize < 0) + _selectSize++; + if(addEdit) + doEdit(); } } else if(direction == 1) // Delete next character (delete) { _editString.erase(_caretPos, 1); handled = true; + if(_selectSize > 0) + _selectSize--; + if(addEdit) + doEdit(); } return handled; @@ -502,12 +569,13 @@ bool EditableWidget::killLine(int direction) if(count > 0) { for (int i = 0; i < count; i++) - killChar(-1); + killChar(-1, false); handled = true; // remove selection for removed text if(_selectSize < 0) _selectSize = 0; + doEdit(); } } else if(direction == 1) // erase from current position to end of line @@ -516,12 +584,13 @@ bool EditableWidget::killLine(int direction) if(count > 0) { for (int i = 0; i < count; i++) - killChar(+1); + killChar(+1, false); handled = true; // remove selection for removed text if(_selectSize > 0) _selectSize = 0; + doEdit(); } } @@ -551,12 +620,13 @@ bool EditableWidget::killLastWord() if(count > 0) { for (int i = 0; i < count; i++) - killChar(-1); + killChar(-1, false); handled = true; // remove selection for removed word if(_selectSize < 0) _selectSize = std::min(_selectSize + count, 0); + doEdit(); } return handled; @@ -649,7 +719,7 @@ int EditableWidget::selectEndPos() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::killSelectedText() +bool EditableWidget::killSelectedText(bool addEdit) { if(_selectSize) { @@ -660,6 +730,8 @@ bool EditableWidget::killSelectedText() } _editString.erase(_caretPos, _selectSize); _selectSize = 0; + if(addEdit) + doEdit(); return true; } return false; @@ -703,7 +775,7 @@ bool EditableWidget::pasteSelectedText() // retrieve the pasted text instance().eventHandler().pasteText(pasted); // remove the currently selected text - killSelectedText(); + killSelectedText(false); // insert filtered paste text instead ostringstream buf; bool lastOk = true; // only one filler char per invalid character (block) @@ -725,5 +797,10 @@ bool EditableWidget::pasteSelectedText() // position cursor at the end of pasted text _caretPos += int(buf.str().length()); - return selected || !pasted.empty(); + if(selected || !pasted.empty()) + { + doEdit(); + return true; + } + return false; } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index f6ef9dd9e..4d5ff71dc 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -19,6 +19,7 @@ #define EDITABLE_WIDGET_HXX #include +#include #include "Widget.hxx" #include "Rect.hxx" @@ -89,18 +90,23 @@ class EditableWidget : public Widget, public CommandSender bool handleControlKeys(StellaKey key, StellaMod mod); bool handleShiftKeys(StellaKey key); bool handleNormalKeys(StellaKey key); - bool killChar(int direction); + bool killChar(int direction, bool addEdit = true); bool killLine(int direction); bool killLastWord(); bool moveWord(int direction, bool select); - bool killSelectedText(); + bool killSelectedText(bool addEdit = true); int selectStartPos(); int selectEndPos(); // Clipboard bool cutSelectedText(); bool copySelectedText(); bool pasteSelectedText(); + // Undo + void clearEdits(); + void doEdit(); + bool undoEdit(); + bool redoEdit(); // Use the current TextFilter to insert a character into the // internal buffer @@ -109,6 +115,9 @@ class EditableWidget : public Widget, public CommandSender private: bool _editable{true}; string _editString; + + std::deque _editBuffer; + int _redoCount{0}; int _caretPos{0}; // Size of current selected text // 0 = no selection From f4ab26f350a4b0224f49f94aa3e027368f379d61 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 6 Nov 2020 09:54:54 +0100 Subject: [PATCH 138/263] refactored undo functionality into UndoHandler class --- src/gui/EditableWidget.cxx | 80 +++++++----------------------- src/gui/EditableWidget.hxx | 11 ++-- src/gui/UndoHandler.cxx | 70 ++++++++++++++++++++++++++ src/gui/UndoHandler.hxx | 53 ++++++++++++++++++++ src/gui/module.mk | 1 + src/windows/Stella.vcxproj | 2 + src/windows/Stella.vcxproj.filters | 6 +++ 7 files changed, 152 insertions(+), 71 deletions(-) create mode 100644 src/gui/UndoHandler.cxx create mode 100644 src/gui/UndoHandler.hxx diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 76b592516..d7f0e4aea 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -21,6 +21,7 @@ #include "Font.hxx" #include "OSystem.hxx" #include "EventHandler.hxx" +#include "UndoHandler.hxx" #include "EditableWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -36,6 +37,8 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font, _bgcolorlo = kDlgColor; _textcolor = kTextColor; _textcolorhi = kTextColor; + + myUndoHandler = make_unique(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -47,8 +50,8 @@ void EditableWidget::setText(const string& str, bool) if(_filter(tolower(c))) _editString.push_back(c); - clearEdits(); - doEdit(); + myUndoHandler->reset(); + myUndoHandler->doo(_editString); _caretPos = int(_editString.size()); _selectSize = 0; @@ -81,64 +84,13 @@ void EditableWidget::lostFocusWidget() _selectSize = 0; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::clearEdits() -{ - _editBuffer.clear(); - _redoCount = 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::doEdit() -{ - constexpr size_t UNDO_SIZE = 100; - - // clear redos - for(; _redoCount; _redoCount--) - _editBuffer.pop_back(); - - if(_editBuffer.size() == UNDO_SIZE) - _editBuffer.pop_front(); - _editBuffer.push_back(_editString); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::undoEdit() -{ - if(_editBuffer.size() - _redoCount - 1) - { - _redoCount++; - _editString = _editBuffer[_editBuffer.size() - _redoCount - 1]; - _caretPos = int(_editString.size()); // TODO: put at last difference - _selectSize = 0; - - return true; - } - return false; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::redoEdit() -{ - if(_redoCount) - { - _redoCount--; - _editString = _editBuffer[_editBuffer.size() - _redoCount - 1]; - _caretPos = int(_editString.size()); // TODO: put at last difference - _selectSize = 0; - - return true; - } - return false; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::tryInsertChar(char c, int pos) { if(_filter(tolower(c))) { _editString.insert(pos, 1, c); - doEdit(); + myUndoHandler->doo(_editString); return true; } return false; @@ -245,9 +197,11 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) case KBDK_Y: case KBDK_Z: if(key == KBDK_Y != instance().eventHandler().isQwertz()) - dirty = redoEdit(); + dirty = myUndoHandler->redo(_editString); else - dirty = undoEdit(); + dirty = myUndoHandler->undo(_editString); + _caretPos = int(_editString.size()); // TODO: put at last difference + _selectSize = 0; break; case KBDK_LEFT: @@ -542,7 +496,7 @@ bool EditableWidget::killChar(int direction, bool addEdit) if(_selectSize < 0) _selectSize++; if(addEdit) - doEdit(); + myUndoHandler->doo(_editString); } } else if(direction == 1) // Delete next character (delete) @@ -552,7 +506,7 @@ bool EditableWidget::killChar(int direction, bool addEdit) if(_selectSize > 0) _selectSize--; if(addEdit) - doEdit(); + myUndoHandler->doo(_editString); } return handled; @@ -575,7 +529,7 @@ bool EditableWidget::killLine(int direction) // remove selection for removed text if(_selectSize < 0) _selectSize = 0; - doEdit(); + myUndoHandler->doo(_editString); } } else if(direction == 1) // erase from current position to end of line @@ -590,7 +544,7 @@ bool EditableWidget::killLine(int direction) // remove selection for removed text if(_selectSize > 0) _selectSize = 0; - doEdit(); + myUndoHandler->doo(_editString); } } @@ -626,7 +580,7 @@ bool EditableWidget::killLastWord() // remove selection for removed word if(_selectSize < 0) _selectSize = std::min(_selectSize + count, 0); - doEdit(); + myUndoHandler->doo(_editString); } return handled; @@ -731,7 +685,7 @@ bool EditableWidget::killSelectedText(bool addEdit) _editString.erase(_caretPos, _selectSize); _selectSize = 0; if(addEdit) - doEdit(); + myUndoHandler->doo(_editString); return true; } return false; @@ -799,7 +753,7 @@ bool EditableWidget::pasteSelectedText() if(selected || !pasted.empty()) { - doEdit(); + myUndoHandler->doo(_editString); return true; } return false; diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 4d5ff71dc..66c8dc20e 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -19,10 +19,10 @@ #define EDITABLE_WIDGET_HXX #include -#include #include "Widget.hxx" #include "Rect.hxx" +#include "UndoHandler.hxx" /** * Base class for widgets which need to edit text, like ListWidget and @@ -102,11 +102,6 @@ class EditableWidget : public Widget, public CommandSender bool cutSelectedText(); bool copySelectedText(); bool pasteSelectedText(); - // Undo - void clearEdits(); - void doEdit(); - bool undoEdit(); - bool redoEdit(); // Use the current TextFilter to insert a character into the // internal buffer @@ -115,10 +110,10 @@ class EditableWidget : public Widget, public CommandSender private: bool _editable{true}; string _editString; + unique_ptr myUndoHandler; - std::deque _editBuffer; - int _redoCount{0}; int _caretPos{0}; + // Size of current selected text // 0 = no selection // <0 = selected left of caret diff --git a/src/gui/UndoHandler.cxx b/src/gui/UndoHandler.cxx new file mode 100644 index 000000000..756dbb19a --- /dev/null +++ b/src/gui/UndoHandler.cxx @@ -0,0 +1,70 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "UndoHandler.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +UndoHandler::UndoHandler(size_t size) + : myRedoCount(0), + mySize(size) +{} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void UndoHandler::reset() +{ + myBuffer.clear(); + myRedoCount = 0; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void UndoHandler::doo(const string& text) +{ + // clear redos + for(; myRedoCount; myRedoCount--) + myBuffer.pop_front(); + + // limit buffer size + if(myBuffer.size() == mySize) + myBuffer.pop_back(); + + // add text to buffer + myBuffer.push_front(text); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool UndoHandler::undo(string& text) +{ + if(myBuffer.size() > myRedoCount + 1) + { + text = myBuffer[++myRedoCount]; + + return true; + } + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool UndoHandler::redo(string& text) +{ + if(myRedoCount) + { + text = myBuffer[--myRedoCount]; + + return true; + } + return false; +} diff --git a/src/gui/UndoHandler.hxx b/src/gui/UndoHandler.hxx new file mode 100644 index 000000000..42630671f --- /dev/null +++ b/src/gui/UndoHandler.hxx @@ -0,0 +1,53 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + + +#ifndef UNDO_HANDLER_HXX +#define UNDO_HANDLER_HXX + +#include "bspf.hxx" +#include + +/** + * Class for providing undo/redo functionality + * + * @author Thomas Jentzsch + */ +class UndoHandler +{ + public: + UndoHandler(size_t size = 100); + ~UndoHandler() = default; + + void reset(); + void doo(const string& text); + bool undo(string& text); + bool redo(string& text); + + private: + std::deque myBuffer; + size_t mySize; + uInt32 myRedoCount; + + private: + // Following constructors and assignment operators not supported + UndoHandler(const UndoHandler&) = delete; + UndoHandler(UndoHandler&&) = delete; + UndoHandler& operator=(const UndoHandler&) = delete; + UndoHandler& operator=(UndoHandler&&) = delete; +}; +#endif diff --git a/src/gui/module.mk b/src/gui/module.mk index d7412d2a2..a2f8489fd 100644 --- a/src/gui/module.mk +++ b/src/gui/module.mk @@ -49,6 +49,7 @@ MODULE_OBJS := \ src/gui/TimeLineWidget.o \ src/gui/TimeMachineDialog.o \ src/gui/TimeMachine.o \ + src/gui/UndoHandler.o \ src/gui/UIDialog.o \ src/gui/VideoAudioDialog.o \ src/gui/WhatsNewDialog.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 420c63513..5f0bd9126 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -786,6 +786,7 @@ + @@ -1837,6 +1838,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 44f2539a2..8dca2be2e 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1029,6 +1029,9 @@ Source Files + + Source Files\gui + @@ -2117,6 +2120,9 @@ Header Files\emucore + + Header Files\gui + From e94f5461d57e77025d0dbcc0aac41af83be14109 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 6 Nov 2020 09:25:08 -0330 Subject: [PATCH 139/263] Added UndoHandler to Xcode, and fixed minor warnings. --- src/gui/UndoHandler.cxx | 6 +++--- src/gui/UndoHandler.hxx | 5 +++-- src/macos/stella.xcodeproj/project.pbxproj | 8 ++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/gui/UndoHandler.cxx b/src/gui/UndoHandler.cxx index 756dbb19a..daaa95bd3 100644 --- a/src/gui/UndoHandler.cxx +++ b/src/gui/UndoHandler.cxx @@ -19,9 +19,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UndoHandler::UndoHandler(size_t size) - : myRedoCount(0), - mySize(size) -{} + : mySize(size) +{ +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void UndoHandler::reset() diff --git a/src/gui/UndoHandler.hxx b/src/gui/UndoHandler.hxx index 42630671f..b9e832880 100644 --- a/src/gui/UndoHandler.hxx +++ b/src/gui/UndoHandler.hxx @@ -40,8 +40,8 @@ class UndoHandler private: std::deque myBuffer; - size_t mySize; - uInt32 myRedoCount; + size_t mySize{0}; + uInt32 myRedoCount{0}; private: // Following constructors and assignment operators not supported @@ -50,4 +50,5 @@ class UndoHandler UndoHandler& operator=(const UndoHandler&) = delete; UndoHandler& operator=(UndoHandler&&) = delete; }; + #endif diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index d5e4a0e9e..4452ddce2 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -522,6 +522,8 @@ DCB60AD12543100900A5C1D2 /* FBBackendSDL2.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB60ACE2543100900A5C1D2 /* FBBackendSDL2.hxx */; }; DCB60AD22543100900A5C1D2 /* audio in Resources */ = {isa = PBXBuildFile; fileRef = DCB60ACF2543100900A5C1D2 /* audio */; }; DCB87E581A104C1E00BF2A3B /* MediaFactory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB87E571A104C1E00BF2A3B /* MediaFactory.hxx */; }; + DCBA539925557E2800087DD7 /* UndoHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBA539725557E2700087DD7 /* UndoHandler.hxx */; }; + DCBA539A25557E2800087DD7 /* UndoHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCBA539825557E2800087DD7 /* UndoHandler.cxx */; }; DCBD31E82299ADB400567357 /* KeyMap.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBD31E52299ADB400567357 /* KeyMap.hxx */; }; DCBD31E92299ADB400567357 /* Rect.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBD31E62299ADB400567357 /* Rect.hxx */; }; DCBD31EA2299ADB400567357 /* KeyMap.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCBD31E72299ADB400567357 /* KeyMap.cxx */; }; @@ -1286,6 +1288,8 @@ DCB60ACE2543100900A5C1D2 /* FBBackendSDL2.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FBBackendSDL2.hxx; sourceTree = ""; }; DCB60ACF2543100900A5C1D2 /* audio */ = {isa = PBXFileReference; lastKnownFileType = folder; path = audio; sourceTree = ""; }; DCB87E571A104C1E00BF2A3B /* MediaFactory.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MediaFactory.hxx; sourceTree = ""; }; + DCBA539725557E2700087DD7 /* UndoHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = UndoHandler.hxx; sourceTree = ""; }; + DCBA539825557E2800087DD7 /* UndoHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UndoHandler.cxx; sourceTree = ""; }; DCBA710010DED62E0077193B /* Stella.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stella.app; sourceTree = BUILT_PRODUCTS_DIR; }; DCBD31E52299ADB400567357 /* KeyMap.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KeyMap.hxx; sourceTree = ""; }; DCBD31E62299ADB400567357 /* Rect.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Rect.hxx; sourceTree = ""; }; @@ -2165,6 +2169,8 @@ DCA82C701FEB4E780059340F /* TimeMachineDialog.hxx */, DC8078E60B4BD697005E9305 /* UIDialog.cxx */, DC8078E70B4BD697005E9305 /* UIDialog.hxx */, + DCBA539825557E2800087DD7 /* UndoHandler.cxx */, + DCBA539725557E2700087DD7 /* UndoHandler.hxx */, DC3C9BC72469C93D00CF2D47 /* VideoAudioDialog.cxx */, DC3C9BC92469C93D00CF2D47 /* VideoAudioDialog.hxx */, DC1E474C24D34F3A0047E61A /* WhatsNewDialog.cxx */, @@ -2513,6 +2519,7 @@ DCE8B1871E7E03B300189864 /* FrameLayout.hxx in Headers */, DCA233B523BAB1300032ABF3 /* Lightgun.hxx in Headers */, DCBD31E92299ADB400567357 /* Rect.hxx in Headers */, + DCBA539925557E2800087DD7 /* UndoHandler.hxx in Headers */, 2D91741A09BA90380026E9FF /* FSNode.hxx in Headers */, 2D91741B09BA90380026E9FF /* OSystem.hxx in Headers */, DC6A18F919B3E65500DEB242 /* CartMDMWidget.hxx in Headers */, @@ -3166,6 +3173,7 @@ DCAAE5F01715887B0080BB82 /* CartFAWidget.cxx in Sources */, DCAAE5F21715887B0080BB82 /* CartUAWidget.cxx in Sources */, DC676A411729A0B000E4E73D /* Cart3EWidget.cxx in Sources */, + DCBA539A25557E2800087DD7 /* UndoHandler.cxx in Sources */, DC676A431729A0B000E4E73D /* Cart4A50Widget.cxx in Sources */, DC3EE85A1E2C0E6D00905161 /* deflate.c in Sources */, DC676A451729A0B000E4E73D /* CartARWidget.cxx in Sources */, From d0d55a8fec76f806f5d12eee552cbec15abea578 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 6 Nov 2020 14:38:33 +0100 Subject: [PATCH 140/263] added single char aggregation for undos fixed potential bug when moving cursor one word left --- src/gui/EditableWidget.cxx | 73 ++++++++++++++++++++++++-------------- src/gui/UndoHandler.cxx | 36 +++++++++++++++++++ src/gui/UndoHandler.hxx | 17 +++++++++ 3 files changed, 99 insertions(+), 27 deletions(-) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index d7f0e4aea..48bc79013 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -90,7 +90,7 @@ bool EditableWidget::tryInsertChar(char c, int pos) if(_filter(tolower(c))) { _editString.insert(pos, 1, c); - myUndoHandler->doo(_editString); + myUndoHandler->doChar(); // aggregate single chars return true; } return false; @@ -140,7 +140,6 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) { bool shift = StellaModTest::isShift(mod); bool handled = true; - bool dirty = true; switch(key) { @@ -154,13 +153,13 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) handled = copySelectedText(); break; - case KBDK_E: - if(shift) - _selectSize += _caretPos - int(_editString.size()); - else - _selectSize = 0; - setCaretPos(int(_editString.size())); - break; + //case KBDK_E: + // if(shift) + // _selectSize += _caretPos - int(_editString.size()); + // else + // _selectSize = 0; + // setCaretPos(int(_editString.size())); + // break; case KBDK_D: handled = killChar(+1); @@ -196,13 +195,29 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) case KBDK_Y: case KBDK_Z: + { + string oldString = _editString; + + myUndoHandler->endChars(_editString); + // Reverse Y and Z for QWERTZ keyboards if(key == KBDK_Y != instance().eventHandler().isQwertz()) - dirty = myUndoHandler->redo(_editString); + handled = myUndoHandler->redo(_editString); else - dirty = myUndoHandler->undo(_editString); - _caretPos = int(_editString.size()); // TODO: put at last difference - _selectSize = 0; + if(shift) + handled = myUndoHandler->redo(_editString); + else + handled = myUndoHandler->undo(_editString); + + if(handled) + { + // Put caret at last difference + myUndoHandler->lastDiff(_editString, oldString); + _caretPos = myUndoHandler->lastDiff(_editString, oldString); + _selectSize = 0; + sendCommand(EditableWidget::kChangedCmd, key, _id); + } break; + } case KBDK_LEFT: handled = moveWord(-1, shift); @@ -218,11 +233,13 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) default: handled = false; - dirty = false; } - if(dirty) + if(handled) + { + myUndoHandler->endChars(_editString); setDirty(); + } return handled; } @@ -271,7 +288,10 @@ bool EditableWidget::handleShiftKeys(StellaKey key) } if(handled) + { + myUndoHandler->endChars(_editString); setDirty(); + } return handled; } @@ -321,7 +341,7 @@ bool EditableWidget::handleNormalKeys(StellaKey key) break; case KBDK_LEFT: - if (_selectSize) + if(_selectSize) handled = setCaretPos(selectStartPos()); else if(_caretPos > 0) handled = setCaretPos(_caretPos - 1); @@ -348,7 +368,10 @@ bool EditableWidget::handleNormalKeys(StellaKey key) } if(handled) + { + myUndoHandler->endChars(_editString); setDirty(); + } if(!selectMode) _selectSize = 0; @@ -490,6 +513,7 @@ bool EditableWidget::killChar(int direction, bool addEdit) { if(_caretPos > 0) { + myUndoHandler->endChars(_editString); _caretPos--; _editString.erase(_caretPos, 1); handled = true; @@ -501,6 +525,7 @@ bool EditableWidget::killChar(int direction, bool addEdit) } else if(direction == 1) // Delete next character (delete) { + myUndoHandler->endChars(_editString); _editString.erase(_caretPos, 1); handled = true; if(_selectSize > 0) @@ -616,7 +641,7 @@ bool EditableWidget::moveWord(int direction, bool select) { while (currentPos < int(_editString.size())) { - if (_editString[currentPos - 1] == ' ') + if (currentPos && _editString[currentPos - 1] == ' ') { if (!space) break; @@ -677,6 +702,7 @@ bool EditableWidget::killSelectedText(bool addEdit) { if(_selectSize) { + myUndoHandler->endChars(_editString); if(_selectSize < 0) { _caretPos += _selectSize; @@ -694,16 +720,7 @@ bool EditableWidget::killSelectedText(bool addEdit) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::cutSelectedText() { - string selected = selectString(); - - // only cut and copy if anything is selected, else keep old cut text - if(!selected.empty()) - { - instance().eventHandler().copyText(selected); - killSelectedText(); - return true; - } - return false; + return copySelectedText() && killSelectedText(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -726,6 +743,8 @@ bool EditableWidget::pasteSelectedText() bool selected = !selectString().empty(); string pasted; + myUndoHandler->endChars(_editString); + // retrieve the pasted text instance().eventHandler().pasteText(pasted); // remove the currently selected text diff --git a/src/gui/UndoHandler.cxx b/src/gui/UndoHandler.cxx index daaa95bd3..92dd4d2d8 100644 --- a/src/gui/UndoHandler.cxx +++ b/src/gui/UndoHandler.cxx @@ -21,15 +21,35 @@ UndoHandler::UndoHandler(size_t size) : mySize(size) { + reset(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void UndoHandler::reset() { myBuffer.clear(); + myCharMode = false; myRedoCount = 0; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void UndoHandler::doChar() +{ + myCharMode = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool UndoHandler::endChars(const string& text) +{ + if(myCharMode) + { + doo(text); + + return true; + } + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void UndoHandler::doo(const string& text) { @@ -43,6 +63,7 @@ void UndoHandler::doo(const string& text) // add text to buffer myBuffer.push_front(text); + myCharMode = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -68,3 +89,18 @@ bool UndoHandler::redo(string& text) } return false; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 UndoHandler::lastDiff(const string& text, const string& oldText) const +{ + uInt32 pos = uInt32(text.size()); + + for(auto itn = text.crbegin(), ito = oldText.crbegin(); + itn != text.crend() && ito != oldText.crend(); ++itn, ++ito) + { + if(*itn != *ito) + break; + pos--; + } + return uInt32(pos); +} \ No newline at end of file diff --git a/src/gui/UndoHandler.hxx b/src/gui/UndoHandler.hxx index b9e832880..499423caf 100644 --- a/src/gui/UndoHandler.hxx +++ b/src/gui/UndoHandler.hxx @@ -33,14 +33,31 @@ class UndoHandler UndoHandler(size_t size = 100); ~UndoHandler() = default; + // Reset undo buffer void reset(); + + // Add input to undo buffer void doo(const string& text); + // Retrieve last input from undo buffer bool undo(string& text); + // Retrieve next input from undo buffer bool redo(string& text); + // Add single char for aggregation + void doChar(); + // Add aggregated single chars to undo buffer + bool endChars(const string& text); + + // Get index into text of last different character + uInt32 lastDiff(const string& text, const string& oldText) const; + private: std::deque myBuffer; + // Undo buffer size size_t mySize{0}; + // Aggregated single chars flag + bool myCharMode{false}; + // Number of chars available for redo uInt32 myRedoCount{0}; private: From 9bb30a9bc2db7638b2ad410e7c232c64b15752e0 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 6 Nov 2020 18:16:21 +0100 Subject: [PATCH 141/263] refactored EditableWidget to use events instead of scancodes (TODO: text, MacOS keys) --- src/common/PKeyboardHandler.cxx | 76 +++++++ src/common/PKeyboardHandler.hxx | 1 + src/emucore/Event.hxx | 8 + src/emucore/EventHandler.cxx | 5 + src/emucore/EventHandler.hxx | 1 + src/emucore/EventHandlerConstants.hxx | 1 + src/gui/EditableWidget.cxx | 306 +++++++++----------------- src/gui/EditableWidget.hxx | 3 - 8 files changed, 201 insertions(+), 200 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 5151fe191..aefccb0f6 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -29,6 +29,8 @@ #if defined(BSPF_MACOS) || defined(MACOS_KEYS) static constexpr int MOD3 = KBDM_GUI; +static constexpr int CMD = KBDM_GUI; +static constexpr int OPTION = KBDM_ALT; #else static constexpr int MOD3 = KBDM_ALT; #endif @@ -60,6 +62,7 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler& setDefaultMapping(Event::NoType, EventMode::kEmulationMode, updateDefaults); setDefaultMapping(Event::NoType, EventMode::kMenuMode, updateDefaults); + setDefaultMapping(Event::NoType, EventMode::kEditMode, updateDefaults); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -151,6 +154,12 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod setDefaultKey(item, event, EventMode::kMenuMode, updateDefaults); break; + case EventMode::kEditMode: + // Edit mode events are always set because they are not saved + for(const auto& item : FixedEditMapping) + setDefaultKey(item, event, EventMode::kEditMode); + break; + default: break; } @@ -641,6 +650,73 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuM #endif }; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMapping = { +// TOOD: check MacOS mappings + {Event::MoveLeftChar, KBDK_LEFT}, + {Event::MoveRightChar, KBDK_RIGHT}, + {Event::SelectLeftChar, KBDK_LEFT, KBDM_SHIFT}, + {Event::SelectRightChar, KBDK_RIGHT, KBDM_SHIFT}, +#ifdef BSPF_MACOS + {Event::MoveLeftWord, KBDK_LEFT, CMD}, +// {Event::MoveRightWord, KBDK_RIGHT, KBDM_CTRL}, + {Event::MoveHome, KBDK_LEFT, CMD}, + {Event::MoveHome, KBDK_A, KBDM_CTRL}, + {Event::MoveEnd, KBDK_RIGHT, CMD}, + {Event::MoveEnd, KBDK_E, KBDM_CTRL}, + {Event::SelectLeftWord, KBDK_LEFT, KBDM_SHIFT | OPTION}, +// {Event::SelectRightWord, KBDK_RIGHT, KBDM_SHIFT | OPTION}, + {Event::SelectHome, KBDK_A, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectHome, KBDK_LEFT, KBDM_SHIFT | CMD}, + {Event::SelectEnd, KBDK_E, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectEnd, KBDK_RIGHT, KBDM_SHIFT | CMD}, + {Event::SelectAll, KBDK_A, CMD}, + {Event::Delete, KBDK_DELETE}, + {Event::Delete, KBDK_KP_PERIOD}, // ??? +// {Event::DeleteChar, }, // ??? + {Event::DeleteWord, KBDK_W, OPTION}, + {Event::DeleteHome, KBDK_BACKSPACE, CMD}, + {Event::DeleteEnd, KBDK_BACKSPACE, KBDM_SHIFT | KBDM_CTRL}, + {Event::Backspace, KBDK_BACKSPACE}, // ??? + {Event::Undo, KBDK_Z, CMD}, + {Event::Redo, KBDK_Y, CMD}, + {Event::Redo, KBDK_Z, KBDM_SHIFT | CMD}, + {Event::Cut, KBDK_X, CMD}, + {Event::Copy, KBDK_C, CMD}, + {Event::Paste, KBDK_V, CMD}, +#else + {Event::MoveLeftWord, KBDK_LEFT, KBDM_CTRL}, + {Event::MoveRightWord, KBDK_RIGHT, KBDM_CTRL}, + {Event::MoveHome, KBDK_HOME}, + {Event::MoveEnd, KBDK_END}, + {Event::SelectLeftWord, KBDK_LEFT, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectRightWord, KBDK_RIGHT, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectHome, KBDK_HOME, KBDM_SHIFT}, + {Event::SelectEnd, KBDK_END, KBDM_SHIFT}, + {Event::SelectAll, KBDK_A, KBDM_CTRL}, + {Event::Delete, KBDK_DELETE}, + {Event::Delete, KBDK_KP_PERIOD}, + {Event::DeleteChar, KBDK_D, KBDM_CTRL}, + {Event::DeleteWord, KBDK_W, KBDM_CTRL}, + {Event::DeleteHome, KBDK_U, KBDM_CTRL}, + {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, + {Event::Backspace, KBDK_BACKSPACE}, + {Event::Undo, KBDK_Z, KBDM_CTRL}, + {Event::Redo, KBDK_Y, KBDM_CTRL}, + {Event::Redo, KBDK_Z, KBDM_SHIFT | KBDM_CTRL}, + {Event::Cut, KBDK_X, KBDM_CTRL}, + {Event::Cut, KBDK_DELETE, KBDM_SHIFT}, + {Event::Cut, KBDK_KP_PERIOD, KBDM_SHIFT}, + {Event::Copy, KBDK_C, KBDM_CTRL}, + {Event::Copy, KBDK_INSERT, KBDM_CTRL}, + {Event::Paste, KBDK_V, KBDM_CTRL}, + {Event::Paste, KBDK_INSERT, KBDM_SHIFT}, +#endif + {Event::EndEdit, KBDK_RETURN}, + {Event::EndEdit, KBDK_KP_ENTER}, + {Event::AbortEdit, KBDK_ESCAPE}, +}; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoystickMapping = { {Event::JoystickZeroUp, KBDK_UP}, diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx index ede6aa55a..8ebfd5acb 100644 --- a/src/common/PKeyboardHandler.hxx +++ b/src/common/PKeyboardHandler.hxx @@ -132,6 +132,7 @@ class PhysicalKeyboardHandler // Controller menu and common emulation mappings static EventMappingArray DefaultMenuMapping; + static EventMappingArray FixedEditMapping; static EventMappingArray DefaultCommonMapping; // Controller specific mappings static EventMappingArray DefaultJoystickMapping; diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index d71f9a2e6..87a609834 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -136,6 +136,14 @@ class Event ToggleCorrectAspectRatio, + MoveLeftChar, MoveRightChar, MoveLeftWord, MoveRightWord, + MoveHome, MoveEnd, + SelectLeftChar, SelectRightChar, SelectLeftWord, SelectRightWord, + SelectHome, SelectEnd, SelectAll, + Delete, DeleteChar, DeleteWord, DeleteHome, DeleteEnd, Backspace, + Cut, Copy, Paste, Undo, Redo, + AbortEdit, EndEdit, + LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index f0da1226c..3ce9a4da5 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -2830,3 +2830,8 @@ const Event::EventSet EventHandler::DebugEvents = { Event::ToggleColorLoss, Event::ToggleJitter, }; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const Event::EventSet EventHandler::EditEvents = { + +}; diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 3833f7bec..5671e1291 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -511,6 +511,7 @@ class EventHandler static const Event::EventSet KeyboardEvents; static const Event::EventSet ComboEvents; static const Event::EventSet DebugEvents; + static const Event::EventSet EditEvents; /** The following methods take care of assigning action mappings. diff --git a/src/emucore/EventHandlerConstants.hxx b/src/emucore/EventHandlerConstants.hxx index 0009af3d3..b67df420f 100644 --- a/src/emucore/EventHandlerConstants.hxx +++ b/src/emucore/EventHandlerConstants.hxx @@ -79,6 +79,7 @@ static const int NUM_PORTS = 2; enum class EventMode { kEmulationMode, // active mapping used for emulation kMenuMode, // mapping used for dialogs + kEditMode, // mapping used in editable widgets kJoystickMode, // 4 extra modes for mapping controller keys separately for emulation mode kPaddlesMode, kKeypadMode, diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 48bc79013..810d3f1d3 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -89,6 +89,7 @@ bool EditableWidget::tryInsertChar(char c, int pos) { if(_filter(tolower(c))) { + killSelectedText(); _editString.insert(pos, 1, c); myUndoHandler->doChar(); // aggregate single chars return true; @@ -105,7 +106,7 @@ bool EditableWidget::handleText(char text) if(tryInsertChar(text, _caretPos)) { _caretPos++; - _selectSize = 0; + //_selectSize = 0; sendCommand(EditableWidget::kChangedCmd, 0, _id); setDirty(); return true; @@ -119,94 +120,139 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) if(!_editable) return true; - // Ignore all alt-mod keys - if(StellaModTest::isAlt(mod)) - return true; - - // Handle Control and Control-Shift keys - if(StellaModTest::isControl(mod) && handleControlKeys(key, mod)) - return true; - - // Handle Shift keys - if(StellaModTest::isShift(mod) && handleShiftKeys(key)) - return true; - - // Handle keys without modifiers - return handleNormalKeys(key); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) -{ - bool shift = StellaModTest::isShift(mod); bool handled = true; + Event::Type event = instance().eventHandler().eventForKey(EventMode::kEditMode, key, mod); - switch(key) + switch(event) { - case KBDK_A: + case Event::MoveLeftChar: + if(_selectSize) + handled = setCaretPos(selectStartPos()); + else if(_caretPos > 0) + handled = setCaretPos(_caretPos - 1); + _selectSize = 0; + break; + + case Event::MoveRightChar: + if(_selectSize) + handled = setCaretPos(selectEndPos()); + else if(_caretPos < int(_editString.size())) + handled = setCaretPos(_caretPos + 1); + _selectSize = 0; + break; + + case Event::MoveLeftWord: + handled = moveWord(-1, false); + _selectSize = 0; + break; + + case Event::MoveRightWord: + handled = moveWord(+1, false); + _selectSize = 0; + break; + + case Event::MoveHome: + handled = setCaretPos(0); + _selectSize = 0; + break; + + case Event::MoveEnd: + handled = setCaretPos(int(_editString.size())); + _selectSize = 0; + break; + + case Event::SelectLeftChar: + if(_caretPos > 0) + handled = moveCaretPos(-1); + break; + + case Event::SelectRightChar: + if(_caretPos < int(_editString.size())) + handled = moveCaretPos(+1); + break; + + case Event::SelectLeftWord: + handled = moveWord(-1, true); + break; + + case Event::SelectRightWord: + handled = moveWord(+1, true); + break; + + case Event::SelectHome: + handled = moveCaretPos(-_caretPos); + break; + + case Event::SelectEnd: + handled = moveCaretPos(int(_editString.size()) - _caretPos); + break; + + case Event::SelectAll: if(setCaretPos(int(_editString.size()))) _selectSize = -int(_editString.size()); break; - case KBDK_C: - case KBDK_INSERT: - handled = copySelectedText(); + case Event::Delete: + handled = killSelectedText(); + if(!handled) + handled = killChar(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - //case KBDK_E: - // if(shift) - // _selectSize += _caretPos - int(_editString.size()); - // else - // _selectSize = 0; - // setCaretPos(int(_editString.size())); - // break; - - case KBDK_D: + case Event::DeleteChar: handled = killChar(+1); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_K: - handled = killLine(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_U: - handled = killLine(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_V: - handled = pasteSelectedText(); - if(handled) - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_W: + case Event::DeleteWord: handled = killLastWord(); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_X: + case Event::DeleteEnd: + handled = killLine(+1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::DeleteHome: + handled = killLine(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::Backspace: + handled = killSelectedText(); + if(!handled) + handled = killChar(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::Cut: handled = cutSelectedText(); if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case KBDK_Y: - case KBDK_Z: + case Event::Copy: + handled = copySelectedText(); + break; + + case Event::Paste: + handled = pasteSelectedText(); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + + case Event::Undo: + case Event::Redo: { string oldString = _editString; myUndoHandler->endChars(_editString); // Reverse Y and Z for QWERTZ keyboards - if(key == KBDK_Y != instance().eventHandler().isQwertz()) + if(event == Event::Redo != instance().eventHandler().isQwertz()) handled = myUndoHandler->redo(_editString); else - if(shift) - handled = myUndoHandler->redo(_editString); - else - handled = myUndoHandler->undo(_editString); + handled = myUndoHandler->undo(_editString); if(handled) { @@ -219,152 +265,20 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod) break; } - case KBDK_LEFT: - handled = moveWord(-1, shift); - if(!shift) - _selectSize = 0; - break; - - case KBDK_RIGHT: - handled = moveWord(+1, shift); - if(!shift) - _selectSize = 0; - break; - - default: - handled = false; - } - - if(handled) - { - myUndoHandler->endChars(_editString); - setDirty(); - } - - return handled; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleShiftKeys(StellaKey key) -{ - bool handled = true; - - switch(key) - { - case KBDK_DELETE: - case KBDK_KP_PERIOD: - handled = cutSelectedText(); - if(handled) - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_INSERT: - handled = pasteSelectedText(); - if(handled) - sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_LEFT: - if(_caretPos > 0) - handled = moveCaretPos(-1); - break; - - case KBDK_RIGHT: - if(_caretPos < int(_editString.size())) - handled = moveCaretPos(+1); - break; - - case KBDK_HOME: - handled = moveCaretPos(-_caretPos); - break; - - case KBDK_END: - handled = moveCaretPos(int(_editString.size()) - _caretPos); - break; - - - default: - handled = false; - } - - if(handled) - { - myUndoHandler->endChars(_editString); - setDirty(); - } - - return handled; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::handleNormalKeys(StellaKey key) -{ - bool selectMode = false; - bool handled = true; - - switch(key) - { - case KBDK_LSHIFT: - case KBDK_RSHIFT: - case KBDK_LCTRL: - case KBDK_RCTRL: - // stay in select mode - selectMode = _selectSize; - handled = false; - break; - - case KBDK_RETURN: - case KBDK_KP_ENTER: + case Event::EndEdit: // confirm edit and exit editmode endEditMode(); sendCommand(EditableWidget::kAcceptCmd, 0, _id); break; - case KBDK_ESCAPE: + case Event::AbortEdit: abortEditMode(); sendCommand(EditableWidget::kCancelCmd, 0, _id); break; - case KBDK_BACKSPACE: - handled = killSelectedText(); - if(!handled) - handled = killChar(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_DELETE: - case KBDK_KP_PERIOD: - handled = killSelectedText(); - if(!handled) - handled = killChar(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - - case KBDK_LEFT: - if(_selectSize) - handled = setCaretPos(selectStartPos()); - else if(_caretPos > 0) - handled = setCaretPos(_caretPos - 1); - break; - - case KBDK_RIGHT: - if(_selectSize) - handled = setCaretPos(selectEndPos()); - else if(_caretPos < int(_editString.size())) - handled = setCaretPos(_caretPos + 1); - break; - - case KBDK_HOME: - handled = setCaretPos(0); - break; - - case KBDK_END: - handled = setCaretPos(int(_editString.size())); - break; - default: - killSelectedText(); handled = false; + break; } if(handled) @@ -372,8 +286,6 @@ bool EditableWidget::handleNormalKeys(StellaKey key) myUndoHandler->endChars(_editString); setDirty(); } - if(!selectMode) - _selectSize = 0; return handled; } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 66c8dc20e..6c3a1bda1 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -87,9 +87,6 @@ class EditableWidget : public Widget, public CommandSender private: // Line editing - bool handleControlKeys(StellaKey key, StellaMod mod); - bool handleShiftKeys(StellaKey key); - bool handleNormalKeys(StellaKey key); bool killChar(int direction, bool addEdit = true); bool killLine(int direction); bool killLastWord(); From cd069b85103a81828266555408bc7873d96a2fc5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 6 Nov 2020 21:34:30 +0100 Subject: [PATCH 142/263] bugfix: edit mappings removed identical emulation mappings --- src/common/PKeyboardHandler.cxx | 2 +- src/gui/EditableWidget.cxx | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index aefccb0f6..5fb59da65 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -365,7 +365,7 @@ bool PhysicalKeyboardHandler::addMapping(Event::Type event, EventMode mode, myKeyMap.erase(EventMode::kKeypadMode, key, mod); myKeyMap.erase(EventMode::kCompuMateMode, key, mod); } - else if(evMode != EventMode::kMenuMode) + else if(evMode != EventMode::kMenuMode && evMode != EventMode::kEditMode) { // erase identical mapping for kCommonMode myKeyMap.erase(EventMode::kCommonMode, key, mod); diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 810d3f1d3..f6518bead 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -81,6 +81,7 @@ void EditableWidget::setEditable(bool editable, bool hiliteBG) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::lostFocusWidget() { + myUndoHandler->reset(); _selectSize = 0; } @@ -90,8 +91,8 @@ bool EditableWidget::tryInsertChar(char c, int pos) if(_filter(tolower(c))) { killSelectedText(); - _editString.insert(pos, 1, c); myUndoHandler->doChar(); // aggregate single chars + _editString.insert(pos, 1, c); return true; } return false; @@ -106,7 +107,6 @@ bool EditableWidget::handleText(char text) if(tryInsertChar(text, _caretPos)) { _caretPos++; - //_selectSize = 0; sendCommand(EditableWidget::kChangedCmd, 0, _id); setDirty(); return true; @@ -192,6 +192,13 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) _selectSize = -int(_editString.size()); break; + case Event::Backspace: + handled = killSelectedText(); + if(!handled) + handled = killChar(-1); + if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + break; + case Event::Delete: handled = killSelectedText(); if(!handled) @@ -219,13 +226,6 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case Event::Backspace: - handled = killSelectedText(); - if(!handled) - handled = killChar(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); - break; - case Event::Cut: handled = cutSelectedText(); if(handled) From 7ed31f11b4740b8689fe5b8dced186bbb0857f34 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Fri, 6 Nov 2020 23:00:27 +0100 Subject: [PATCH 143/263] MacOS mappings. --- src/common/PKeyboardHandler.cxx | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 5fb59da65..4c2583187 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -657,27 +657,32 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMap {Event::MoveRightChar, KBDK_RIGHT}, {Event::SelectLeftChar, KBDK_LEFT, KBDM_SHIFT}, {Event::SelectRightChar, KBDK_RIGHT, KBDM_SHIFT}, -#ifdef BSPF_MACOS - {Event::MoveLeftWord, KBDK_LEFT, CMD}, -// {Event::MoveRightWord, KBDK_RIGHT, KBDM_CTRL}, - {Event::MoveHome, KBDK_LEFT, CMD}, +#if defined(BSPF_MACOS) || defined(MACOS_KEYS) + {Event::MoveLeftWord, KBDK_LEFT, OPTION}, + {Event::MoveRightWord, KBDK_RIGHT, OPTION}, + {Event::MoveHome, KBDK_HOME}, {Event::MoveHome, KBDK_A, KBDM_CTRL}, - {Event::MoveEnd, KBDK_RIGHT, CMD}, + {Event::MoveHome, KBDK_LEFT, CMD}, + {Event::MoveEnd, KBDK_END}, {Event::MoveEnd, KBDK_E, KBDM_CTRL}, + {Event::MoveEnd, KBDK_RIGHT, CMD}, {Event::SelectLeftWord, KBDK_LEFT, KBDM_SHIFT | OPTION}, -// {Event::SelectRightWord, KBDK_RIGHT, KBDM_SHIFT | OPTION}, - {Event::SelectHome, KBDK_A, KBDM_SHIFT | KBDM_CTRL}, + {Event::SelectRightWord, KBDK_RIGHT, KBDM_SHIFT | OPTION}, + {Event::SelectHome, KBDK_HOME, KBDM_SHIFT}, {Event::SelectHome, KBDK_LEFT, KBDM_SHIFT | CMD}, + {Event::SelectHome, KBDK_A, KBDM_CTRL | KBDM_SHIFT}, {Event::SelectEnd, KBDK_E, KBDM_SHIFT | KBDM_CTRL}, {Event::SelectEnd, KBDK_RIGHT, KBDM_SHIFT | CMD}, + {Event::SelectEnd, KBDK_END, KBDM_SHIFT}, {Event::SelectAll, KBDK_A, CMD}, {Event::Delete, KBDK_DELETE}, - {Event::Delete, KBDK_KP_PERIOD}, // ??? -// {Event::DeleteChar, }, // ??? - {Event::DeleteWord, KBDK_W, OPTION}, + {Event::DeleteChar, KBDK_D, KBDM_CTRL}, + {Event::DeleteWord, KBDK_W, KBDM_CTRL}, + {Event::DeleteWord, KBDK_BACKSPACE, KBDM_CTRL}, + {Event::DeleteHome, KBDK_U, KBDM_CTRL}, {Event::DeleteHome, KBDK_BACKSPACE, CMD}, - {Event::DeleteEnd, KBDK_BACKSPACE, KBDM_SHIFT | KBDM_CTRL}, - {Event::Backspace, KBDK_BACKSPACE}, // ??? + {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, + {Event::Backspace, KBDK_BACKSPACE}, {Event::Undo, KBDK_Z, CMD}, {Event::Redo, KBDK_Y, CMD}, {Event::Redo, KBDK_Z, KBDM_SHIFT | CMD}, From 5515a9066986dec9cb7b4c44ac5fc352fd27cfca Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Fri, 6 Nov 2020 23:07:05 +0100 Subject: [PATCH 144/263] Fix option-backspace. --- src/common/PKeyboardHandler.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 4c2583187..5b6cffae1 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -678,7 +678,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMap {Event::Delete, KBDK_DELETE}, {Event::DeleteChar, KBDK_D, KBDM_CTRL}, {Event::DeleteWord, KBDK_W, KBDM_CTRL}, - {Event::DeleteWord, KBDK_BACKSPACE, KBDM_CTRL}, + {Event::DeleteWord, KBDK_BACKSPACE, OPTION}, {Event::DeleteHome, KBDK_U, KBDM_CTRL}, {Event::DeleteHome, KBDK_BACKSPACE, CMD}, {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, From 1e069016d28881475d47a29c320d39c48418a2fc Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 6 Nov 2020 23:57:34 +0100 Subject: [PATCH 145/263] fixed problem with QWERTZ keys --- src/common/EventHandlerSDL2.hxx | 2 +- src/common/PKeyboardHandler.cxx | 11 ++++++++++- src/emucore/EventHandler.cxx | 21 +++++++++++---------- src/gui/EditableWidget.cxx | 2 +- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/common/EventHandlerSDL2.hxx b/src/common/EventHandlerSDL2.hxx index 2654cd132..0c5301749 100644 --- a/src/common/EventHandlerSDL2.hxx +++ b/src/common/EventHandlerSDL2.hxx @@ -38,7 +38,7 @@ class EventHandlerSDL2 : public EventHandler explicit EventHandlerSDL2(OSystem& osystem); ~EventHandlerSDL2() override; -private: + private: /** Enable/disable text events (distinct from single-key events). */ diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 5b6cffae1..11243c666 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -102,6 +102,15 @@ void PhysicalKeyboardHandler::setDefaultKey(EventMapping map, Event::Type event, // Otherwise, only reset the given event bool eraseAll = !updateDefaults && (event == Event::NoType); + // Swap Y and Z for QWERTZ keyboards + if(mode == EventMode::kEditMode && myHandler.isQwertz()) + { + if(map.key == KBDK_Z) + map.key = KBDK_Y; + else if(map.key == KBDK_Y) + map.key = KBDK_Z; + } + if (updateDefaults) { // if there is no existing mapping for the event and @@ -678,7 +687,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMap {Event::Delete, KBDK_DELETE}, {Event::DeleteChar, KBDK_D, KBDM_CTRL}, {Event::DeleteWord, KBDK_W, KBDM_CTRL}, - {Event::DeleteWord, KBDK_BACKSPACE, OPTION}, + {Event::DeleteWord, KBDK_BACKSPACE, KBDM_CTRL}, {Event::DeleteHome, KBDK_U, KBDM_CTRL}, {Event::DeleteHome, KBDK_BACKSPACE, CMD}, {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 3ce9a4da5..871d6cd73 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -69,16 +69,6 @@ using namespace std::placeholders; EventHandler::EventHandler(OSystem& osystem) : myOSystem(osystem) { - // Create keyboard handler (to handle all physical keyboard functionality) - myPKeyHandler = make_unique(osystem, *this); - - // Create joystick handler (to handle all physical joystick functionality) - myPJoyHandler = make_unique(osystem, *this); - - // Erase the 'combo' array - for(int i = 0; i < COMBO_SIZE; ++i) - for(int j = 0; j < EVENTS_PER_COMBO; ++j) - myComboTable[i][j] = Event::NoType; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -89,6 +79,17 @@ EventHandler::~EventHandler() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::initialize() { + // Create keyboard handler (to handle all physical keyboard functionality) + myPKeyHandler = make_unique(myOSystem, *this); + + // Create joystick handler (to handle all physical joystick functionality) + myPJoyHandler = make_unique(myOSystem, *this); + + // Erase the 'combo' array + for(int i = 0; i < COMBO_SIZE; ++i) + for(int j = 0; j < EVENTS_PER_COMBO; ++j) + myComboTable[i][j] = Event::NoType; + // Make sure the event/action mappings are correctly set, // and fill the ActionList structure with valid values setComboMap(); diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index f6518bead..05cf74887 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -249,7 +249,7 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) myUndoHandler->endChars(_editString); // Reverse Y and Z for QWERTZ keyboards - if(event == Event::Redo != instance().eventHandler().isQwertz()) + if(event == Event::Redo) handled = myUndoHandler->redo(_editString); else handled = myUndoHandler->undo(_editString); From ec8c4002573e156f1094847531995020b7d12076 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 6 Nov 2020 19:38:02 -0330 Subject: [PATCH 146/263] Added a few more editing shortcuts, fixed a few warnings, and re-applied reverted commit. --- src/common/PKeyboardHandler.cxx | 8 +++++--- src/common/PKeyboardHandler.hxx | 1 + src/gui/EditableWidget.cxx | 2 +- src/gui/UndoHandler.cxx | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 11243c666..d459029c1 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -165,7 +165,7 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod case EventMode::kEditMode: // Edit mode events are always set because they are not saved - for(const auto& item : FixedEditMapping) + for(const auto& item: FixedEditMapping) setDefaultKey(item, event, EventMode::kEditMode); break; @@ -661,7 +661,6 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuM // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMapping = { -// TOOD: check MacOS mappings {Event::MoveLeftChar, KBDK_LEFT}, {Event::MoveRightChar, KBDK_RIGHT}, {Event::SelectLeftChar, KBDK_LEFT, KBDM_SHIFT}, @@ -687,7 +686,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMap {Event::Delete, KBDK_DELETE}, {Event::DeleteChar, KBDK_D, KBDM_CTRL}, {Event::DeleteWord, KBDK_W, KBDM_CTRL}, - {Event::DeleteWord, KBDK_BACKSPACE, KBDM_CTRL}, + {Event::DeleteWord, KBDK_BACKSPACE, OPTION}, {Event::DeleteHome, KBDK_U, KBDM_CTRL}, {Event::DeleteHome, KBDK_BACKSPACE, CMD}, {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, @@ -711,8 +710,11 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMap {Event::Delete, KBDK_DELETE}, {Event::Delete, KBDK_KP_PERIOD}, {Event::DeleteChar, KBDK_D, KBDM_CTRL}, + {Event::DeleteWord, KBDK_BACKSPACE, KBDM_CTRL}, {Event::DeleteWord, KBDK_W, KBDM_CTRL}, + {Event::DeleteHome, KBDK_HOME, KBDM_CTRL}, {Event::DeleteHome, KBDK_U, KBDM_CTRL}, + {Event::DeleteEnd, KBDK_END, KBDM_CTRL}, {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, {Event::Backspace, KBDK_BACKSPACE}, {Event::Undo, KBDK_Z, KBDM_CTRL}, diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx index 8ebfd5acb..f00608b28 100644 --- a/src/common/PKeyboardHandler.hxx +++ b/src/common/PKeyboardHandler.hxx @@ -106,6 +106,7 @@ class PhysicalKeyboardHandler void enableMappings(const Event::EventSet& events, EventMode mode); void enableMapping(const Event::Type event, EventMode mode); + private: OSystem& myOSystem; EventHandler& myHandler; diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 05cf74887..6f5db0f29 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -62,6 +62,7 @@ void EditableWidget::setText(const string& str, bool) setDirty(); } + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::setEditable(bool editable, bool hiliteBG) { @@ -608,7 +609,6 @@ int EditableWidget::selectEndPos() return _caretPos; } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::killSelectedText(bool addEdit) { diff --git a/src/gui/UndoHandler.cxx b/src/gui/UndoHandler.cxx index 92dd4d2d8..f8eeb0c48 100644 --- a/src/gui/UndoHandler.cxx +++ b/src/gui/UndoHandler.cxx @@ -103,4 +103,4 @@ uInt32 UndoHandler::lastDiff(const string& text, const string& oldText) const pos--; } return uInt32(pos); -} \ No newline at end of file +} From aec9bb42c17ebda25e8d0f469ff93de4625d5f5c Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 6 Nov 2020 19:49:08 -0330 Subject: [PATCH 147/263] Minor formatting fixes. --- src/common/PKeyboardHandler.cxx | 38 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index d459029c1..f6cf1a8ef 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -175,7 +175,8 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalKeyboardHandler::defineControllerMappings(const Controller::Type type, Controller::Jack port) +void PhysicalKeyboardHandler::defineControllerMappings( + const Controller::Type type, Controller::Jack port) { // determine controller events to use switch(type) @@ -217,7 +218,8 @@ void PhysicalKeyboardHandler::enableEmulationMappings() myKeyMap.eraseMode(EventMode::kEmulationMode); enableCommonMappings(); - // enable right mode first, so that in case of mapping clashes the left controller has preference + // enable right mode first, so that in case of mapping clashes the left + // controller has preference switch (myRightMode) { case EventMode::kPaddlesMode: @@ -271,14 +273,16 @@ void PhysicalKeyboardHandler::enableCommonMappings() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalKeyboardHandler::enableMappings(const Event::EventSet& events, EventMode mode) +void PhysicalKeyboardHandler::enableMappings(const Event::EventSet& events, + EventMode mode) { for (const auto& event : events) enableMapping(event, mode); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalKeyboardHandler::enableMapping(const Event::Type event, EventMode mode) +void PhysicalKeyboardHandler::enableMapping(const Event::Type event, + EventMode mode) { // copy from controller mode into emulation mode KeyMap::MappingArray mappings = myKeyMap.getEventMapping(event, mode); @@ -288,7 +292,8 @@ void PhysicalKeyboardHandler::enableMapping(const Event::Type event, EventMode m } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EventMode PhysicalKeyboardHandler::getEventMode(const Event::Type event, const EventMode mode) const +EventMode PhysicalKeyboardHandler::getEventMode(const Event::Type event, + const EventMode mode) const { if (mode == EventMode::kEmulationMode) { @@ -389,11 +394,12 @@ bool PhysicalKeyboardHandler::addMapping(Event::Type event, EventMode mode, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pressed, bool repeated) +void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, + bool pressed, bool repeated) { #ifdef BSPF_UNIX // Swallow KBDK_TAB under certain conditions - // See commments on 'myAltKeyCounter' for more information + // See comments on 'myAltKeyCounter' for more information if(myAltKeyCounter > 1 && key == KBDK_TAB) { myAltKeyCounter = 0; @@ -449,7 +455,8 @@ void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pre } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommonMapping = { +PhysicalKeyboardHandler::EventMappingArray +PhysicalKeyboardHandler::DefaultCommonMapping = { {Event::ConsoleSelect, KBDK_F1}, {Event::ConsoleReset, KBDK_F2}, {Event::ConsoleColor, KBDK_F3}, @@ -605,7 +612,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuMapping = { +PhysicalKeyboardHandler::EventMappingArray +PhysicalKeyboardHandler::DefaultMenuMapping = { {Event::UIUp, KBDK_UP}, {Event::UIDown, KBDK_DOWN}, {Event::UILeft, KBDK_LEFT}, @@ -660,7 +668,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuM }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMapping = { +PhysicalKeyboardHandler::EventMappingArray +PhysicalKeyboardHandler::FixedEditMapping = { {Event::MoveLeftChar, KBDK_LEFT}, {Event::MoveRightChar, KBDK_RIGHT}, {Event::SelectLeftChar, KBDK_LEFT, KBDM_SHIFT}, @@ -779,7 +788,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoyst }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultPaddleMapping = { +PhysicalKeyboardHandler::EventMappingArray +PhysicalKeyboardHandler::DefaultPaddleMapping = { {Event::PaddleZeroDecrease, KBDK_RIGHT}, {Event::PaddleZeroIncrease, KBDK_LEFT}, {Event::PaddleZeroFire, KBDK_SPACE}, @@ -801,7 +811,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultPaddl }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultKeypadMapping = { +PhysicalKeyboardHandler::EventMappingArray +PhysicalKeyboardHandler::DefaultKeypadMapping = { {Event::KeyboardZero1, KBDK_1}, {Event::KeyboardZero2, KBDK_2}, {Event::KeyboardZero3, KBDK_3}, @@ -830,7 +841,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultKeypa }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::CompuMateMapping = { +PhysicalKeyboardHandler::EventMappingArray +PhysicalKeyboardHandler::CompuMateMapping = { {Event::CompuMateShift, KBDK_LSHIFT}, {Event::CompuMateShift, KBDK_RSHIFT}, {Event::CompuMateFunc, KBDK_LCTRL}, From 106494ad8e5e86c80f784b59d03969a7a31b4fcb Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 7 Nov 2020 10:15:51 +0100 Subject: [PATCH 148/263] finalized EditableWidget updated doc --- docs/index.html | 140 ++++++++++++++++++++++++----- src/common/PKeyboardHandler.cxx | 17 ++-- src/debugger/gui/PromptWidget.cxx | 4 +- src/debugger/gui/PromptWidget.hxx | 2 +- src/emucore/Event.hxx | 2 +- src/gui/EditableWidget.cxx | 141 ++++++++++++++++-------------- src/gui/EditableWidget.hxx | 2 +- 7 files changed, 207 insertions(+), 101 deletions(-) diff --git a/docs/index.html b/docs/index.html index 0ac22e5dd..0d2a8fd48 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1964,8 +1964,6 @@

    UI Keys in Text Editing areas (cannot be remapped)

    - *** TODO!!! *** - @@ -1973,34 +1971,128 @@ - - - + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FunctionKey (macOS)
    Move cursor to beginning of lineHome, Control + aHome, Control + aMove cursor to previous characterLeft arrowLeft arrow
    .........Move cursor to next characterRight arrowRight arrow
    Move cursor to beginning of current wordControl + Left arrowOption + Left arrow
    Move cursor to beginning of next wordControl + Right arrowOption + Right arrow
    Move cursor to beginning of lineHomeHome, Control + a, Command + Left arrow
    Move cursor to end of lineEndEnd, Control + e, Command + Right arrow
    Delete character to left of cursorBackspaceBackspace
    Delete character to right of cursorDelete, Control + dDelete, Control + d
    Delete word to left of cursorControl + Backspace, Control + wOption + Backspace, Control + w
    Delete word to right of cursorControl + Delete, Alt + dOption + Delete
    Delete all text to beginning of lineControl + Home, Control + uCommand + Backspace, Control + u
    Delete all text to end of lineControl + End, Control + kControl + k
    Select character to left of cursorShift + Left arrowShift + Left arrow
    Select character to right of cursorShift + Right arrowShift + Right arrow
    Select all text to beginning of current wordShift-Control + Left arrowShift-Option + Left arrow
    Select all text to beginning of next wordShift-Control + Right arrowShift-Option + Right arrow
    Select all text to beginning of lineShift + HomeShift + Home, Shift-Control + a, Shift-Command + Left arrow
    Select all text to end of lineShift + EndShift + End, Shift-Control + e, Shift-Command + Right arrow
    Select all textControl + aCommand + a
    Cut selected textControl + x, Shift + DeleteCommand + x
    Copy selected textControl + c, Control + InsertCommand + c
    Paste at cursor and replace selectionControl + v, Shift + InsertCommand + v
    Undo last operationControl + zCommand + z
    Redo last operationControl + y, Shift-Control + zCommand + y, Shift-Command + z

    - - - - - - - - - - - - - - -
    KeyEditor Function
    Home, Control + aMove cursor to beginning of line
    End, Control + eMove cursor to end of line
    Delete, Control + dRemove character to right of cursor
    BackspaceRemove character to left of cursor
    Control + kRemove all characters from cursor to end of line
    Control + uRemove all characters from cursor to beginning of line
    Control + wRemove entire word to left of cursor
    Control + Left arrowMove cursor to beginning of word to the left
    Control + Right arrowMove cursor to beginning of word to the right
    Control + c, Control + InsertCopy entire line to clipboard
    Control + v, Shift + InsertPaste clipboard contents
    Control + x, Shift + DeleteCut entire line to clipboard
    -

    Controller Map

    diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index f6cf1a8ef..159a5d99f 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -693,9 +693,10 @@ PhysicalKeyboardHandler::FixedEditMapping = { {Event::SelectEnd, KBDK_END, KBDM_SHIFT}, {Event::SelectAll, KBDK_A, CMD}, {Event::Delete, KBDK_DELETE}, - {Event::DeleteChar, KBDK_D, KBDM_CTRL}, - {Event::DeleteWord, KBDK_W, KBDM_CTRL}, - {Event::DeleteWord, KBDK_BACKSPACE, OPTION}, + {Event::Delete, KBDK_D, KBDM_CTRL}, + {Event::DeleteLeftWord, KBDK_W, KBDM_CTRL}, + {Event::DeleteLeftWord, KBDK_BACKSPACE, OPTION}, + {Event::DeleteRightWord, KBDK_DELETE, OPTION}, {Event::DeleteHome, KBDK_U, KBDM_CTRL}, {Event::DeleteHome, KBDK_BACKSPACE, CMD}, {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, @@ -718,17 +719,21 @@ PhysicalKeyboardHandler::FixedEditMapping = { {Event::SelectAll, KBDK_A, KBDM_CTRL}, {Event::Delete, KBDK_DELETE}, {Event::Delete, KBDK_KP_PERIOD}, - {Event::DeleteChar, KBDK_D, KBDM_CTRL}, - {Event::DeleteWord, KBDK_BACKSPACE, KBDM_CTRL}, - {Event::DeleteWord, KBDK_W, KBDM_CTRL}, + {Event::Delete, KBDK_D, KBDM_CTRL}, + {Event::DeleteLeftWord, KBDK_BACKSPACE, KBDM_CTRL}, + {Event::DeleteLeftWord, KBDK_W, KBDM_CTRL}, + {Event::DeleteRightWord, KBDK_DELETE, KBDM_CTRL}, + {Event::DeleteRightWord, KBDK_D, KBDM_ALT}, {Event::DeleteHome, KBDK_HOME, KBDM_CTRL}, {Event::DeleteHome, KBDK_U, KBDM_CTRL}, {Event::DeleteEnd, KBDK_END, KBDM_CTRL}, {Event::DeleteEnd, KBDK_K, KBDM_CTRL}, {Event::Backspace, KBDK_BACKSPACE}, {Event::Undo, KBDK_Z, KBDM_CTRL}, + {Event::Undo, KBDK_BACKSPACE, KBDM_ALT}, {Event::Redo, KBDK_Y, KBDM_CTRL}, {Event::Redo, KBDK_Z, KBDM_SHIFT | KBDM_CTRL}, + {Event::Redo, KBDK_BACKSPACE, KBDM_SHIFT | KBDM_ALT}, {Event::Cut, KBDK_X, KBDM_CTRL}, {Event::Cut, KBDK_DELETE, KBDM_SHIFT}, {Event::Cut, KBDK_KP_PERIOD, KBDM_SHIFT}, diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 4f5a0abae..490f7b8a6 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -591,7 +591,7 @@ void PromptWidget::specialKeys(StellaKey key) killLine(-1); break; case KBDK_W: - killLastWord(); + killWord(); break; case KBDK_A: textSelectAll(); @@ -666,7 +666,7 @@ void PromptWidget::killLine(int direction) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptWidget::killLastWord() +void PromptWidget::killWord() { int cnt = 0; bool space = true; diff --git a/src/debugger/gui/PromptWidget.hxx b/src/debugger/gui/PromptWidget.hxx index 925fee4e7..c1719fa1a 100644 --- a/src/debugger/gui/PromptWidget.hxx +++ b/src/debugger/gui/PromptWidget.hxx @@ -68,7 +68,7 @@ class PromptWidget : public Widget, public CommandSender void nextLine(); void killChar(int direction); void killLine(int direction); - void killLastWord(); + void killWord(); // Clipboard void textSelectAll(); diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index 87a609834..f348fbeff 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -140,7 +140,7 @@ class Event MoveHome, MoveEnd, SelectLeftChar, SelectRightChar, SelectLeftWord, SelectRightWord, SelectHome, SelectEnd, SelectAll, - Delete, DeleteChar, DeleteWord, DeleteHome, DeleteEnd, Backspace, + Delete, DeleteLeftWord, DeleteRightWord, DeleteHome, DeleteEnd, Backspace, Cut, Copy, Paste, Undo, Redo, AbortEdit, EndEdit, diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 6f5db0f29..7bd6af8d5 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -197,34 +197,40 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) handled = killSelectedText(); if(!handled) handled = killChar(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case Event::Delete: handled = killSelectedText(); if(!handled) handled = killChar(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case Event::DeleteChar: - handled = killChar(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + case Event::DeleteLeftWord: + handled = killWord(-1); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; - case Event::DeleteWord: - handled = killLastWord(); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + case Event::DeleteRightWord: + handled = killWord(+1); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case Event::DeleteEnd: handled = killLine(+1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case Event::DeleteHome: handled = killLine(-1); - if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id); + if(handled) + sendCommand(EditableWidget::kChangedCmd, key, _id); break; case Event::Cut: @@ -426,23 +432,27 @@ bool EditableWidget::killChar(int direction, bool addEdit) { if(_caretPos > 0) { - myUndoHandler->endChars(_editString); _caretPos--; - _editString.erase(_caretPos, 1); - handled = true; if(_selectSize < 0) _selectSize++; - if(addEdit) - myUndoHandler->doo(_editString); + handled = true; } } else if(direction == 1) // Delete next character (delete) + { + if(_caretPos < _editString.size()) + { + if(_selectSize > 0) + _selectSize--; + handled = true; + } + } + + if(handled) { myUndoHandler->endChars(_editString); _editString.erase(_caretPos, 1); - handled = true; - if(_selectSize > 0) - _selectSize--; + if(addEdit) myUndoHandler->doo(_editString); } @@ -453,75 +463,74 @@ bool EditableWidget::killChar(int direction, bool addEdit) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EditableWidget::killLine(int direction) { - bool handled = false; + int count = 0; if(direction == -1) // erase from current position to beginning of line - { - int count = _caretPos; - if(count > 0) - { - for (int i = 0; i < count; i++) - killChar(-1, false); + count = _caretPos; + else if(direction == +1) // erase from current position to end of line + count = int(_editString.size()) - _caretPos; - handled = true; - // remove selection for removed text - if(_selectSize < 0) - _selectSize = 0; - myUndoHandler->doo(_editString); - } - } - else if(direction == 1) // erase from current position to end of line + if(count > 0) { - int count = int(_editString.size()) - _caretPos; - if(count > 0) - { - for (int i = 0; i < count; i++) - killChar(+1, false); + for(int i = 0; i < count; i++) + killChar(direction, false); - handled = true; - // remove selection for removed text - if(_selectSize > 0) - _selectSize = 0; - myUndoHandler->doo(_editString); - } + myUndoHandler->doo(_editString); + return true; } - return handled; + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::killLastWord() +bool EditableWidget::killWord(int direction) { - bool handled = false; - int count = 0, currentPos = _caretPos; bool space = true; - while (currentPos > 0) - { - if (_editString[currentPos - 1] == ' ') - { - if (!space) - break; - } - else - space = false; + int count = 0, currentPos = _caretPos; - currentPos--; - count++; + if(direction == -1) // move to first character of previous word + { + while(currentPos > 0) + { + if(_editString[currentPos - 1] == ' ') + { + if(!space) + break; + } + else + space = false; + + currentPos--; + count++; + } + } + else if(direction == +1) // move to first character of next word + { + while(currentPos < int(_editString.size())) + { + if(currentPos && _editString[currentPos - 1] == ' ') + { + if(!space) + break; + } + else + space = false; + + currentPos++; + count++; + } } if(count > 0) { - for (int i = 0; i < count; i++) - killChar(-1, false); + for(int i = 0; i < count; i++) + killChar(direction, false); - handled = true; - // remove selection for removed word - if(_selectSize < 0) - _selectSize = std::min(_selectSize + count, 0); myUndoHandler->doo(_editString); + return true; } - return handled; + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 6c3a1bda1..fda92ccdf 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -89,7 +89,7 @@ class EditableWidget : public Widget, public CommandSender // Line editing bool killChar(int direction, bool addEdit = true); bool killLine(int direction); - bool killLastWord(); + bool killWord(int direction); bool moveWord(int direction, bool select); bool killSelectedText(bool addEdit = true); From d43b34833209175fa0230fcd05ef21c5f53ffb3c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 7 Nov 2020 10:53:40 +0100 Subject: [PATCH 149/263] Fix #721 --- src/common/PKeyboardHandler.cxx | 8 ++++++++ src/common/PKeyboardHandler.hxx | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 159a5d99f..ae02d3c6e 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -62,7 +62,9 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler& setDefaultMapping(Event::NoType, EventMode::kEmulationMode, updateDefaults); setDefaultMapping(Event::NoType, EventMode::kMenuMode, updateDefaults); +#ifdef GUI_SUPPORT setDefaultMapping(Event::NoType, EventMode::kEditMode, updateDefaults); +#endif // DEBUG } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -102,6 +104,7 @@ void PhysicalKeyboardHandler::setDefaultKey(EventMapping map, Event::Type event, // Otherwise, only reset the given event bool eraseAll = !updateDefaults && (event == Event::NoType); +#ifdef GUI_SUPPORT // Swap Y and Z for QWERTZ keyboards if(mode == EventMode::kEditMode && myHandler.isQwertz()) { @@ -110,6 +113,7 @@ void PhysicalKeyboardHandler::setDefaultKey(EventMapping map, Event::Type event, else if(map.key == KBDK_Y) map.key = KBDK_Z; } +#endif if (updateDefaults) { @@ -163,11 +167,13 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod setDefaultKey(item, event, EventMode::kMenuMode, updateDefaults); break; + #ifdef GUI_SUPPORT case EventMode::kEditMode: // Edit mode events are always set because they are not saved for(const auto& item: FixedEditMapping) setDefaultKey(item, event, EventMode::kEditMode); break; + #endif default: break; @@ -667,6 +673,7 @@ PhysicalKeyboardHandler::DefaultMenuMapping = { #endif }; +#ifdef GUI_SUPPORT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::FixedEditMapping = { @@ -746,6 +753,7 @@ PhysicalKeyboardHandler::FixedEditMapping = { {Event::EndEdit, KBDK_KP_ENTER}, {Event::AbortEdit, KBDK_ESCAPE}, }; +#endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoystickMapping = { diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx index f00608b28..2bb72107a 100644 --- a/src/common/PKeyboardHandler.hxx +++ b/src/common/PKeyboardHandler.hxx @@ -133,7 +133,9 @@ class PhysicalKeyboardHandler // Controller menu and common emulation mappings static EventMappingArray DefaultMenuMapping; + #ifdef GUI_SUPPORT static EventMappingArray FixedEditMapping; + #endif static EventMappingArray DefaultCommonMapping; // Controller specific mappings static EventMappingArray DefaultJoystickMapping; From a5cef956279b7f7ed6ec3c4740821ed06a039fff Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 7 Nov 2020 09:51:46 -0330 Subject: [PATCH 150/263] Fix compile warning. --- src/gui/EditableWidget.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 7bd6af8d5..16b371813 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -440,7 +440,7 @@ bool EditableWidget::killChar(int direction, bool addEdit) } else if(direction == 1) // Delete next character (delete) { - if(_caretPos < _editString.size()) + if(_caretPos < int(_editString.size())) { if(_selectSize > 0) _selectSize--; From 0149ebfbce1ca12d6262e29b21dc3cc067190263 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Sat, 7 Nov 2020 15:32:00 +0100 Subject: [PATCH 151/263] Use a native version in the Debian changelog Since the Debian packaging specifies a native package, the version in the changelog must not include anything after the upstream version. Keeping this as a native package makes it easier to build from the git repository (no need for an upstream tarball). Signed-off-by: Stephen Kitt --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 424a4e46c..d1456ede4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -stella (6.4-1) stable; urgency=high +stella (6.4) stable; urgency=high * Version 6.4 release From 8d9c30d6b1adf5341c5d1b97ac8c66ff33947adb Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Sat, 7 Nov 2020 15:33:12 +0100 Subject: [PATCH 152/263] Sync the Debian packaging from Debian ... preserving the ability to build on Debian 9 (Stretch). Signed-off-by: Stephen Kitt --- debian/compat | 2 +- debian/control | 42 ++++++--- debian/copyright | 216 ++++++++++++++++++++++++++++++++++++++++++----- debian/dirs | 1 - debian/doc-base | 9 ++ debian/rules | 77 ++++------------- debian/watch | 6 +- 7 files changed, 260 insertions(+), 93 deletions(-) delete mode 100644 debian/dirs create mode 100644 debian/doc-base diff --git a/debian/compat b/debian/compat index ec635144f..f599e28b8 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -9 +10 diff --git a/debian/control b/debian/control index 4d19b476f..9106212fe 100644 --- a/debian/control +++ b/debian/control @@ -1,17 +1,39 @@ Source: stella -Section: games -Priority: optional Maintainer: Stephen Anthony -Standards-Version: 3.7.2 -Build-Depends: debhelper (>= 5.0.0), libsdl2-dev, libpng-dev +Section: otherosfs +Priority: optional +Build-Depends: debhelper (>= 10~), + libpng-dev, + libsdl2-dev, + zlib1g-dev +Standards-Version: 4.5.0 +Vcs-Browser: https://github.com/stella-emu/stella/ +Vcs-Git: https://github.com/stella-emu/stella.git +Homepage: https://stella-emu.github.io +Rules-Requires-Root: no Package: stella Architecture: any -Depends: ${shlibs:Depends} +Depends: ${misc:Depends}, + ${shlibs:Depends} +Recommends: joystick (>= 1:1.5.1) +Pre-Depends: ${misc:Pre-Depends} Description: Atari 2600 Emulator for SDL2 - The Atari 2600 Video Computer System (VCS), introduced in 1977, was - the most popular home video game system of the early 1980's. This - emulator will run most Atari ROM images, so that you can play your - favorite old Atari 2600 games on your PC. + Stella is a portable emulator of the old Atari 2600 video-game + console. You can play most Atari 2600 games with it. . - Homepage: https://stella-emu.github.io + Stella's features include: + * emulation of Atari 2600 joysticks, keyboards, paddles and driving + controllers using the host system's input peripherals; + * emulation of trackballs, joysticks, booster grips, driving + controllers and the Amiga Mouse using the host system's mouse; + * support for real Atari 2600 controllers using the Stelladaptor, + 2600-daptor or 2600-daptor II; + * support for real Atari 7800 controllers using the 2600-daptor II; + * support for the speech portion of a real AtariVox device; + * support for Supercharger single-load and multi-load games; + * emulation of CRT TV features, including texturing, colour bleed, + RF noise and phosphor burn-off (requires OpenGL). + . + An extensive debugger is included, with the Distella disassembler. + diff --git a/debian/copyright b/debian/copyright index 129ab1224..9658cf4e9 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,29 +1,205 @@ -This package was debianized first by Tom Lear on -Thu, 7 Oct 1999 08:57:16 -0700. +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0 +Upstream-Name: stella +Source: https://stella-emu.github.io +Copyright: 1995-2020 Bradford W. Mott, Stephen Anthony and the Stella Team +License: GPL-2+ -It was downloaded from +Files: * +Copyright: 1995-2020 Bradford W. Mott, Stephen Anthony and the Stella + Team +License: GPL-2+ -Copyright Holder(s): Bradford W. Mott and the Stella Team +Files: debian/* +Copyright: 1998-2004 Tom Lear + 2006 Mario Iseli + 2010-2020 Stephen Kitt +License: GPL-2+ -License: +Files: + src/common/Stack.hxx + src/emucore/FrameBuffer.hxx + src/emucore/FSNode.* + src/gui/* +Copyright: 2002-2004 The ScummVM project +License: GPL-2+ - Copyright (C) 1995-2010 Bradford W. Mott - and the Stella Team +Files: src/common/ZipHandler.hxx +Copyright: Aaron Giles +License: BSD-3 + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + . + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name 'MAME' nor the names of its contributors may + be used to endorse or promote products derived from this + software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. +Files: src/emucore/MD5.cxx +Copyright: 1991-1992, RSA Data Security, Inc. +License: RSA + License to copy and use this software is granted provided that it is + identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software or + this function. + . + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + . + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" without + express or implied warranty of any kind. + . + These notices must be retained in any copies of any part of this + documentation and/or software. - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +Files: src/libpng/* +Copyright: 1995-1996 Guy Eric Schalnat, Group 42, Inc. + 1996-1997 Andreas Dilger + 1998-2013 Glenn Randers-Pehrson +License: libpng + The PNG Reference Library is supplied "AS IS". The Contributing + Authors and Group 42, Inc. disclaim all warranties, expressed or + implied, including, without limitation, the warranties of + merchantability and of fitness for any purpose. The Contributing + Authors and Group 42, Inc. assume no liability for direct, indirect, + incidental, special, exemplary, or consequential damages, which may + result from the use of the PNG Reference Library, even if advised of + the possibility of such damage. + . + Permission is hereby granted to use, copy, modify, and distribute + this source code, or portions hereof, for any purpose, without fee, + subject to the following restrictions: + . + 1. The origin of this source code must not be misrepresented. + . + 2. Altered versions must be plainly marked as such and must not be + misrepresented as being the original source. + . + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + . + The Contributing Authors and Group 42, Inc. specifically permit, + without fee, and encourage the use of this source code as a component + to supporting the PNG file format in commercial products. If you use + this source code in a product, acknowledgment is not required but + would be appreciated. + . + There is no warranty against interference with your enjoyment of the + library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is + with the user. - You should have received a copy of the GNU General Public License - along with this package; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +Files: src/libretro/libretro.h +Copyright: 2010-2017 The RetroArch team +License: MIT + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. -On Debian systems, the complete text of the GNU General -Public License can be found in `/usr/share/common-licenses/GPL'. +Files: src/macos/* +Copyright: 2005-2006 Mark Grebe +License: GPL-2+ +Files: src/tools/convbdf.c +Copyright: 2002 Greg Haerr +License: GPL-2+ + +Files: src/tools/evdev-joystick/* +Copyright: 2016 Stephen Anthony +License: GPL-2 + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + . + This package is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA. + . + On Debian systems, the complete text of the GNU General Public + License version 2 can be found in + `/usr/share/common-licenses/GPL-2'. + +Files: src/zlib/* +Copyright: 1995-2012, 2016 Jean-loup Gailly and Mark Adler +License: zlib + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any + damages arising from the use of this software. + . + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + . + 1. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source + distribution. + +License: GPL-2+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at + your option) any later version. + . + This package is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA. + . + On Debian systems, the complete text of the GNU General Public + License version 2 can be found in + `/usr/share/common-licenses/GPL-2'. diff --git a/debian/dirs b/debian/dirs deleted file mode 100644 index e77248175..000000000 --- a/debian/dirs +++ /dev/null @@ -1 +0,0 @@ -usr/bin diff --git a/debian/doc-base b/debian/doc-base new file mode 100644 index 000000000..dd94cd309 --- /dev/null +++ b/debian/doc-base @@ -0,0 +1,9 @@ +Document: stella +Title: Stella Manual +Author: The Stella Team +Abstract: Documentation for the Stella Atari 2600 VCS emulator. +Section: Emulators + +Format: HTML +Index: /usr/share/doc/stella/index.html +Files: /usr/share/doc/stella/*.html diff --git a/debian/rules b/debian/rules index 2e9b442c1..8277e8a69 100755 --- a/debian/rules +++ b/debian/rules @@ -4,67 +4,26 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -# These are used for cross-compiling and for saving the configure script -# from having to guess our platform (since we know it already) -DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) -DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) -DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +export DEB_BUILD_MAINT_OPTIONS = hardening=+all -CFLAGS = -Wall +include /usr/share/dpkg/architecture.mk +DPKG_EXPORT_BUILDTOOLS=1 +-include /usr/share/dpkg/buildtools.mk -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CXXFLAGS += -O0 -else - CXXFLAGS += -O2 -endif +%: + dh $@ --with autotools_dev -config.status: configure - dh_testdir - CXXFLAGS="$(CXXFLAGS)" ./configure --prefix=/usr --enable-release +override_dh_auto_clean: +# Generate the minimal config.mak required for "make distclean" + test -f config.mak || echo "RM_REC := rm -f -r" > config.mak + dh_auto_clean -build: build-stamp +override_dh_auto_configure: + ./configure --prefix=/usr $(if $(filter $(DEB_BUILD_ARCH),$(DEB_HOST_ARCH)),,--host=$(DEB_HOST_GNU_TYPE)) --enable-release -build-stamp: config.status - dh_testdir - $(MAKE) - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - -$(MAKE) distclean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - $(MAKE) install DESTDIR=$(CURDIR)/debian/stella - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs Changes.txt - dh_installdocs - dh_installmenu -# dh_installman $(CURDIR)/debian/stella.6 - dh_link - dh_strip - dh_compress - dh_fixperms - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install +override_dh_auto_install: + dh_auto_install + # This is also installed as the upstream changelog + rm $(CURDIR)/debian/stella/usr/share/doc/stella/Changes.txt + # This is overridden by the copyright file + rm $(CURDIR)/debian/stella/usr/share/doc/stella/License.txt diff --git a/debian/watch b/debian/watch index 8cdd8c1ec..b507d13a8 100644 --- a/debian/watch +++ b/debian/watch @@ -1,2 +1,4 @@ -version=3 -http://sf.net/stella/stella-(.*)-src\.tar\.gz +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%stella-$1.tar.gz%" \ + https://github.com/stella-emu/stella/tags \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate From ad7e543dacc3e0460f7dc9f06158315149995bc8 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sat, 7 Nov 2020 23:13:50 +0100 Subject: [PATCH 153/263] Don't calculate palette before all sliders have initialized. --- src/gui/VideoAudioDialog.cxx | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 47c955b94..a2e68e329 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -941,21 +941,49 @@ void VideoAudioDialog::handlePaletteUpdate() // TIA Palette instance().settings().setValue("palette", myTIAPalette->getSelectedTag().toString()); + // Palette adjustables PaletteHandler::Adjustable paletteAdj; + + if (myPhaseShiftNtsc->getValue() < 0) return; paletteAdj.phaseNtsc = myPhaseShiftNtsc->getValue(); + + if (myPhaseShiftPal->getValue() < 0) return; paletteAdj.phasePal = myPhaseShiftPal->getValue(); + + if (myTVRedScale->getValue() < 0) return; paletteAdj.redScale = myTVRedScale->getValue(); + + if (myTVRedShift->getValue() < 0) return; paletteAdj.redShift = myTVRedShift->getValue(); + + if (myTVGreenScale->getValue() < 0) return; paletteAdj.greenScale = myTVGreenScale->getValue(); + + if (myTVGreenShift->getValue() < 0) return; paletteAdj.greenShift = myTVGreenShift->getValue(); + + if (myTVBlueScale->getValue() < 0) return; paletteAdj.blueScale = myTVBlueScale->getValue(); + + if (myTVBlueShift->getValue() < 0) return; paletteAdj.blueShift = myTVBlueShift->getValue(); + + if (myTVHue->getValue() < 0) return; paletteAdj.hue = myTVHue->getValue(); + + if (myTVSatur->getValue() < 0) return; paletteAdj.saturation = myTVSatur->getValue(); + + if (myTVContrast->getValue() < 0) return; paletteAdj.contrast = myTVContrast->getValue(); + + if (myTVBright->getValue() < 0) return; paletteAdj.brightness = myTVBright->getValue(); + + if (myTVGamma->getValue() < 0) return; paletteAdj.gamma = myTVGamma->getValue(); + instance().frameBuffer().tiaSurface().paletteHandler().setAdjustables(paletteAdj); if(instance().hasConsole()) From 0d184f7a8053951ea8edb854da5d2999e1b61454 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 8 Nov 2020 18:25:24 +0100 Subject: [PATCH 154/263] Revert "Don't calculate palette before all sliders have initialized." This reverts commit ad7e543dacc3e0460f7dc9f06158315149995bc8. Added clamping of the returned SliderWidget values to valid range instead --- src/gui/VideoAudioDialog.cxx | 28 ---------------------------- src/gui/Widget.hxx | 2 +- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index a2e68e329..47c955b94 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -941,49 +941,21 @@ void VideoAudioDialog::handlePaletteUpdate() // TIA Palette instance().settings().setValue("palette", myTIAPalette->getSelectedTag().toString()); - // Palette adjustables PaletteHandler::Adjustable paletteAdj; - - if (myPhaseShiftNtsc->getValue() < 0) return; paletteAdj.phaseNtsc = myPhaseShiftNtsc->getValue(); - - if (myPhaseShiftPal->getValue() < 0) return; paletteAdj.phasePal = myPhaseShiftPal->getValue(); - - if (myTVRedScale->getValue() < 0) return; paletteAdj.redScale = myTVRedScale->getValue(); - - if (myTVRedShift->getValue() < 0) return; paletteAdj.redShift = myTVRedShift->getValue(); - - if (myTVGreenScale->getValue() < 0) return; paletteAdj.greenScale = myTVGreenScale->getValue(); - - if (myTVGreenShift->getValue() < 0) return; paletteAdj.greenShift = myTVGreenShift->getValue(); - - if (myTVBlueScale->getValue() < 0) return; paletteAdj.blueScale = myTVBlueScale->getValue(); - - if (myTVBlueShift->getValue() < 0) return; paletteAdj.blueShift = myTVBlueShift->getValue(); - - if (myTVHue->getValue() < 0) return; paletteAdj.hue = myTVHue->getValue(); - - if (myTVSatur->getValue() < 0) return; paletteAdj.saturation = myTVSatur->getValue(); - - if (myTVContrast->getValue() < 0) return; paletteAdj.contrast = myTVContrast->getValue(); - - if (myTVBright->getValue() < 0) return; paletteAdj.brightness = myTVBright->getValue(); - - if (myTVGamma->getValue() < 0) return; paletteAdj.gamma = myTVGamma->getValue(); - instance().frameBuffer().tiaSurface().paletteHandler().setAdjustables(paletteAdj); if(instance().hasConsole()) diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 91fffff04..50e71681e 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -336,7 +336,7 @@ class SliderWidget : public ButtonWidget ~SliderWidget() override = default; void setValue(int value); - int getValue() const { return _value; } + int getValue() const { return BSPF::clamp(_value, _valueMin, _valueMax); } void setMinValue(int value); int getMinValue() const { return _valueMin; } From 20785c006e8e884ac4dccdff6eb61441e90adf88 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 8 Nov 2020 19:18:53 +0100 Subject: [PATCH 155/263] fixed too large shift exponent used in DataGridWidget --- src/debugger/gui/RiotWidget.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index 20c04326c..73a70391f 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -128,12 +128,12 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, readNames[row]); } xpos += t->getWidth() + 5; - myTimRead = new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 4, 32, Common::Base::Fmt::_16); + myTimRead = new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 4, 30, Common::Base::Fmt::_16); myTimRead->setTarget(this); myTimRead->setEditable(false); ypos += myTimRead->getHeight() - 1; - myTimDivider = new DataGridWidget(boss, nfont, xpos, ypos, 1, 1, 4, 32, Common::Base::Fmt::_10_4); + myTimDivider = new DataGridWidget(boss, nfont, xpos, ypos, 1, 1, 4, 12, Common::Base::Fmt::_10_4); myTimDivider->setTarget(this); myTimDivider->setEditable(false); From c9d6a58832e29eb5bbbb55fb532f595cdda811f6 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 9 Nov 2020 16:01:36 -0330 Subject: [PATCH 156/263] Fix minor warnings from clang static analyzer. --- src/common/PaletteHandler.hxx | 8 +++----- src/common/SoundSDL2.cxx | 2 +- src/debugger/gui/CartMNetworkWidget.cxx | 7 +++---- src/gui/RomAuditDialog.cxx | 3 ++- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/common/PaletteHandler.hxx b/src/common/PaletteHandler.hxx index 66da36715..42ba37cfc 100644 --- a/src/common/PaletteHandler.hxx +++ b/src/common/PaletteHandler.hxx @@ -135,12 +135,10 @@ class PaletteHandler }; struct vector2d { - float x; - float y; + float x{0.F}; + float y{0.F}; - explicit vector2d() - : x(0.F), y(0.F) { } - explicit vector2d(float _x, float _y) + explicit vector2d(float _x = 0.F, float _y = 0.F) : x(_x), y(_y) { } }; diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index af99d3f2c..6caabc72e 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -117,7 +117,7 @@ bool SoundSDL2::openDevice() if(myIsInitializedFlag) SDL_CloseAudioDevice(myDevice); - myDeviceId = BSPF::clamp(myAudioSettings.device(), 0u, uInt32(myDevices.size() - 1)); + myDeviceId = BSPF::clamp(myAudioSettings.device(), 0U, uInt32(myDevices.size() - 1)); const char* device = myDeviceId ? myDevices.at(myDeviceId).first.c_str() : nullptr; myDevice = SDL_OpenAudioDevice(device, 0, &desired, &myHardwareSpec, diff --git a/src/debugger/gui/CartMNetworkWidget.cxx b/src/debugger/gui/CartMNetworkWidget.cxx index e9cc68869..e56a1ecb7 100644 --- a/src/debugger/gui/CartMNetworkWidget.cxx +++ b/src/debugger/gui/CartMNetworkWidget.cxx @@ -26,14 +26,13 @@ CartridgeMNetworkWidget::CartridgeMNetworkWidget( int x, int y, int w, int h, CartridgeMNetwork& cart) : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart), - myLower2K(nullptr), - myUpper256B(nullptr) + myCart(cart) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeMNetworkWidget::initialize(GuiObject* boss, CartridgeMNetwork& cart, ostringstream& info) +void CartridgeMNetworkWidget::initialize(GuiObject* boss, + CartridgeMNetwork& cart, ostringstream& info) { uInt32 size = cart.romBankCount() * cart.BANK_SIZE; diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx index 58b9acaba..09c264025 100644 --- a/src/gui/RomAuditDialog.cxx +++ b/src/gui/RomAuditDialog.cxx @@ -143,7 +143,8 @@ void RomAuditDialog::auditRoms() // Only rename the file if we found a valid properties entry if(name != "" && name != files[idx].getName()) { - const string& newfile = node.getPath() + name + "." + extension; + string newfile = node.getPath(); + newfile.append(name).append(".").append(extension); if(files[idx].getPath() != newfile && files[idx].rename(newfile)) renameSucceeded = true; } From e448cd0a684d15e9dac4a4e8790cd26fc496beeb Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 9 Nov 2020 18:20:50 -0330 Subject: [PATCH 157/263] A few more fixes for suggestions from clang static analyzer. --- src/emucore/CartEnhanced.cxx | 4 ++-- src/gui/InputDialog.cxx | 3 ++- src/gui/VideoAudioDialog.cxx | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index e24d5a5b7..22eb63ee7 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -93,7 +93,7 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM writing pages // Note: Writes are mapped to poke() (NOT using direcPokeBase) to check for read from write port (RWP) access.type = System::PageAccessType::WRITE; - for(uInt16 addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) + for(size_t addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) { const uInt16 offset = addr & myRamMask; @@ -105,7 +105,7 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM reading pages access.type = System::PageAccessType::READ; - for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) + for(size_t addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { const uInt16 offset = addr & myRamMask; diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index d5d847f1b..82dae982a 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -672,7 +672,8 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd, break; case kPSpeedChanged: - myPaddleSpeed->setValueLabel(Paddles::setAnalogSensitivity(myPaddleSpeed->getValue()) * 100.F + 0.5F); + myPaddleSpeed->setValueLabel(std::round(Paddles::setAnalogSensitivity( + myPaddleSpeed->getValue()) * 100.F)); break; case kDejitterAvChanged: diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 47c955b94..f68be6df8 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -631,7 +631,7 @@ void VideoAudioDialog::loadConfig() myVolumeSlider->setValue(audioSettings.volume()); // Device - uInt32 deviceId = BSPF::clamp(audioSettings.device(), 0u, + uInt32 deviceId = BSPF::clamp(audioSettings.device(), 0U, uInt32(instance().sound().supportedDevices().size() - 1)); myDevicePopup->setSelected(deviceId); From 30dd5dc4f06e062dc4f351d932d40382638ed654 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 10 Nov 2020 09:03:28 +0100 Subject: [PATCH 158/263] trying to fix CLANG warning --- src/emucore/CartEnhanced.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 22eb63ee7..487a22741 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -60,7 +60,7 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, void CartridgeEnhanced::install(System& system) { // limit banked RAM size to the size of one RAM bank - const uInt32 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : uInt32(myRamSize); + const uInt16 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : uInt16(myRamSize); // calculate bank switching and RAM sizes and masks myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 @@ -93,7 +93,7 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM writing pages // Note: Writes are mapped to poke() (NOT using direcPokeBase) to check for read from write port (RWP) access.type = System::PageAccessType::WRITE; - for(size_t addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) + for(uInt16 addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) { const uInt16 offset = addr & myRamMask; @@ -105,7 +105,7 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM reading pages access.type = System::PageAccessType::READ; - for(size_t addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) + for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { const uInt16 offset = addr & myRamMask; From d3b9f52b089eb9abf78cb8e340850be668daef57 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 10 Nov 2020 19:53:36 +0100 Subject: [PATCH 159/263] initial commit for #719 --- src/emucore/FrameBuffer.cxx | 2 +- src/gui/ContextMenu.cxx | 2 +- src/gui/Dialog.cxx | 93 +++++++++++++++++------- src/gui/Dialog.hxx | 7 +- src/gui/DialogContainer.cxx | 42 ++++++++--- src/gui/GuiObject.hxx | 5 ++ src/gui/ScrollBarWidget.cxx | 1 + src/gui/TabWidget.cxx | 60 +++++++++------- src/gui/Widget.cxx | 139 ++++++++++++++++++++++-------------- src/gui/Widget.hxx | 2 + 10 files changed, 235 insertions(+), 118 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 97bbb2153..e922ff390 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -439,7 +439,7 @@ void FrameBuffer::update(bool force) force = force || myOSystem.launcher().needsRedraw(); if(force) { - clear(); + //clear(); myOSystem.launcher().draw(force); } break; // EventHandlerState::LAUNCHER diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index 41f049ba2..9cf626657 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -621,5 +621,5 @@ void ContextMenu::drawDialog() s.drawBitmap(_downImg, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, _arrowSize); } - setDirty(); + clearDirty(); } diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 85c95349f..6e81535c2 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -149,6 +149,35 @@ void Dialog::center() positionAt(instance().settings().getInt("dialogpos")); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::setDirty() +{ + _dirty = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Dialog::isDirty() const +{ + return _dirty; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Dialog::isChainDirty() const +{ + bool dirty = false; + + // Check if widget or any subwidgets are dirty + Widget* w = _firstWidget; + + while(!dirty && w) + { + dirty |= w->needsRedraw(); + w = w->_next; + } + + return dirty; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::positionAt(uInt32 pos) { @@ -192,7 +221,9 @@ void Dialog::positionAt(uInt32 pos) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Dialog::render() { - if(!_dirty || !isVisible()) + //assert(_dirty); + + if(!isVisible() || !needsRedraw()) return false; // Draw this dialog @@ -207,7 +238,7 @@ bool Dialog::render() surface->render(); }); } - _dirty = false; + //_dirty = false; return true; } @@ -371,37 +402,49 @@ void Dialog::drawDialog() FBSurface& s = surface(); - // Dialog is still on top if e.g a ContextMenu is opened - _onTop = parent().myDialogStack.top() == this - || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this - && !parent().myDialogStack.top()->hasTitle()); - - if(_flags & Widget::FLAG_CLEARBG) + if(isDirty()) { - // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; - s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo); - if(_th) - { - s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo); - s.drawString(_font, _title, _x + _font.getMaxCharWidth() * 1.25, _y + _font.getFontHeight() / 6, - _font.getStringWidth(_title), - _onTop ? kColorTitleText : kColorTitleTextLo); - } - } - else - s.invalidate(); - if(_flags & Widget::FLAG_BORDER) // currently only used by Dialog itself - s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor); + //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; + + // Dialog is still on top if e.g a ContextMenu is opened + _onTop = parent().myDialogStack.top() == this + || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this + && !parent().myDialogStack.top()->hasTitle()); + + if(_flags & Widget::FLAG_CLEARBG) + { + // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; + s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo); + if(_th) + { + s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo); + s.drawString(_font, _title, _x + _font.getMaxCharWidth() * 1.25, _y + _font.getFontHeight() / 6, + _font.getStringWidth(_title), + _onTop ? kColorTitleText : kColorTitleTextLo); + } + } + else { + s.invalidate(); + cerr << "invalidate " << typeid(*this).name() << endl; + } + if(_flags & Widget::FLAG_BORDER) // currently only used by Dialog itself + s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor); + + // Make all child widgets dirty + Widget::setDirtyInChain(_firstWidget); + + clearDirty(); + } - // Make all child widget dirty Widget* w = _firstWidget; - Widget::setDirtyInChain(w); // Draw all children w = _firstWidget; while(w) { - w->draw(); + // only redraw changed widgets + if(w->needsRedraw()) + w->draw(); w = w->_next; } diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 1f6bbec60..805522c42 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -64,8 +64,9 @@ class Dialog : public GuiObject // A dialog being dirty indicates that its underlying surface needs to be // redrawn and then re-rendered; this is taken care of in ::render() - void setDirty() override { _dirty = true; } - bool isDirty() const { return _dirty; } + void setDirty() override; + bool isDirty() const override; + bool isChainDirty() const override; bool render(); void addFocusWidget(Widget* w) override; @@ -235,7 +236,7 @@ class Dialog : public GuiObject int _tabID{0}; int _flags{0}; - bool _dirty{false}; + //bool _dirty{false}; uInt32 _max_w{0}; // maximum wanted width uInt32 _max_h{0}; // maximum wanted height diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 950d71c06..af353f452 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -91,21 +91,32 @@ void DialogContainer::updateTime(uInt64 time) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool DialogContainer::draw(bool full) { + cerr << "draw " << full << endl; if(myDialogStack.empty()) return false; // Make the top dialog dirty if a full redraw is requested - if(full) - myDialogStack.top()->setDirty(); + //if(full) + // myDialogStack.top()->setDirty(); // If the top dialog is dirty, then all below it must be redrawn too const bool dirty = needsRedraw(); + //if(dirty) + // myDialogStack.top()->setDirty(); - myDialogStack.applyAll([&](Dialog*& d){ - if(dirty) - d->setDirty(); - full |= d->render(); - }); + //myDialogStack.applyAll([&](Dialog*& d){ + // if(dirty) + // d->setDirty(); + // full |= d->render(); + //}); + //if(dirty) + { + myDialogStack.applyAll([&](Dialog*& d) { + if(d->needsRedraw()) + //d->setDirty(); + full |= d->render(); + }); + } return full; } @@ -113,7 +124,9 @@ bool DialogContainer::draw(bool full) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool DialogContainer::needsRedraw() const { - return !myDialogStack.empty() ? myDialogStack.top()->isDirty() : false; + return !myDialogStack.empty() + ? myDialogStack.top()->needsRedraw() + : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -133,6 +146,9 @@ int DialogContainer::addDialog(Dialog* d) "Unable to show dialog box; FIX THE CODE"); else { + // fade out current top dialog + if(!myDialogStack.empty()) + myDialogStack.top()->setDirty(); d->setDirty(); myDialogStack.push(d); } @@ -145,8 +161,16 @@ void DialogContainer::removeDialog() if(!myDialogStack.empty()) { myDialogStack.pop(); + // necessary as long as all dialogs share the same surface if(!myDialogStack.empty()) - myDialogStack.top()->setDirty(); + { + //myDialogStack.top()->setDirty(); + + // Mark all dialogs for redraw + myDialogStack.applyAll([&](Dialog*& d){ + d->setDirty(); + }); + } } } diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index 77392209c..2f4a5c1ca 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -78,6 +78,10 @@ class GuiObject : public CommandReceiver virtual bool isVisible() const = 0; virtual void setDirty() = 0; + virtual void clearDirty() { _dirty = false; } + virtual bool isDirty() const { return _dirty; } + virtual bool isChainDirty() const = 0; + virtual bool needsRedraw() const { return isDirty() || isChainDirty(); }; /** Add given widget(s) to the focus list */ virtual void addFocusWidget(Widget* w) = 0; @@ -104,6 +108,7 @@ class GuiObject : public CommandReceiver protected: int _x{0}, _y{0}, _w{0}, _h{0}; + bool _dirty{false}; Widget* _firstWidget{nullptr}; WidgetArray _focusList; diff --git a/src/gui/ScrollBarWidget.cxx b/src/gui/ScrollBarWidget.cxx index 335b716de..451f4a3ee 100644 --- a/src/gui/ScrollBarWidget.cxx +++ b/src/gui/ScrollBarWidget.cxx @@ -315,6 +315,7 @@ void ScrollBarWidget::drawWidget(bool hilite) s.fillRect(_x + 1, _y + _sliderPos - 1, _w - 2, _sliderHeight + 2, onTop ? (hilite && _part == Part::Slider) ? kScrollColorHi : kScrollColor : kColor); } + clearDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx index f1b92b876..61f42b350 100644 --- a/src/gui/TabWidget.cxx +++ b/src/gui/TabWidget.cxx @@ -275,39 +275,45 @@ void TabWidget::drawWidget(bool hilite) // The tab widget is strange in that it acts as both a widget (obviously) // and a dialog (it contains other widgets). Because of the latter, // it must assume responsibility for refreshing all its children. - Widget::setDirtyInChain(_tabs[_activeTab].firstWidget); - FBSurface& s = dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); - - // Iterate over all tabs and draw them - int i, x = _x + kTabLeftOffset; - for (i = 0; i < int(_tabs.size()); ++i) + if(isDirty()) { - int tabWidth = _tabs[i].tabWidth ? _tabs[i].tabWidth : _tabWidth; - ColorId fontcolor = _tabs[i].enabled && onTop? kTextColor : kColor; - int yOffset = (i == _activeTab) ? 0 : 1; - s.fillRect(x, _y + 1, tabWidth, _tabHeight - 1, - (i == _activeTab) - ? onTop ? kDlgColor : kBGColorLo - : onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor - s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset, - _y + yOffset + (_tabHeight - _lineHeight - 1), - tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center); - if(i == _activeTab) + FBSurface& s = dialog().surface(); + bool onTop = _boss->dialog().isOnTop(); + + // Iterate over all tabs and draw them + int i, x = _x + kTabLeftOffset; + for(i = 0; i < int(_tabs.size()); ++i) { - s.hLine(x, _y, x + tabWidth - 1, onTop ? kWidColor : kDlgColor); - s.vLine(x + tabWidth, _y + 1, _y + _tabHeight - 1, onTop ? kBGColorLo : kColor); + int tabWidth = _tabs[i].tabWidth ? _tabs[i].tabWidth : _tabWidth; + ColorId fontcolor = _tabs[i].enabled && onTop ? kTextColor : kColor; + int yOffset = (i == _activeTab) ? 0 : 1; + s.fillRect(x, _y + 1, tabWidth, _tabHeight - 1, + (i == _activeTab) + ? onTop ? kDlgColor : kBGColorLo + : onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor + s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset, + _y + yOffset + (_tabHeight - _lineHeight - 1), + tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center); + if(i == _activeTab) + { + s.hLine(x, _y, x + tabWidth - 1, onTop ? kWidColor : kDlgColor); + s.vLine(x + tabWidth, _y + 1, _y + _tabHeight - 1, onTop ? kBGColorLo : kColor); + } + else + s.hLine(x, _y + _tabHeight, x + tabWidth, onTop ? kWidColor : kDlgColor); + + x += tabWidth + kTabSpacing; } - else - s.hLine(x, _y + _tabHeight, x + tabWidth, onTop ? kWidColor : kDlgColor); - x += tabWidth + kTabSpacing; + // fill empty right space + s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor); + s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor); + + clearDirty(); + // Make all child widgets of currently active tab dirty + Widget::setDirtyInChain(_tabs[_activeTab].firstWidget); } - - // fill empty right space - s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor); - s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index a54d9e45c..33f6b632d 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -56,7 +56,41 @@ void Widget::setDirty() { // A widget being dirty indicates that its parent dialog is dirty // So we inform the parent about it - _boss->dialog().setDirty(); + //_boss->dialog().setDirty(); + //cerr << "set dirty " << typeid(*this).name() << endl; + + _dirty = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Widget::isDirty() const +{ + string name = typeid(*this).name(); + if(_dirty && name == "class TabWidget") + cerr << "is dirty " << typeid(*this).name() << endl; + + return _dirty; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Widget::isChainDirty() const +{ + string name = typeid(*this).name(); + if(_dirty && name == "class TabWidget") + cerr << "is chain dirty " << typeid(*this).name() << endl; + + bool dirty = false; + + // Check if widget or any subwidgets are dirty + Widget* w = _firstWidget; + + while(!dirty && w) + { + dirty |= w->isDirty(); + w = w->_next; + } + + return dirty; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -65,60 +99,67 @@ void Widget::draw() if(!isVisible() || !_boss->isVisible()) return; - FBSurface& s = _boss->dialog().surface(); - - bool onTop = _boss->dialog().isOnTop(); - - bool hasBorder = _flags & Widget::FLAG_BORDER; // currently only used by Dialog widget - int oldX = _x, oldY = _y; - - // Account for our relative position in the dialog - _x = getAbsX(); - _y = getAbsY(); - - // Clear background (unless alpha blending is enabled) - if(_flags & Widget::FLAG_CLEARBG) + if(isDirty()) { - int x = _x, y = _y, w = _w, h = _h; + //cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; + + FBSurface& s = _boss->dialog().surface(); + + bool onTop = _boss->dialog().isOnTop(); + + bool hasBorder = _flags & Widget::FLAG_BORDER; // currently only used by Dialog widget + int oldX = _x, oldY = _y; + + // Account for our relative position in the dialog + _x = getAbsX(); + _y = getAbsY(); + + // Clear background (unless alpha blending is enabled) + if(_flags & Widget::FLAG_CLEARBG) + { + int x = _x, y = _y, w = _w, h = _h; + if(hasBorder) + { + x++; y++; w -= 2; h -= 2; + } + s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor); + } + + // Draw border if(hasBorder) { - x++; y++; w-=2; h-=2; + s.frameRect(_x, _y, _w, _h, !onTop ? kColor : (_flags & Widget::FLAG_HILITED) && isEnabled() ? kWidColorHi : kColor); + _x += 4; + _y += 4; + _w -= 8; + _h -= 8; } - s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor); + + // Now perform the actual widget draw + drawWidget((_flags & Widget::FLAG_HILITED) ? true : false); + + // Restore x/y + if(hasBorder) + { + _x -= 4; + _y -= 4; + _w += 8; + _h += 8; + } + + _x = oldX; + _y = oldY; } - // Draw border - if(hasBorder) - { - s.frameRect(_x, _y, _w, _h, !onTop ? kColor : (_flags & Widget::FLAG_HILITED) && isEnabled() ? kWidColorHi : kColor); - _x += 4; - _y += 4; - _w -= 8; - _h -= 8; - } - - // Now perform the actual widget draw - drawWidget((_flags & Widget::FLAG_HILITED) ? true : false); - - // Restore x/y - if (hasBorder) - { - _x -= 4; - _y -= 4; - _w += 8; - _h += 8; - } - - _x = oldX; - _y = oldY; - // Draw all children Widget* w = _firstWidget; while(w) { - w->draw(); + if(w->needsRedraw()) + w->draw(); w = w->_next; } + clearDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -290,6 +331,7 @@ void Widget::setDirtyInChain(Widget* start) { while(start) { + //cerr << "setDirtyInChain " << typeid(*start).name() << endl; start->setDirty(); start = start->_next; } @@ -345,8 +387,6 @@ void StaticTextWidget::drawWidget(bool hilite) bool onTop = _boss->dialog().isOnTop(); s.drawString(_font, _label, _x, _y, _w, isEnabled() && onTop ? _textcolor : kColor, _align, 0, true, _shadowcolor); - - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -454,6 +494,7 @@ void ButtonWidget::setBitmap(const uInt32* bitmap, int bmw, int bmh) _bmh = bmh; _bmw = bmw; + cerr << "setBitmap" << endl; setDirty(); } @@ -474,8 +515,6 @@ void ButtonWidget::drawWidget(bool hilite) !(isEnabled() && onTop) ? _textcolorlo : hilite ? _textcolorhi : _textcolor, _bmw, _bmh); - - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -635,8 +674,6 @@ void CheckboxWidget::drawWidget(bool hilite) // Finally draw the label s.drawString(_font, _label, _x + prefixSize(_font), _y + _textY, _w, onTop && isEnabled() ? kTextColor : kColor); - - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -652,7 +689,7 @@ SliderWidget::SliderWidget(GuiObject* boss, const GUI::Font& font, _valueLabelWidth(valueLabelWidth), _forceLabelSign(forceLabelSign) { - _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE; + _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE | Widget::FLAG_CLEARBG;; _bgcolor = kDlgColor; _bgcolorhi = kDlgColor; @@ -870,8 +907,6 @@ void SliderWidget::drawWidget(bool hilite) if(_valueLabelWidth > 0) s.drawString(_font, _valueLabel + _valueUnit, _x + _w - _valueLabelWidth, _y + 2, _valueLabelWidth, isEnabled() ? kTextColor : kColor); - - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 50e71681e..c5fd8dced 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -83,6 +83,8 @@ class Widget : public GuiObject virtual bool handleEvent(Event::Type event) { return false; } void setDirty() override; + bool isDirty() const override; + bool isChainDirty() const override; void draw() override; void receivedFocus(); void lostFocus(); From de5233d63b3bd8d24e5f9b96d4291036cb024ae4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 10 Nov 2020 23:29:56 +0100 Subject: [PATCH 160/263] added support of transparent widgets (for TimeMachineDialog) --- src/common/FBSurfaceSDL2.cxx | 16 ++++++++++++++++ src/common/FBSurfaceSDL2.hxx | 2 ++ src/emucore/FBSurface.hxx | 11 +++++++++++ src/gui/Dialog.cxx | 8 ++++++-- src/gui/DialogContainer.cxx | 2 +- src/gui/TimeLineWidget.cxx | 18 +++++++++++------- src/gui/TimeMachineDialog.cxx | 3 +++ src/gui/Widget.cxx | 13 ++++++++----- src/gui/Widget.hxx | 4 +++- 9 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/common/FBSurfaceSDL2.cxx b/src/common/FBSurfaceSDL2.cxx index 543195165..398c773ba 100644 --- a/src/common/FBSurfaceSDL2.cxx +++ b/src/common/FBSurfaceSDL2.cxx @@ -176,6 +176,22 @@ void FBSurfaceSDL2::invalidate() SDL_FillRect(mySurface, nullptr, 0); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FBSurfaceSDL2::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) +{ + ASSERT_MAIN_THREAD; + + // Clear the rectangle + SDL_Rect tmp; + tmp.x = x; + tmp.y = y; + tmp.w = w; + tmp.h = h; + // Note: Transparency has to be 0 to clear the rectangle foreground + // without affecting the background display. + SDL_FillRect(mySurface, &tmp, 0); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceSDL2::free() { diff --git a/src/common/FBSurfaceSDL2.hxx b/src/common/FBSurfaceSDL2.hxx index f446bb17b..c19808f27 100644 --- a/src/common/FBSurfaceSDL2.hxx +++ b/src/common/FBSurfaceSDL2.hxx @@ -55,6 +55,8 @@ class FBSurfaceSDL2 : public FBSurface void translateCoords(Int32& x, Int32& y) const override; bool render() override; void invalidate() override; + void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) override; + void free() override; void reload() override; void resize(uInt32 width, uInt32 height) override; diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index a018ac2c9..67eaa86d2 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -325,6 +325,17 @@ class FBSurface */ virtual void invalidate() = 0; + /** + This method should be called to reset a surface area to empty + + @param x The x coordinate + @param y The y coordinate + @param w The width of the area + @param h The height of the area + */ + virtual void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) = 0; + + /** This method should be called to free any resources being used by the surface. diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 6e81535c2..c691c545a 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -404,7 +404,7 @@ void Dialog::drawDialog() if(isDirty()) { - //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; + cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; // Dialog is still on top if e.g a ContextMenu is opened _onTop = parent().myDialogStack.top() == this @@ -414,7 +414,11 @@ void Dialog::drawDialog() if(_flags & Widget::FLAG_CLEARBG) { // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; - s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo); + + if(_flags & Widget::FLAG_TRANSPARENT) + s.invalidateRect(_x, _y + _th, _w, _h - _th); + else + s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo); if(_th) { s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo); diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index af353f452..8577eb50f 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -91,7 +91,7 @@ void DialogContainer::updateTime(uInt64 time) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool DialogContainer::draw(bool full) { - cerr << "draw " << full << endl; + //cerr << "draw " << full << endl; if(myDialogStack.empty()) return false; diff --git a/src/gui/TimeLineWidget.cxx b/src/gui/TimeLineWidget.cxx index 053d7bccf..94c4d3ef9 100644 --- a/src/gui/TimeLineWidget.cxx +++ b/src/gui/TimeLineWidget.cxx @@ -35,8 +35,11 @@ TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font, : ButtonWidget(boss, font, x, y, w, h, label, cmd), _labelWidth(labelWidth) { - _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE; + _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE + | Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT; + _bgcolor = kDlgColor; + //_bgcolor = kBGColor; _bgcolorhi = kDlgColor; if(!_label.empty() && _labelWidth == 0) @@ -84,7 +87,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps) if(steps.size() > _stepValue.capacity()) _stepValue.reserve(2 * steps.size()); - double scale = (_w - _labelWidth - 2 - HANDLE_W*0) / double(steps.back()); + double scale = (_w - _labelWidth - 2 - HANDLE_W) / double(steps.back()); // Skip the very last value; we take care of it outside the end of the loop for(uInt32 i = 0; i < steps.size() - 1; ++i) @@ -92,7 +95,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps) // Due to integer <-> double conversion, the last value is sometimes // slightly less than the maximum value; we assign it manually to fix this - _stepValue.push_back(_w - _labelWidth - 2 - HANDLE_W*0); + _stepValue.push_back(_w - _labelWidth - 2 - HANDLE_W); } else _stepValue.push_back(0); @@ -141,17 +144,18 @@ void TimeLineWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); + cerr << "TimeLineWidget::drawWidget " << typeid(s).name() << endl; + // Draw the label, if any if(_labelWidth > 0) s.drawString(_font, _label, _x, _y + 2, _labelWidth, isEnabled() ? kTextColor : kColor, TextAlign::Left); - int p = valueToPos(_value), - x = _x + _labelWidth, - w = _w - _labelWidth; - // Frame the handle const int HANDLE_W2 = (HANDLE_W + 1) / 2; + int p = valueToPos(_value), + x = _x + _labelWidth + HANDLE_W2, + w = _w - _labelWidth - HANDLE_W; s.hLine(x + p - HANDLE_W2, _y + 0, x + p - HANDLE_W2 + HANDLE_W, kColorInfo); s.vLine(x + p - HANDLE_W2, _y + 1, _y + _h - 2, kColorInfo); s.hLine(x + p - HANDLE_W2 + 1, _y + _h - 1, x + p - HANDLE_W2 + 1 + HANDLE_W, kBGColor); diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx index 3b591a62d..5982ba693 100644 --- a/src/gui/TimeMachineDialog.cxx +++ b/src/gui/TimeMachineDialog.cxx @@ -225,6 +225,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, // Add index info myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, "1000", TextAlign::Left, kBGColor); myCurrentIdxWidget->setTextColor(kColorInfo); + myCurrentIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT); myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("1000"), ypos, "1000", TextAlign::Right, kBGColor); myLastIdxWidget->setTextColor(kColorInfo); @@ -241,6 +242,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, // Add time info int ypos_s = ypos + (buttonHeight - font.getFontHeight() + 1) / 2; // align to button vertical center myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos_s, "00:00.00", TextAlign::Left, kBGColor); + myCurrentTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT); myCurrentTimeWidget->setTextColor(kColorInfo); myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("00:00.00"), ypos_s, "00:00.00", TextAlign::Right, kBGColor); @@ -287,6 +289,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, // Add message myMessageWidget = new StaticTextWidget(this, font, xpos, ypos_s, " ", TextAlign::Left, kBGColor); + myMessageWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT); myMessageWidget->setTextColor(kColorInfo); } diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 33f6b632d..3c0252688 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -65,9 +65,9 @@ void Widget::setDirty() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Widget::isDirty() const { - string name = typeid(*this).name(); - if(_dirty && name == "class TabWidget") - cerr << "is dirty " << typeid(*this).name() << endl; + //string name = typeid(*this).name(); + //if(_dirty && name == "class TabWidget") + // cerr << "is dirty " << typeid(*this).name() << endl; return _dirty; } @@ -101,7 +101,7 @@ void Widget::draw() if(isDirty()) { - //cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; + cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; FBSurface& s = _boss->dialog().surface(); @@ -122,7 +122,10 @@ void Widget::draw() { x++; y++; w -= 2; h -= 2; } - s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor); + if(isTransparent()) + s.invalidateRect(x, y, w, h); + else + s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor); } // Draw border diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index c5fd8dced..15e7a1d9c 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -52,7 +52,8 @@ class Widget : public GuiObject FLAG_TRACK_MOUSE = 1 << 5, FLAG_RETAIN_FOCUS = 1 << 6, FLAG_WANTS_TAB = 1 << 7, - FLAG_WANTS_RAWDATA = 1 << 8 + FLAG_WANTS_RAWDATA = 1 << 8, + FLAG_TRANSPARENT = 1 << 9 }; public: @@ -105,6 +106,7 @@ class Widget : public GuiObject virtual bool wantsFocus() const { return _flags & FLAG_RETAIN_FOCUS; } bool wantsTab() const { return _flags & FLAG_WANTS_TAB; } bool wantsRaw() const { return _flags & FLAG_WANTS_RAWDATA; } + bool isTransparent() const { return _flags & FLAG_TRANSPARENT; } void setID(uInt32 id) { _id = id; } uInt32 getID() const { return _id; } From 49fcb524fd1cb1e3794ecdf1d1f9ada6a0a3ae83 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 08:56:11 +0100 Subject: [PATCH 161/263] move Widget flags into GuiObject --- src/emucore/FBSurface.hxx | 2 +- src/gui/Dialog.cxx | 14 +++++++------- src/gui/Dialog.hxx | 6 ------ src/gui/GuiObject.hxx | 29 ++++++++++++++++++++++++++--- src/gui/TimeLineWidget.cxx | 3 +-- src/gui/TimeMachineDialog.cxx | 9 ++++++--- src/gui/Widget.cxx | 27 ++++++++++++++++----------- src/gui/Widget.hxx | 20 -------------------- src/libretro/FBSurfaceLIBRETRO.hxx | 1 + 9 files changed, 58 insertions(+), 53 deletions(-) diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index 67eaa86d2..d72ffdd64 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -323,7 +323,7 @@ class FBSurface This method should be called to reset the surface to empty pixels / colour black. */ - virtual void invalidate() = 0; + virtual void invalidate() {}; /** This method should be called to reset a surface area to empty diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index c691c545a..f519cdadc 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -49,9 +49,9 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font const string& title, int x, int y, int w, int h) : GuiObject(instance, parent, *this, x, y, w, h), _font(font), - _title(title), - _flags(Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG) + _title(title) { + _flags = Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG; setTitle(title); } @@ -411,14 +411,14 @@ void Dialog::drawDialog() || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this && !parent().myDialogStack.top()->hasTitle()); - if(_flags & Widget::FLAG_CLEARBG) + if(clearsBackground()) { // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; - if(_flags & Widget::FLAG_TRANSPARENT) - s.invalidateRect(_x, _y + _th, _w, _h - _th); - else + if(hasBackground()) s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo); + else + s.invalidateRect(_x, _y + _th, _w, _h - _th); if(_th) { s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo); @@ -431,7 +431,7 @@ void Dialog::drawDialog() s.invalidate(); cerr << "invalidate " << typeid(*this).name() << endl; } - if(_flags & Widget::FLAG_BORDER) // currently only used by Dialog itself + if(hasBorder()) // currently only used by Dialog itself s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor); // Make all child widgets dirty diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 805522c42..d9b750ab6 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -90,10 +90,6 @@ class Dialog : public GuiObject */ void addSurface(const shared_ptr& surface); - void setFlags(int flags) { _flags |= flags; setDirty(); } - void clearFlags(int flags) { _flags &= ~flags; setDirty(); } - int getFlags() const { return _flags; } - void setTitle(const string& title); bool hasTitle() { return !_title.empty(); } @@ -235,8 +231,6 @@ class Dialog : public GuiObject shared_ptr _surface; int _tabID{0}; - int _flags{0}; - //bool _dirty{false}; uInt32 _max_w{0}; // maximum wanted width uInt32 _max_h{0}; // maximum wanted height diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index 2f4a5c1ca..3bb510a6b 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -41,6 +41,20 @@ class GuiObject : public CommandReceiver friend class Widget; friend class DialogContainer; + public: + enum : uInt32 { + FLAG_ENABLED = 1 << 0, + FLAG_INVISIBLE = 1 << 1, + FLAG_HILITED = 1 << 2, + FLAG_BORDER = 1 << 3, + FLAG_CLEARBG = 1 << 4, + FLAG_TRACK_MOUSE = 1 << 5, + FLAG_RETAIN_FOCUS = 1 << 6, + FLAG_WANTS_TAB = 1 << 7, + FLAG_WANTS_RAWDATA = 1 << 8, + FLAG_NOBG = 1 << 9 + }; + public: // The commands generated by various widgets enum { @@ -83,6 +97,14 @@ class GuiObject : public CommandReceiver virtual bool isChainDirty() const = 0; virtual bool needsRedraw() const { return isDirty() || isChainDirty(); }; + void setFlags(uInt32 flags) { _flags |= flags; setDirty(); } + void clearFlags(uInt32 flags) { _flags &= ~flags; setDirty(); } + uInt32 getFlags() const { return _flags; } + + bool hasBorder() const { return _flags & FLAG_BORDER; } + bool clearsBackground() const { return _flags & FLAG_CLEARBG; } + bool hasBackground() const { return !(_flags & FLAG_NOBG); } + /** Add given widget(s) to the focus list */ virtual void addFocusWidget(Widget* w) = 0; virtual void addToFocusList(WidgetArray& list) = 0; @@ -107,10 +129,11 @@ class GuiObject : public CommandReceiver Dialog& myDialog; protected: - int _x{0}, _y{0}, _w{0}, _h{0}; - bool _dirty{false}; + int _x{0}, _y{0}, _w{0}, _h{0}; + bool _dirty{false}; + uInt32 _flags{0}; - Widget* _firstWidget{nullptr}; + Widget* _firstWidget{nullptr}; WidgetArray _focusList; private: diff --git a/src/gui/TimeLineWidget.cxx b/src/gui/TimeLineWidget.cxx index 94c4d3ef9..4e6b9e9a0 100644 --- a/src/gui/TimeLineWidget.cxx +++ b/src/gui/TimeLineWidget.cxx @@ -36,10 +36,9 @@ TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font, _labelWidth(labelWidth) { _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE - | Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT; + | Widget::FLAG_CLEARBG | Widget::FLAG_NOBG; _bgcolor = kDlgColor; - //_bgcolor = kBGColor; _bgcolorhi = kDlgColor; if(!_label.empty() && _labelWidth == 0) diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx index 5982ba693..e822504a9 100644 --- a/src/gui/TimeMachineDialog.cxx +++ b/src/gui/TimeMachineDialog.cxx @@ -218,6 +218,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, this->clearFlags(Widget::FLAG_CLEARBG); // does only work combined with blending (0..100)! this->clearFlags(Widget::FLAG_BORDER); + this->setFlags(Widget::FLAG_NOBG); xpos = H_BORDER; ypos = V_BORDER; @@ -225,9 +226,10 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, // Add index info myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, "1000", TextAlign::Left, kBGColor); myCurrentIdxWidget->setTextColor(kColorInfo); - myCurrentIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT); + myCurrentIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG); myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("1000"), ypos, "1000", TextAlign::Right, kBGColor); + myLastIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG); myLastIdxWidget->setTextColor(kColorInfo); // Add timeline @@ -242,10 +244,11 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, // Add time info int ypos_s = ypos + (buttonHeight - font.getFontHeight() + 1) / 2; // align to button vertical center myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos_s, "00:00.00", TextAlign::Left, kBGColor); - myCurrentTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT); + myCurrentTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG); myCurrentTimeWidget->setTextColor(kColorInfo); myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("00:00.00"), ypos_s, "00:00.00", TextAlign::Right, kBGColor); + myLastTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG); myLastTimeWidget->setTextColor(kColorInfo); xpos = myCurrentTimeWidget->getRight() + BUTTON_GAP * 4; @@ -289,7 +292,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, // Add message myMessageWidget = new StaticTextWidget(this, font, xpos, ypos_s, " ", TextAlign::Left, kBGColor); - myMessageWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_TRANSPARENT); + myMessageWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG); myMessageWidget->setTextColor(kColorInfo); } diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 3c0252688..6358808e7 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -106,8 +106,6 @@ void Widget::draw() FBSurface& s = _boss->dialog().surface(); bool onTop = _boss->dialog().isOnTop(); - - bool hasBorder = _flags & Widget::FLAG_BORDER; // currently only used by Dialog widget int oldX = _x, oldY = _y; // Account for our relative position in the dialog @@ -115,23 +113,29 @@ void Widget::draw() _y = getAbsY(); // Clear background (unless alpha blending is enabled) - if(_flags & Widget::FLAG_CLEARBG) + if(clearsBackground()) { int x = _x, y = _y, w = _w, h = _h; - if(hasBorder) + if(hasBorder()) { x++; y++; w -= 2; h -= 2; } - if(isTransparent()) - s.invalidateRect(x, y, w, h); + if(hasBackground()) + s.fillRect(x, y, w, h, !onTop + ? _bgcolorlo + : (_flags & Widget::FLAG_HILITED) && isEnabled() + ? _bgcolorhi : _bgcolor); else - s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor); + s.invalidateRect(x, y, w, h); } // Draw border - if(hasBorder) + if(hasBorder()) { - s.frameRect(_x, _y, _w, _h, !onTop ? kColor : (_flags & Widget::FLAG_HILITED) && isEnabled() ? kWidColorHi : kColor); + s.frameRect(_x, _y, _w, _h, !onTop + ? kColor + : (_flags & Widget::FLAG_HILITED) && isEnabled() + ? kWidColorHi : kColor); _x += 4; _y += 4; _w -= 8; @@ -142,7 +146,7 @@ void Widget::draw() drawWidget((_flags & Widget::FLAG_HILITED) ? true : false); // Restore x/y - if(hasBorder) + if(hasBorder()) { _x -= 4; _y -= 4; @@ -350,6 +354,7 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font, _align(align) { _flags = Widget::FLAG_ENABLED; + _bgcolor = kDlgColor; _bgcolorhi = kDlgColor; _textcolor = kTextColor; @@ -692,7 +697,7 @@ SliderWidget::SliderWidget(GuiObject* boss, const GUI::Font& font, _valueLabelWidth(valueLabelWidth), _forceLabelSign(forceLabelSign) { - _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE | Widget::FLAG_CLEARBG;; + _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE | Widget::FLAG_CLEARBG; _bgcolor = kDlgColor; _bgcolorhi = kDlgColor; diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 15e7a1d9c..270f1eb32 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -42,20 +42,6 @@ class Widget : public GuiObject { friend class Dialog; - public: - enum : uInt32 { - FLAG_ENABLED = 1 << 0, - FLAG_INVISIBLE = 1 << 1, - FLAG_HILITED = 1 << 2, - FLAG_BORDER = 1 << 3, - FLAG_CLEARBG = 1 << 4, - FLAG_TRACK_MOUSE = 1 << 5, - FLAG_RETAIN_FOCUS = 1 << 6, - FLAG_WANTS_TAB = 1 << 7, - FLAG_WANTS_RAWDATA = 1 << 8, - FLAG_TRANSPARENT = 1 << 9 - }; - public: Widget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); ~Widget() override; @@ -97,16 +83,11 @@ class Widget : public GuiObject /** Set/clear FLAG_ENABLED */ void setEnabled(bool e); - void setFlags(uInt32 flags) { _flags |= flags; setDirty(); } - void clearFlags(uInt32 flags) { _flags &= ~flags; setDirty(); } - uInt32 getFlags() const { return _flags; } - bool isEnabled() const { return _flags & FLAG_ENABLED; } bool isVisible() const override { return !(_flags & FLAG_INVISIBLE); } virtual bool wantsFocus() const { return _flags & FLAG_RETAIN_FOCUS; } bool wantsTab() const { return _flags & FLAG_WANTS_TAB; } bool wantsRaw() const { return _flags & FLAG_WANTS_RAWDATA; } - bool isTransparent() const { return _flags & FLAG_TRANSPARENT; } void setID(uInt32 id) { _id = id; } uInt32 getID() const { return _id; } @@ -140,7 +121,6 @@ class Widget : public GuiObject const GUI::Font& _font; Widget* _next{nullptr}; uInt32 _id{0}; - uInt32 _flags{0}; bool _hasFocus{false}; int _fontWidth{0}; int _lineHeight{0}; diff --git a/src/libretro/FBSurfaceLIBRETRO.hxx b/src/libretro/FBSurfaceLIBRETRO.hxx index 646d2c46c..3918ff673 100644 --- a/src/libretro/FBSurfaceLIBRETRO.hxx +++ b/src/libretro/FBSurfaceLIBRETRO.hxx @@ -51,6 +51,7 @@ class FBSurfaceLIBRETRO : public FBSurface void translateCoords(Int32& x, Int32& y) const override { } bool render() override { return true; } void invalidate() override { } + void invalidateRect(uInt32, uInt32, uInt32, uInt32) override { } void free() override { } void reload() override { } void resize(uInt32 width, uInt32 height) override { } From 7a1a5e9c17d71f191ec6b37cc9daf30aad6cb673 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 13:00:44 +0100 Subject: [PATCH 162/263] added individual size to each save state (fixes #727) --- src/common/RewindManager.cxx | 24 ++++++++++++++---------- src/common/RewindManager.hxx | 2 -- src/emucore/Serializer.cxx | 2 ++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/common/RewindManager.cxx b/src/common/RewindManager.cxx index 70fa481d7..bc6b70813 100644 --- a/src/common/RewindManager.cxx +++ b/src/common/RewindManager.cxx @@ -37,7 +37,6 @@ RewindManager::RewindManager(OSystem& system, StateManager& statemgr) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RewindManager::setup() { - myStateSize = 0; myLastTimeMachineAdd = false; const string& prefix = myOSystem.settings().getBool("dev.settings") ? "dev." : "plr."; @@ -138,7 +137,6 @@ bool RewindManager::addState(const string& message, bool timeMachine) s.rewind(); // rewind Serializer internal buffers if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s)) { - myStateSize = std::max(myStateSize, uInt32(s.size())); state.message = message; state.cycles = myOSystem.console().tia().cycles(); myLastTimeMachineAdd = timeMachine; @@ -256,18 +254,22 @@ string RewindManager::saveAllStates() buf.str(""); out.putString(STATE_HEADER); out.putShort(numStates); - out.putInt(myStateSize); - unique_ptr buffer = make_unique(myStateSize); for (uInt32 i = 0; i < numStates; ++i) { RewindState& state = myStateList.current(); Serializer& s = state.data; + uInt32 stateSize = uInt32(s.size()); + unique_ptr buffer = make_unique(stateSize); + + out.putInt(stateSize); + // Rewind Serializer internal buffers s.rewind(); + // Save state - s.getByteArray(buffer.get(), myStateSize); - out.putByteArray(buffer.get(), myStateSize); + s.getByteArray(buffer.get(), stateSize); + out.putByteArray(buffer.get(), stateSize); out.putString(state.message); out.putLong(state.cycles); @@ -310,25 +312,27 @@ string RewindManager::loadAllStates() if (in.getString() != STATE_HEADER) return "Incompatible all states file"; numStates = in.getShort(); - myStateSize = in.getInt(); - unique_ptr buffer = make_unique(myStateSize); for (uInt32 i = 0; i < numStates; ++i) { if (myStateList.full()) compressStates(); + uInt32 stateSize = in.getInt(); + unique_ptr buffer = make_unique(stateSize); + // Add new state at the end of the list (queue adds at end) // This updates the 'current' iterator inside the list myStateList.addLast(); RewindState& state = myStateList.current(); Serializer& s = state.data; + // Rewind Serializer internal buffers s.rewind(); // Fill new state with saved values - in.getByteArray(buffer.get(), myStateSize); - s.putByteArray(buffer.get(), myStateSize); + in.getByteArray(buffer.get(), stateSize); + s.putByteArray(buffer.get(), stateSize); state.message = in.getString(); state.cycles = in.getLong(); } diff --git a/src/common/RewindManager.hxx b/src/common/RewindManager.hxx index 619af7264..5f53083f7 100644 --- a/src/common/RewindManager.hxx +++ b/src/common/RewindManager.hxx @@ -144,7 +144,6 @@ class RewindManager bool atLast() const { return myStateList.atLast(); } void resize(uInt32 size) { myStateList.resize(size); } void clear() { - myStateSize = 0; myStateList.clear(); } @@ -176,7 +175,6 @@ class RewindManager uInt64 myHorizon{0}; double myFactor{0.0}; bool myLastTimeMachineAdd{false}; - uInt32 myStateSize{0}; struct RewindState { Serializer data; // actual save state diff --git a/src/emucore/Serializer.cxx b/src/emucore/Serializer.cxx index 80282bdc2..7f94dced2 100644 --- a/src/emucore/Serializer.cxx +++ b/src/emucore/Serializer.cxx @@ -91,6 +91,8 @@ void Serializer::rewind() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - size_t Serializer::size() const { + myStream->seekp(0, std::ios::end); + return myStream->tellp(); } From 515ef088df8b11670fad53c8d7b9cc22f11ba1c0 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 13:00:44 +0100 Subject: [PATCH 163/263] added individual size to each save state (fixes #727) --- src/common/RewindManager.cxx | 24 ++++++++++++++---------- src/common/RewindManager.hxx | 2 -- src/emucore/Serializer.cxx | 2 ++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/common/RewindManager.cxx b/src/common/RewindManager.cxx index 70fa481d7..bc6b70813 100644 --- a/src/common/RewindManager.cxx +++ b/src/common/RewindManager.cxx @@ -37,7 +37,6 @@ RewindManager::RewindManager(OSystem& system, StateManager& statemgr) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RewindManager::setup() { - myStateSize = 0; myLastTimeMachineAdd = false; const string& prefix = myOSystem.settings().getBool("dev.settings") ? "dev." : "plr."; @@ -138,7 +137,6 @@ bool RewindManager::addState(const string& message, bool timeMachine) s.rewind(); // rewind Serializer internal buffers if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s)) { - myStateSize = std::max(myStateSize, uInt32(s.size())); state.message = message; state.cycles = myOSystem.console().tia().cycles(); myLastTimeMachineAdd = timeMachine; @@ -256,18 +254,22 @@ string RewindManager::saveAllStates() buf.str(""); out.putString(STATE_HEADER); out.putShort(numStates); - out.putInt(myStateSize); - unique_ptr buffer = make_unique(myStateSize); for (uInt32 i = 0; i < numStates; ++i) { RewindState& state = myStateList.current(); Serializer& s = state.data; + uInt32 stateSize = uInt32(s.size()); + unique_ptr buffer = make_unique(stateSize); + + out.putInt(stateSize); + // Rewind Serializer internal buffers s.rewind(); + // Save state - s.getByteArray(buffer.get(), myStateSize); - out.putByteArray(buffer.get(), myStateSize); + s.getByteArray(buffer.get(), stateSize); + out.putByteArray(buffer.get(), stateSize); out.putString(state.message); out.putLong(state.cycles); @@ -310,25 +312,27 @@ string RewindManager::loadAllStates() if (in.getString() != STATE_HEADER) return "Incompatible all states file"; numStates = in.getShort(); - myStateSize = in.getInt(); - unique_ptr buffer = make_unique(myStateSize); for (uInt32 i = 0; i < numStates; ++i) { if (myStateList.full()) compressStates(); + uInt32 stateSize = in.getInt(); + unique_ptr buffer = make_unique(stateSize); + // Add new state at the end of the list (queue adds at end) // This updates the 'current' iterator inside the list myStateList.addLast(); RewindState& state = myStateList.current(); Serializer& s = state.data; + // Rewind Serializer internal buffers s.rewind(); // Fill new state with saved values - in.getByteArray(buffer.get(), myStateSize); - s.putByteArray(buffer.get(), myStateSize); + in.getByteArray(buffer.get(), stateSize); + s.putByteArray(buffer.get(), stateSize); state.message = in.getString(); state.cycles = in.getLong(); } diff --git a/src/common/RewindManager.hxx b/src/common/RewindManager.hxx index 619af7264..5f53083f7 100644 --- a/src/common/RewindManager.hxx +++ b/src/common/RewindManager.hxx @@ -144,7 +144,6 @@ class RewindManager bool atLast() const { return myStateList.atLast(); } void resize(uInt32 size) { myStateList.resize(size); } void clear() { - myStateSize = 0; myStateList.clear(); } @@ -176,7 +175,6 @@ class RewindManager uInt64 myHorizon{0}; double myFactor{0.0}; bool myLastTimeMachineAdd{false}; - uInt32 myStateSize{0}; struct RewindState { Serializer data; // actual save state diff --git a/src/emucore/Serializer.cxx b/src/emucore/Serializer.cxx index 80282bdc2..7f94dced2 100644 --- a/src/emucore/Serializer.cxx +++ b/src/emucore/Serializer.cxx @@ -91,6 +91,8 @@ void Serializer::rewind() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - size_t Serializer::size() const { + myStream->seekp(0, std::ios::end); + return myStream->tellp(); } From 113ee123986166e099efb046b5f3410c8a8723d4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 15:37:32 +0100 Subject: [PATCH 164/263] activated enhanced "full" redraw logic --- src/emucore/FrameBuffer.cxx | 32 ++++++++++++++++---------------- src/gui/DialogContainer.cxx | 29 ++++++++--------------------- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index e922ff390..828c14e8f 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -323,13 +323,14 @@ void FrameBuffer::update(bool force) // last, since they are always drawn on top of everything else). // Full rendering is required when messages are enabled - force = force || myMsg.counter >= 0; + force |= (myMsg.counter >= 0); // Detect when a message has been turned off; one last redraw is required // in this case, to draw over the area that the message occupied if(myMsg.counter == 0) myMsg.counter = -1; + bool redraw = false; switch(myOSystem.eventHandler().state()) { case EventHandlerState::NONE: @@ -354,8 +355,8 @@ void FrameBuffer::update(bool force) #ifdef GUI_SUPPORT case EventHandlerState::OPTIONSMENU: { - force = force || myOSystem.menu().needsRedraw(); - if(force) + redraw = myOSystem.menu().needsRedraw(); + if(force || redraw) { clear(); myTIASurface->render(); @@ -366,8 +367,8 @@ void FrameBuffer::update(bool force) case EventHandlerState::CMDMENU: { - force = force || myOSystem.commandMenu().needsRedraw(); - if(force) + redraw = myOSystem.commandMenu().needsRedraw(); + if(force || redraw) { clear(); myTIASurface->render(); @@ -378,8 +379,8 @@ void FrameBuffer::update(bool force) case EventHandlerState::MESSAGEMENU: { - force = force || myOSystem.messageMenu().needsRedraw(); - if (force) + redraw = myOSystem.messageMenu().needsRedraw(); + if(force || redraw) { clear(); myTIASurface->render(); @@ -390,8 +391,8 @@ void FrameBuffer::update(bool force) case EventHandlerState::TIMEMACHINE: { - force = force || myOSystem.timeMachine().needsRedraw(); - if(force) + redraw = myOSystem.timeMachine().needsRedraw(); + if(force || redraw) { clear(); myTIASurface->render(); @@ -436,10 +437,9 @@ void FrameBuffer::update(bool force) case EventHandlerState::LAUNCHER: { - force = force || myOSystem.launcher().needsRedraw(); - if(force) + redraw = myOSystem.launcher().needsRedraw(); + if(force || redraw) { - //clear(); myOSystem.launcher().draw(force); } break; // EventHandlerState::LAUNCHER @@ -449,10 +449,10 @@ void FrameBuffer::update(bool force) #ifdef DEBUGGER_SUPPORT case EventHandlerState::DEBUGGER: { - force = force || myOSystem.debugger().needsRedraw(); - if(force) + redraw = myOSystem.debugger().needsRedraw(); + if(force || redraw) { - clear(); + myOSystem.debugger().draw(force); } break; // EventHandlerState::DEBUGGER @@ -471,7 +471,7 @@ void FrameBuffer::update(bool force) drawMessage(); // Push buffers to screen only when necessary - if(force) + if(force || redraw) myBackend->renderToScreen(); } diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 8577eb50f..60bc9b32d 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -91,32 +91,19 @@ void DialogContainer::updateTime(uInt64 time) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool DialogContainer::draw(bool full) { - //cerr << "draw " << full << endl; + cerr << "draw " << full << " " << typeid(*this).name() << endl; if(myDialogStack.empty()) return false; // Make the top dialog dirty if a full redraw is requested - //if(full) - // myDialogStack.top()->setDirty(); + if(full) + myDialogStack.top()->setDirty(); - // If the top dialog is dirty, then all below it must be redrawn too - const bool dirty = needsRedraw(); - //if(dirty) - // myDialogStack.top()->setDirty(); - - //myDialogStack.applyAll([&](Dialog*& d){ - // if(dirty) - // d->setDirty(); - // full |= d->render(); - //}); - //if(dirty) - { - myDialogStack.applyAll([&](Dialog*& d) { - if(d->needsRedraw()) - //d->setDirty(); - full |= d->render(); - }); - } + // Render all dirty dialogs + myDialogStack.applyAll([&](Dialog*& d) { + if(d->needsRedraw()) + full |= d->render(); + }); return full; } From 250a1634de40c312cb835c3e55d15fa1b5aee6de Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 16:50:49 +0100 Subject: [PATCH 165/263] fixed RomInfoWidget drawing --- src/gui/RomInfoWidget.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx index 01b30015b..c2068a4d1 100644 --- a/src/gui/RomInfoWidget.cxx +++ b/src/gui/RomInfoWidget.cxx @@ -172,6 +172,8 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node) myRomInfo.push_back("Controllers: " + (left + " (left), " + right + " (right)")); if (bsDetected != "") myRomInfo.push_back("Type: " + Bankswitch::typeToDesc(Bankswitch::nameToType(bsDetected))); + + setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -227,4 +229,5 @@ void RomInfoWidget::drawWidget(bool hilite) onTop ? _textcolor : _shadowcolor); ypos += _font.getLineHeight() + (lines - 1) * _font.getFontHeight(); } + clearDirty(); } From 678892e8c7fdbe36a5c133dd2a70e42c9eceb24b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 17:26:40 +0100 Subject: [PATCH 166/263] added blinking cursor --- src/gui/Dialog.cxx | 7 +++-- src/gui/Dialog.hxx | 2 +- src/gui/EditableWidget.cxx | 55 +++++++++++++++++++++++++++++++------- src/gui/EditableWidget.hxx | 4 +++ src/gui/GuiObject.hxx | 4 +-- src/gui/Widget.cxx | 4 +-- src/gui/Widget.hxx | 2 +- 7 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index f519cdadc..669d7341c 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -156,7 +156,7 @@ void Dialog::setDirty() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Dialog::isDirty() const +bool Dialog::isDirty() { return _dirty; } @@ -221,8 +221,6 @@ void Dialog::positionAt(uInt32 pos) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Dialog::render() { - //assert(_dirty); - if(!isVisible() || !needsRedraw()) return false; @@ -404,7 +402,7 @@ void Dialog::drawDialog() if(isDirty()) { - cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; + //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; // Dialog is still on top if e.g a ContextMenu is opened _onTop = parent().myDialogStack.top() == this @@ -446,6 +444,7 @@ void Dialog::drawDialog() w = _firstWidget; while(w) { + // only redraw changed widgets if(w->needsRedraw()) w->draw(); diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index d9b750ab6..68a71608c 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -65,7 +65,7 @@ class Dialog : public GuiObject // A dialog being dirty indicates that its underlying surface needs to be // redrawn and then re-rendered; this is taken care of in ::render() void setDirty() override; - bool isDirty() const override; + bool isDirty() override; // TODO: remove bool isChainDirty() const override; bool render(); diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 16b371813..b1783c10c 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -62,6 +62,23 @@ void EditableWidget::setText(const string& str, bool) setDirty(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::isDirty() +{ + if(_hasFocus && _editable && isVisible() && _boss->isVisible()) + { + _caretTimer++; + if(_caretTimer > 40) // switch every 2/3rd seconds + { + _caretTimer = 0; + _caretEnabled = !_caretEnabled; + _dirty = true; + } + cerr << "."; + } + + return _dirty; +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::setEditable(bool editable, bool hiliteBG) @@ -79,6 +96,15 @@ void EditableWidget::setEditable(bool editable, bool hiliteBG) } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EditableWidget::receivedFocusWidget() +{ + _caretTimer = 0; + _caretEnabled = true; + + Widget::receivedFocusWidget(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::lostFocusWidget() { @@ -316,22 +342,31 @@ void EditableWidget::drawCaretSelection() if (!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus) return; - const Common::Rect& editRect = getEditRect(); - int x = editRect.x(); - int y = editRect.y(); + if(_caretEnabled) + { + FBSurface& s = _boss->dialog().surface(); + const Common::Rect& editRect = getEditRect(); + int x = editRect.x(); + int y = editRect.y(); + x += getCaretOffset(); - x += getCaretOffset(); + x += _x; + y += _y; - x += _x; - y += _y; - - FBSurface& s = _boss->dialog().surface(); - s.vLine(x, y + 2, y + editRect.h() - 2, kTextColorHi); - s.vLine(x-1, y + 2, y + editRect.h() - 2, kTextColorHi); + s.vLine(x, y + 2, y + editRect.h() - 2, kTextColorHi); + s.vLine(x-1, y + 2, y + editRect.h() - 2, kTextColorHi); + clearDirty(); + } if(_selectSize) { + FBSurface& s = _boss->dialog().surface(); + const Common::Rect& editRect = getEditRect(); + int x = editRect.x(); + int y = editRect.y(); + string text = selectString(); + x = editRect.x(); y = editRect.y(); int w = editRect.w(); diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index fda92ccdf..e4dfbc2f7 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -65,7 +65,9 @@ class EditableWidget : public Widget, public CommandSender void setTextFilter(const TextFilter& filter) { _filter = filter; } protected: + void receivedFocusWidget() override; void lostFocusWidget() override; + bool isDirty() override; virtual void startEditMode() { setFlags(Widget::FLAG_WANTS_RAWDATA); } virtual void endEditMode() { clearFlags(Widget::FLAG_WANTS_RAWDATA); } @@ -110,6 +112,8 @@ class EditableWidget : public Widget, public CommandSender unique_ptr myUndoHandler; int _caretPos{0}; + int _caretTimer{0}; + bool _caretEnabled{true}; // Size of current selected text // 0 = no selection diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index 3bb510a6b..a6cf4e5ca 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -93,9 +93,9 @@ class GuiObject : public CommandReceiver virtual bool isVisible() const = 0; virtual void setDirty() = 0; virtual void clearDirty() { _dirty = false; } - virtual bool isDirty() const { return _dirty; } + virtual bool isDirty() { return _dirty; } virtual bool isChainDirty() const = 0; - virtual bool needsRedraw() const { return isDirty() || isChainDirty(); }; + virtual bool needsRedraw() { return isDirty() || isChainDirty(); }; void setFlags(uInt32 flags) { _flags |= flags; setDirty(); } void clearFlags(uInt32 flags) { _flags &= ~flags; setDirty(); } diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 6358808e7..c9e0441e7 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -63,7 +63,7 @@ void Widget::setDirty() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Widget::isDirty() const +bool Widget::isDirty() { //string name = typeid(*this).name(); //if(_dirty && name == "class TabWidget") @@ -353,7 +353,7 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font, _label(text), _align(align) { - _flags = Widget::FLAG_ENABLED; + _flags = Widget::FLAG_ENABLED | FLAG_CLEARBG; _bgcolor = kDlgColor; _bgcolorhi = kDlgColor; diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 270f1eb32..3e70523c0 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -70,7 +70,7 @@ class Widget : public GuiObject virtual bool handleEvent(Event::Type event) { return false; } void setDirty() override; - bool isDirty() const override; + bool isDirty() override; // TODO: remove bool isChainDirty() const override; void draw() override; void receivedFocus(); From bec842b9d72379e80ec7d5f45d8442362df6e16b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 18:24:30 +0100 Subject: [PATCH 167/263] removed some superfluous redraws --- src/debugger/gui/DataGridWidget.cxx | 8 ++++---- src/debugger/gui/RomListWidget.cxx | 8 ++++---- src/debugger/gui/TiaZoomWidget.cxx | 8 ++++---- src/debugger/gui/ToggleWidget.cxx | 8 ++++---- src/gui/Dialog.cxx | 29 ++++++++++++++--------------- src/gui/EditTextWidget.cxx | 8 ++++---- src/gui/GuiObject.hxx | 18 ++++++++++++++++-- src/gui/PopUpWidget.cxx | 8 ++++---- src/gui/ScrollBarWidget.cxx | 8 ++++---- src/gui/StringListWidget.cxx | 8 ++++---- src/gui/TabWidget.cxx | 8 ++++---- src/gui/Widget.cxx | 14 +++++++++----- 12 files changed, 75 insertions(+), 58 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index f3b81676c..32358dd05 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -242,15 +242,15 @@ void DataGridWidget::setRange(int lower, int upper) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DataGridWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DataGridWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 48885f734..20fc53052 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -285,15 +285,15 @@ void RomListWidget::handleMouseWheel(int x, int y, int direction) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomListWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomListWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx index e4553f361..a008c4444 100644 --- a/src/debugger/gui/TiaZoomWidget.cxx +++ b/src/debugger/gui/TiaZoomWidget.cxx @@ -181,15 +181,15 @@ void TiaZoomWidget::handleMouseMoved(int x, int y) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaZoomWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaZoomWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); myMouseMoving = false; } diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index 02ba10146..ea3253d8a 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -43,15 +43,15 @@ ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToggleWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToggleWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 669d7341c..26922f26d 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -438,19 +438,6 @@ void Dialog::drawDialog() clearDirty(); } - Widget* w = _firstWidget; - - // Draw all children - w = _firstWidget; - while(w) - { - - // only redraw changed widgets - if(w->needsRedraw()) - w->draw(); - w = w->_next; - } - // Draw outlines for focused widgets // Don't change focus, since this will trigger lost and received // focus events @@ -458,8 +445,20 @@ void Dialog::drawDialog() { _focusedWidget = Widget::setFocusForChain(this, getFocusList(), _focusedWidget, 0, false); - if(_focusedWidget) - _focusedWidget->draw(); // make sure the highlight color is drawn initially + // if(_focusedWidget) + // _focusedWidget->draw(); // make sure the highlight color is drawn initially + } + + Widget* w = _firstWidget; + + // Draw all children + w = _firstWidget; + while(w) + { + // only redraw changed widgets + if(w->needsRedraw()) + w->draw(); + w = w->_next; } } diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index 6105e70d3..c818f3cf0 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -51,15 +51,15 @@ void EditTextWidget::setText(const string& str, bool changed) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditTextWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled() && isEditable()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditTextWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled() && isEditable()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index a6cf4e5ca..811f1569b 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -97,8 +97,22 @@ class GuiObject : public CommandReceiver virtual bool isChainDirty() const = 0; virtual bool needsRedraw() { return isDirty() || isChainDirty(); }; - void setFlags(uInt32 flags) { _flags |= flags; setDirty(); } - void clearFlags(uInt32 flags) { _flags &= ~flags; setDirty(); } + void setFlags(uInt32 flags) + { + uInt32 oldFlags = _flags; + + _flags |= flags; + if(oldFlags != _flags) + setDirty(); + } + void clearFlags(uInt32 flags) + { + uInt32 oldFlags = _flags; + + _flags &= ~flags; + if(oldFlags != _flags) + setDirty(); + } uInt32 getFlags() const { return _flags; } bool hasBorder() const { return _flags & FLAG_BORDER; } diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 8540f2df3..cf799dc47 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -161,15 +161,15 @@ void PopUpWidget::handleMouseWheel(int x, int y, int direction) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PopUpWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PopUpWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ScrollBarWidget.cxx b/src/gui/ScrollBarWidget.cxx index 451f4a3ee..04a99c732 100644 --- a/src/gui/ScrollBarWidget.cxx +++ b/src/gui/ScrollBarWidget.cxx @@ -243,16 +243,16 @@ void ScrollBarWidget::checkBounds(int old_pos) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ScrollBarWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ScrollBarWidget::handleMouseLeft() { _part = Part::None; - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 4171632cb..5032654e6 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -53,15 +53,15 @@ void StringListWidget::setList(const StringList& list) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StringListWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StringListWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx index 61f42b350..5e96338ab 100644 --- a/src/gui/TabWidget.cxx +++ b/src/gui/TabWidget.cxx @@ -216,15 +216,15 @@ void TabWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TabWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); - setDirty(); + //if(isEnabled()) + // setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TabWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); - setDirty(); + //if(isEnabled()) + // clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index c9e0441e7..69c94b3ed 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -157,6 +157,7 @@ void Widget::draw() _x = oldX; _y = oldY; } + clearDirty(); // Draw all children Widget* w = _firstWidget; @@ -166,7 +167,6 @@ void Widget::draw() w->draw(); w = w->_next; } - clearDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -448,13 +448,15 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ButtonWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ButtonWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -558,13 +560,15 @@ CheckboxWidget::CheckboxWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CheckboxWidget::handleMouseEntered() { - setFlags(Widget::FLAG_HILITED); + if(isEnabled()) + setFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CheckboxWidget::handleMouseLeft() { - clearFlags(Widget::FLAG_HILITED); + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From cc21f75b958444ee0dc27c2d8d38251efbc0c2c8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 19:54:44 +0100 Subject: [PATCH 168/263] improved blinking cursor --- src/gui/EditableWidget.cxx | 52 +++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index b1783c10c..0b78c8952 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -133,7 +133,7 @@ bool EditableWidget::handleText(char text) if(tryInsertChar(text, _caretPos)) { - _caretPos++; + setCaretPos(_caretPos + 1); sendCommand(EditableWidget::kChangedCmd, 0, _id); setDirty(); return true; @@ -291,7 +291,7 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod) { // Put caret at last difference myUndoHandler->lastDiff(_editString, oldString); - _caretPos = myUndoHandler->lastDiff(_editString, oldString); + setCaretPos(myUndoHandler->lastDiff(_editString, oldString)); _selectSize = 0; sendCommand(EditableWidget::kChangedCmd, key, _id); } @@ -342,22 +342,7 @@ void EditableWidget::drawCaretSelection() if (!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus) return; - if(_caretEnabled) - { - FBSurface& s = _boss->dialog().surface(); - const Common::Rect& editRect = getEditRect(); - int x = editRect.x(); - int y = editRect.y(); - x += getCaretOffset(); - - x += _x; - y += _y; - - s.vLine(x, y + 2, y + editRect.h() - 2, kTextColorHi); - s.vLine(x-1, y + 2, y + editRect.h() - 2, kTextColorHi); - clearDirty(); - } - + // Draw the selection if(_selectSize) { FBSurface& s = _boss->dialog().surface(); @@ -393,6 +378,24 @@ void EditableWidget::drawCaretSelection() s.drawString(_font, text, x, y + 1, w, h, kTextColorInv, TextAlign::Left, 0, false); } + + // Draw the caret + if(_caretEnabled ^ (_selectSize != 0)) + { + FBSurface& s = _boss->dialog().surface(); + const Common::Rect& editRect = getEditRect(); + int x = editRect.x(); + int y = editRect.y(); + ColorId color = _caretEnabled ? kTextColorHi : kTextColorInv; + + x += getCaretOffset(); + x += _x; + y += _y; + + s.vLine(x, y + 1, y + editRect.h() - 3, color); + s.vLine(x - 1, y + 1, y + editRect.h() - 3, color); + clearDirty(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -401,6 +404,9 @@ bool EditableWidget::setCaretPos(int newPos) assert(newPos >= 0 && newPos <= int(_editString.size())); _caretPos = newPos; + _caretTimer = 0; + _caretEnabled = true; + return adjustOffset(); } @@ -410,6 +416,8 @@ bool EditableWidget::moveCaretPos(int direction) if(setCaretPos(_caretPos + direction)) { _selectSize -= direction; + _caretTimer = 0; + _caretEnabled = true; return true; } return false; @@ -487,6 +495,7 @@ bool EditableWidget::killChar(int direction, bool addEdit) { myUndoHandler->endChars(_editString); _editString.erase(_caretPos, 1); + setCaretPos(_caretPos); if(addEdit) myUndoHandler->doo(_editString); @@ -591,7 +600,7 @@ bool EditableWidget::moveWord(int direction, bool select) if(select) _selectSize++; } - _caretPos = currentPos; + setCaretPos(currentPos); handled = true; } else if(direction == +1) // move to first character of next word @@ -610,7 +619,7 @@ bool EditableWidget::moveWord(int direction, bool select) if(select) _selectSize--; } - _caretPos = currentPos; + setCaretPos(currentPos); handled = true; } @@ -665,6 +674,7 @@ bool EditableWidget::killSelectedText(bool addEdit) _selectSize = -_selectSize; } _editString.erase(_caretPos, _selectSize); + setCaretPos(_caretPos); _selectSize = 0; if(addEdit) myUndoHandler->doo(_editString); @@ -724,7 +734,7 @@ bool EditableWidget::pasteSelectedText() _editString.insert(_caretPos, buf.str()); // position cursor at the end of pasted text - _caretPos += int(buf.str().length()); + setCaretPos(_caretPos + int(buf.str().length())); if(selected || !pasted.empty()) { From f64285425ac7f6bccbf39cb32f69056150f4865e Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 11 Nov 2020 23:32:00 +0100 Subject: [PATCH 169/263] split Dialog drawing and rendering and skip drawing render when possible --- src/gui/Dialog.cxx | 17 ++++++++++------- src/gui/Dialog.hxx | 3 ++- src/gui/DialogContainer.cxx | 20 ++++++++++---------- src/gui/DialogContainer.hxx | 4 +--- src/gui/EditableWidget.cxx | 1 - src/gui/PopUpWidget.cxx | 2 +- 6 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 26922f26d..9cb5accb2 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -128,7 +128,6 @@ void Dialog::close() _visible = false; parent().removeDialog(); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -219,26 +218,30 @@ void Dialog::positionAt(uInt32 pos) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Dialog::render() +void Dialog::redraw() { if(!isVisible() || !needsRedraw()) - return false; + return;// false; // Draw this dialog center(); drawDialog(); + render(); +// return true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::render() +{ // Update dialog surface; also render any extra surfaces // Extra surfaces must be rendered afterwards, so they are drawn on top if(_surface->render()) { - mySurfaceStack.applyAll([](shared_ptr& surface){ + mySurfaceStack.applyAll([](shared_ptr& surface) { surface->render(); }); } - //_dirty = false; - - return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 68a71608c..b9a924b55 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -67,7 +67,8 @@ class Dialog : public GuiObject void setDirty() override; bool isDirty() override; // TODO: remove bool isChainDirty() const override; - bool render(); + void redraw(); + void render(); void addFocusWidget(Widget* w) override; void addToFocusList(WidgetArray& list) override; diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 60bc9b32d..9649e447c 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -89,11 +89,11 @@ void DialogContainer::updateTime(uInt64 time) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool DialogContainer::draw(bool full) +void DialogContainer::draw(bool full) { cerr << "draw " << full << " " << typeid(*this).name() << endl; if(myDialogStack.empty()) - return false; + return; // Make the top dialog dirty if a full redraw is requested if(full) @@ -102,10 +102,8 @@ bool DialogContainer::draw(bool full) // Render all dirty dialogs myDialogStack.applyAll([&](Dialog*& d) { if(d->needsRedraw()) - full |= d->render(); + d->redraw(); }); - - return full; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -133,7 +131,7 @@ int DialogContainer::addDialog(Dialog* d) "Unable to show dialog box; FIX THE CODE"); else { - // fade out current top dialog + // "darken" current top dialog if(!myDialogStack.empty()) myDialogStack.top()->setDirty(); d->setDirty(); @@ -148,14 +146,16 @@ void DialogContainer::removeDialog() if(!myDialogStack.empty()) { myDialogStack.pop(); - // necessary as long as all dialogs share the same surface + if(!myDialogStack.empty()) { - //myDialogStack.top()->setDirty(); + // this "undarkens" the top dialog + myDialogStack.top()->setDirty(); - // Mark all dialogs for redraw + // Rerender all dialogs (TODO: top dialog is rendered twice) myDialogStack.applyAll([&](Dialog*& d){ - d->setDirty(); + //d->setDirty(); + d->render(); }); } } diff --git a/src/gui/DialogContainer.hxx b/src/gui/DialogContainer.hxx index cc50e23b6..1f6cce8f6 100644 --- a/src/gui/DialogContainer.hxx +++ b/src/gui/DialogContainer.hxx @@ -121,10 +121,8 @@ class DialogContainer /** Draw the stack of menus (full indicates to redraw all items). - - @return Answers whether any drawing actually occurred. */ - bool draw(bool full = false); + void draw(bool full = false); /** Answers whether a full redraw is required. diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 0b78c8952..4032daae3 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -74,7 +74,6 @@ bool EditableWidget::isDirty() _caretEnabled = !_caretEnabled; _dirty = true; } - cerr << "."; } return _dirty; diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index cf799dc47..ccf6af1aa 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -277,7 +277,7 @@ void PopUpWidget::drawWidget(bool hilite) // Fill the background ColorId bgCol = isEditable() ? kWidColor : kDlgColor; - s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 0), _h - 2, + s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 1), _h - 2, onTop ? _changed ? kDbgChangedColor : bgCol : kDlgColor); s.fillRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2, onTop ? isEnabled() && hilite ? kBtnColorHi : bgCol : kBGColorLo); From a643b3d239dbe5af0464b3da53cde0ac56d9217d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 10:43:04 +0100 Subject: [PATCH 170/263] minimized UI redraws and renderings when message is displayed refactored message creation --- src/common/PNGLibrary.cxx | 6 +- src/common/PaletteHandler.cxx | 8 +- src/common/RewindManager.cxx | 4 +- src/common/SoundSDL2.cxx | 4 +- src/common/StateManager.cxx | 18 +- src/debugger/gui/RomWidget.cxx | 2 +- src/debugger/gui/TiaOutputWidget.cxx | 8 +- src/debugger/gui/TiaZoomWidget.cxx | 4 +- src/emucore/Console.cxx | 42 ++-- src/emucore/EventHandler.cxx | 46 ++--- src/emucore/FrameBuffer.cxx | 295 +++++++++++++-------------- src/emucore/FrameBuffer.hxx | 25 ++- src/emucore/OSystem.cxx | 6 +- src/emucore/QuadTari.cxx | 2 +- src/emucore/TIASurface.cxx | 10 +- src/gui/DialogContainer.cxx | 4 +- src/gui/GameInfoDialog.cxx | 6 +- src/gui/LauncherDialog.cxx | 2 +- src/gui/LoggerDialog.cxx | 4 +- src/gui/TimeMachineDialog.cxx | 4 +- 20 files changed, 252 insertions(+), 248 deletions(-) diff --git a/src/common/PNGLibrary.cxx b/src/common/PNGLibrary.cxx index 901d42478..2a6f84d6a 100644 --- a/src/common/PNGLibrary.cxx +++ b/src/common/PNGLibrary.cxx @@ -267,7 +267,7 @@ void PNGLibrary::toggleContinuousSnapshots(bool perFrame) buf << "Enabling snapshots in " << interval << " second intervals"; interval *= uInt32(myOSystem.frameRate()); } - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); setContinuousSnapInterval(interval); } else @@ -276,7 +276,7 @@ void PNGLibrary::toggleContinuousSnapshots(bool perFrame) buf << "Disabling snapshots, generated " << (mySnapCounter / mySnapInterval) << " files"; - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); setContinuousSnapInterval(0); } } @@ -378,7 +378,7 @@ void PNGLibrary::takeSnapshot(uInt32 number) // Re-enable old messages myOSystem.frameBuffer().enableMessages(true); } - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/PaletteHandler.cxx b/src/common/PaletteHandler.cxx index db6961af8..f13c18ab1 100644 --- a/src/common/PaletteHandler.cxx +++ b/src/common/PaletteHandler.cxx @@ -69,7 +69,7 @@ void PaletteHandler::cyclePalette(int direction) const string palette = toPaletteName(PaletteType(type)); const string message = MESSAGES[type] + " palette"; - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); setPalette(palette); } @@ -112,7 +112,7 @@ void PaletteHandler::showAdjustableMessage() const float value = myOSystem.console().timing() == ConsoleTiming::pal ? myPhasePAL : myPhaseNTSC; buf << std::fixed << std::setprecision(1) << value << DEGREE; - myOSystem.frameBuffer().showMessage( + myOSystem.frameBuffer().showGaugeMessage( "Palette phase shift", buf.str(), value, (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) - MAX_PHASE_SHIFT, (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) + MAX_PHASE_SHIFT); @@ -122,7 +122,7 @@ void PaletteHandler::showAdjustableMessage() const float value = *myAdjustables[myCurrentAdjustable].value; buf << std::fixed << std::setprecision(1) << value << DEGREE; - myOSystem.frameBuffer().showMessage( + myOSystem.frameBuffer().showGaugeMessage( msg.str(), buf.str(), value, -MAX_RGB_SHIFT, +MAX_RGB_SHIFT); } else @@ -131,7 +131,7 @@ void PaletteHandler::showAdjustableMessage() ? scaleRGBTo100(*myAdjustables[myCurrentAdjustable].value) : scaleTo100(*myAdjustables[myCurrentAdjustable].value); buf << value << "%"; - myOSystem.frameBuffer().showMessage( + myOSystem.frameBuffer().showGaugeMessage( msg.str(), buf.str(), value); } } diff --git a/src/common/RewindManager.cxx b/src/common/RewindManager.cxx index bc6b70813..044bc57e9 100644 --- a/src/common/RewindManager.cxx +++ b/src/common/RewindManager.cxx @@ -181,7 +181,7 @@ uInt32 RewindManager::rewindStates(uInt32 numStates) if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE && myOSystem.eventHandler().state() != EventHandlerState::PLAYBACK) - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); return i; } @@ -216,7 +216,7 @@ uInt32 RewindManager::unwindStates(uInt32 numStates) if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE && myOSystem.eventHandler().state() != EventHandlerState::PLAYBACK) - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); return i; } diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 6caabc72e..40b95b0f0 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -224,7 +224,7 @@ bool SoundSDL2::toggleMute() string message = "Sound "; message += enabled ? "unmuted" : "muted"; - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); //ostringstream strval; //uInt32 volume; @@ -282,7 +282,7 @@ void SoundSDL2::adjustVolume(int direction) strval << percent << "%"; else strval << "Off"; - myOSystem.frameBuffer().showMessage("Volume", strval.str(), percent); + myOSystem.frameBuffer().showGaugeMessage("Volume", strval.str(), percent); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/StateManager.cxx b/src/common/StateManager.cxx index a4add0889..956f62409 100644 --- a/src/common/StateManager.cxx +++ b/src/common/StateManager.cxx @@ -132,9 +132,9 @@ void StateManager::toggleTimeMachine() myActiveMode = myActiveMode == Mode::TimeMachine ? Mode::Off : Mode::TimeMachine; if(myActiveMode == Mode::TimeMachine) - myOSystem.frameBuffer().showMessage("Time Machine enabled"); + myOSystem.frameBuffer().showTextMessage("Time Machine enabled"); else - myOSystem.frameBuffer().showMessage("Time Machine disabled"); + myOSystem.frameBuffer().showTextMessage("Time Machine disabled"); myOSystem.settings().setValue(devSettings ? "dev.timemachine" : "plr.timemachine", myActiveMode == Mode::TimeMachine); } @@ -215,7 +215,7 @@ void StateManager::loadState(int slot) { buf.str(""); buf << "Can't open/load from state file " << slot; - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); return; } @@ -239,7 +239,7 @@ void StateManager::loadState(int slot) buf << "Invalid data in state " << slot << " file"; } - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); } } @@ -261,7 +261,7 @@ void StateManager::saveState(int slot) { buf.str(""); buf << "Can't open/save to state file " << slot; - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); return; } @@ -274,7 +274,7 @@ void StateManager::saveState(int slot) catch(...) { buf << "Error saving state " << slot; - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); return; } @@ -292,7 +292,7 @@ void StateManager::saveState(int slot) else buf << "Error saving state " << slot; - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); } } @@ -307,7 +307,7 @@ void StateManager::changeState(int direction) buf << "Changed to state slot " << myCurrentSlot; else buf << "State slot " << myCurrentSlot; - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -318,7 +318,7 @@ void StateManager::toggleAutoSlot() // Print appropriate message ostringstream buf; buf << "Automatic slot change " << (autoSlot ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(buf.str()); + myOSystem.frameBuffer().showTextMessage(buf.str()); myOSystem.settings().setValue("autoslot", autoSlot); } diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx index 9b387d69f..87572d6ed 100644 --- a/src/debugger/gui/RomWidget.cxx +++ b/src/debugger/gui/RomWidget.cxx @@ -199,7 +199,7 @@ void RomWidget::runtoPC(int disasm_line) ostringstream command; command << "runtopc #" << address; string msg = instance().debugger().run(command.str()); - instance().frameBuffer().showMessage(msg); + instance().frameBuffer().showTextMessage(msg); } } diff --git a/src/debugger/gui/TiaOutputWidget.cxx b/src/debugger/gui/TiaOutputWidget.cxx index 01d6d094b..2062bd436 100644 --- a/src/debugger/gui/TiaOutputWidget.cxx +++ b/src/debugger/gui/TiaOutputWidget.cxx @@ -92,10 +92,10 @@ void TiaOutputWidget::saveSnapshot(int execDepth, const string& execPrefix) message = e.what(); } if (execDepth == 0) { - instance().frameBuffer().showMessage(message); + instance().frameBuffer().showTextMessage(message); } #else - instance().frameBuffer().showMessage("PNG image saving not supported"); + instance().frameBuffer().showTextMessage("PNG image saving not supported"); #endif } @@ -135,7 +135,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in { command << "scanline #" << lines; string message = instance().debugger().parser().run(command.str()); - instance().frameBuffer().showMessage(message); + instance().frameBuffer().showTextMessage(message); } } else if(rmb == "bp") @@ -144,7 +144,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in int scanline = myClickY + startLine; command << "breakif _scan==#" << scanline; string message = instance().debugger().parser().run(command.str()); - instance().frameBuffer().showMessage(message); + instance().frameBuffer().showTextMessage(message); } else if(rmb == "zoom") { diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx index a008c4444..759e95516 100644 --- a/src/debugger/gui/TiaZoomWidget.cxx +++ b/src/debugger/gui/TiaZoomWidget.cxx @@ -262,7 +262,7 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int { command << "scanline #" << lines; string message = instance().debugger().parser().run(command.str()); - instance().frameBuffer().showMessage(message); + instance().frameBuffer().showTextMessage(message); } } else if(rmb == "bp") @@ -271,7 +271,7 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int int scanline = myClickY / myZoomLevel + myOffY + startLine; command << "breakif _scan==#" << scanline; string message = instance().debugger().parser().run(command.str()); - instance().frameBuffer().showMessage(message); + instance().frameBuffer().showTextMessage(message); } else { diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 099773989..bb292859e 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -476,7 +476,7 @@ void Console::setFormat(uInt32 format, bool force) initializeAudio(); // ensure that audio synthesis is set up to match emulation rate myOSystem.resetFps(); // Reset FPS measurement - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); // Let the other devices know about the console change mySystem->consoleChanged(myConsoleTiming); @@ -493,10 +493,10 @@ void Console::toggleColorLoss(bool toggle) string message = string("PAL color-loss ") + (colorloss ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } else - myOSystem.frameBuffer().showMessage( + myOSystem.frameBuffer().showTextMessage( "PAL color-loss not available in non PAL modes"); } @@ -521,7 +521,7 @@ void Console::toggleInter(bool toggle) ostringstream ss; ss << "Interpolation " << (enabled ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(ss.str()); + myOSystem.frameBuffer().showTextMessage(ss.str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -539,7 +539,7 @@ void Console::toggleTurbo() ostringstream ss; ss << "Turbo mode " << (!enabled ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(ss.str()); + myOSystem.frameBuffer().showTextMessage(ss.str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -564,7 +564,7 @@ void Console::changeSpeed(int direction) ostringstream val; val << formatSpeed(speed) << "%"; - myOSystem.frameBuffer().showMessage("Emulation speed", val.str(), speed, MIN_SPEED, MAX_SPEED); + myOSystem.frameBuffer().showGaugeMessage("Emulation speed", val.str(), speed, MIN_SPEED, MAX_SPEED); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -574,13 +574,13 @@ void Console::togglePhosphor() { myProperties.set(PropType::Display_Phosphor, "NO"); myOSystem.frameBuffer().tiaSurface().enablePhosphor(false); - myOSystem.frameBuffer().showMessage("Phosphor effect disabled"); + myOSystem.frameBuffer().showTextMessage("Phosphor effect disabled"); } else { myProperties.set(PropType::Display_Phosphor, "YES"); myOSystem.frameBuffer().tiaSurface().enablePhosphor(true); - myOSystem.frameBuffer().showMessage("Phosphor effect enabled"); + myOSystem.frameBuffer().showTextMessage("Phosphor effect enabled"); } } @@ -605,7 +605,7 @@ void Console::changePhosphor(int direction) val.str(""); val << "Off"; } - myOSystem.frameBuffer().showMessage("Phosphor blend", val.str(), blend); + myOSystem.frameBuffer().showGaugeMessage("Phosphor blend", val.str(), blend); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -699,7 +699,7 @@ void Console::changeVerticalCenter(int direction) if (vcenter != myTIA->vcenter()) myTIA->setVcenter(vcenter); val << (vcenter ? vcenter > 0 ? "+" : "" : " ") << vcenter << "px"; - myOSystem.frameBuffer().showMessage("V-Center", val.str(), vcenter, + myOSystem.frameBuffer().showGaugeMessage("V-Center", val.str(), vcenter, myTIA->minVcenter(), myTIA->maxVcenter()); } @@ -729,7 +729,7 @@ void Console::changeVSizeAdjust(int direction) val << (newAdjustVSize ? newAdjustVSize > 0 ? "+" : "" : " ") << newAdjustVSize << "%"; - myOSystem.frameBuffer().showMessage("V-Size", val.str(), newAdjustVSize, -5, 5); + myOSystem.frameBuffer().showGaugeMessage("V-Size", val.str(), newAdjustVSize, -5, 5); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -746,7 +746,7 @@ void Console::toggleCorrectAspectRatio(bool toggle) const string& message = string("Correct aspect ratio ") + (enabled ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -920,7 +920,7 @@ unique_ptr Console::getControllerPort(const Controller::Type type, Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { bool devSettings = os.settings().getBool("dev.settings"); if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); + os.frameBuffer().showTextMessage(msg); }; controller = make_unique(port, myEvent, *mySystem, myOSystem.settings().getString("avoxport"), nvramfile, callback); @@ -933,7 +933,7 @@ unique_ptr Console::getControllerPort(const Controller::Type type, Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { bool devSettings = os.settings().getBool("dev.settings"); if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); + os.frameBuffer().showTextMessage(msg); }; controller = make_unique(port, myEvent, *mySystem, nvramfile, callback); break; @@ -987,7 +987,7 @@ void Console::changeAutoFireRate(int direction) else val << "Off"; - myOSystem.frameBuffer().showMessage("Autofire rate", val.str(), rate, 0, isNTSC ? 30 : 25); + myOSystem.frameBuffer().showGaugeMessage("Autofire rate", val.str(), rate, 0, isNTSC ? 30 : 25); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1012,7 +1012,7 @@ void Console::toggleTIABit(TIABit bit, const string& bitname, bool show, bool to bool result = myTIA->toggleBit(bit, toggle ? 2 : 3); const string message = bitname + (result ? " enabled" : " disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1021,7 +1021,7 @@ void Console::toggleBits(bool toggle) const bool enabled = myTIA->toggleBits(toggle); const string message = string("TIA bits ") + (enabled ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1030,7 +1030,7 @@ void Console::toggleTIACollision(TIABit bit, const string& bitname, bool show, b bool result = myTIA->toggleCollision(bit, toggle ? 2 : 3); const string message = bitname + (result ? " collision enabled" : " collision disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1039,7 +1039,7 @@ void Console::toggleCollisions(bool toggle) const bool enabled = myTIA->toggleCollisions(toggle); const string message = string("TIA collisions ") + (enabled ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1048,7 +1048,7 @@ void Console::toggleFixedColors(bool toggle) const bool enabled = toggle ? myTIA->toggleFixedColors() : myTIA->usingFixedColors(); const string message = string("Fixed debug colors ") + (enabled ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1057,7 +1057,7 @@ void Console::toggleJitter(bool toggle) const bool enabled = myTIA->toggleJitter(toggle ? 2 : 3); const string message = string("TV scanline jitter ") + (enabled ? "enabled" : "disabled"); - myOSystem.frameBuffer().showMessage(message); + myOSystem.frameBuffer().showTextMessage(message); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 871d6cd73..9e7c9ea5f 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -191,12 +191,12 @@ void EventHandler::toggleSAPortOrder() if(saport == "lr") { mapStelladaptors("rl"); - myOSystem.frameBuffer().showMessage("Stelladaptor ports right/left"); + myOSystem.frameBuffer().showTextMessage("Stelladaptor ports right/left"); } else { mapStelladaptors("lr"); - myOSystem.frameBuffer().showMessage("Stelladaptor ports left/right"); + myOSystem.frameBuffer().showTextMessage("Stelladaptor ports left/right"); } #endif } @@ -214,7 +214,7 @@ void EventHandler::set7800Mode() void EventHandler::handleMouseControl() { if(myMouseControl) - myOSystem.frameBuffer().showMessage(myMouseControl->next()); + myOSystem.frameBuffer().showTextMessage(myMouseControl->next()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -550,7 +550,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) default: break; } - myOSystem.frameBuffer().showMessage(msg + " settings"); + myOSystem.frameBuffer().showTextMessage(msg + " settings"); myAdjustActive = false; } break; @@ -1210,7 +1210,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) case Event::SaveAllStates: if (pressed && !repeated) - myOSystem.frameBuffer().showMessage(myOSystem.state().rewindManager().saveAllStates()); + myOSystem.frameBuffer().showTextMessage(myOSystem.state().rewindManager().saveAllStates()); return; case Event::PreviousState: @@ -1243,7 +1243,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) case Event::LoadAllStates: if (pressed && !repeated) - myOSystem.frameBuffer().showMessage(myOSystem.state().rewindManager().loadAllStates()); + myOSystem.frameBuffer().showTextMessage(myOSystem.state().rewindManager().loadAllStates()); return; case Event::RewindPause: @@ -1476,7 +1476,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleBlackWhite, 0); myEvent.set(Event::ConsoleColor, 1); - myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause released" : "Color Mode"); + myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause released" : "Color Mode"); myOSystem.console().switches().update(); } return; @@ -1485,7 +1485,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleBlackWhite, 1); myEvent.set(Event::ConsoleColor, 0); - myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause pushed" : "B/W Mode"); + myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause pushed" : "B/W Mode"); myOSystem.console().switches().update(); } return; @@ -1496,13 +1496,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleBlackWhite, 1); myEvent.set(Event::ConsoleColor, 0); - myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause pushed" : "B/W Mode"); + myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause pushed" : "B/W Mode"); } else { myEvent.set(Event::ConsoleBlackWhite, 0); myEvent.set(Event::ConsoleColor, 1); - myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause released" : "Color Mode"); + myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause released" : "Color Mode"); } myOSystem.console().switches().update(); } @@ -1514,7 +1514,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) myEvent.set(Event::ConsoleBlackWhite, 0); myEvent.set(Event::ConsoleColor, 0); if (myIs7800) - myOSystem.frameBuffer().showMessage("Pause pressed"); + myOSystem.frameBuffer().showTextMessage("Pause pressed"); myOSystem.console().switches().update(); } return; @@ -1524,7 +1524,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleLeftDiffA, 1); myEvent.set(Event::ConsoleLeftDiffB, 0); - myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " A"); + myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " A"); myOSystem.console().switches().update(); } return; @@ -1533,7 +1533,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleLeftDiffA, 0); myEvent.set(Event::ConsoleLeftDiffB, 1); - myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " B"); + myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " B"); myOSystem.console().switches().update(); } return; @@ -1544,13 +1544,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleLeftDiffA, 0); myEvent.set(Event::ConsoleLeftDiffB, 1); - myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " B"); + myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " B"); } else { myEvent.set(Event::ConsoleLeftDiffA, 1); myEvent.set(Event::ConsoleLeftDiffB, 0); - myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " A"); + myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " A"); } myOSystem.console().switches().update(); } @@ -1561,7 +1561,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleRightDiffA, 1); myEvent.set(Event::ConsoleRightDiffB, 0); - myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " A"); + myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " A"); myOSystem.console().switches().update(); } return; @@ -1570,7 +1570,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleRightDiffA, 0); myEvent.set(Event::ConsoleRightDiffB, 1); - myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " B"); + myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " B"); myOSystem.console().switches().update(); } return; @@ -1581,13 +1581,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) { myEvent.set(Event::ConsoleRightDiffA, 0); myEvent.set(Event::ConsoleRightDiffB, 1); - myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " B"); + myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " B"); } else { myEvent.set(Event::ConsoleRightDiffA, 1); myEvent.set(Event::ConsoleRightDiffB, 0); - myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " A"); + myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " A"); } myOSystem.console().switches().update(); } @@ -2312,15 +2312,15 @@ bool EventHandler::enterDebugMode() myOSystem.debugger().setQuitState(); setState(EventHandlerState::EMULATION); if(fbstatus == FBInitStatus::FailTooLarge) - myOSystem.frameBuffer().showMessage("Debugger window too large for screen", - MessagePosition::BottomCenter, true); + myOSystem.frameBuffer().showTextMessage("Debugger window too large for screen", + MessagePosition::BottomCenter, true); return false; } myOverlay->reStack(); myOSystem.sound().mute(true); #else - myOSystem.frameBuffer().showMessage("Debugger support not included", - MessagePosition::BottomCenter, true); + myOSystem.frameBuffer().showTextMessage("Debugger support not included", + MessagePosition::BottomCenter, true); #endif return true; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 828c14e8f..66747b2a3 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -322,13 +322,8 @@ void FrameBuffer::update(bool force) // - at the bottom of ::update(), to actually draw them (this must come // last, since they are always drawn on top of everything else). - // Full rendering is required when messages are enabled - force |= (myMsg.counter >= 0); - - // Detect when a message has been turned off; one last redraw is required - // in this case, to draw over the area that the message occupied - if(myMsg.counter == 0) - myMsg.counter = -1; + // Forced full rendering is required when messages are being disabled + force |= (myMsg.enabled && myMsg.counter == 0); bool redraw = false; switch(myOSystem.eventHandler().state()) @@ -344,7 +339,7 @@ void FrameBuffer::update(bool force) if(myPausedCount-- <= 0) { myPausedCount = uInt32(7 * myOSystem.frameRate()); - showMessage("Paused", MessagePosition::MiddleCenter); + showTextMessage("Paused", MessagePosition::MiddleCenter); } if(force) myTIASurface->render(); @@ -422,12 +417,12 @@ void FrameBuffer::update(bool force) } force = force || success; - if (force) + if(force) myTIASurface->render(); // Stop playback mode at the end of the state buffer // and switch to Time Machine or Pause mode - if (!success) + if(!success) { frames = 0; myOSystem.eventHandler().enterMenuMode(EventHandlerState::TIMEMACHINE); @@ -468,7 +463,7 @@ void FrameBuffer::update(bool force) // indicates that, and then the code at the top of this method sees // the change and redraws everything if(myMsg.enabled) - drawMessage(); + redraw |= drawMessage(); // Push buffers to screen only when necessary if(force || redraw) @@ -501,19 +496,15 @@ void FrameBuffer::updateInEmulationMode(float framesPerSecond) myBackend->renderToScreen(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::showMessage(const string& message, MessagePosition position, - bool force) -{ #ifdef GUI_SUPPORT +void FrameBuffer::createMessage(const string& message, MessagePosition position, bool force) +{ // Only show messages if they've been enabled if(myMsg.surface == nullptr || !(force || myOSystem.settings().getBool("uimessages"))) return; - const int fontWidth = font().getMaxCharWidth(), - fontHeight = font().getFontHeight(); + const int fontHeight = font().getFontHeight(); const int VBORDER = fontHeight / 4; - const int HBORDER = fontWidth * 1.25 / 2.0; myMsg.counter = uInt32(myOSystem.frameRate()) * 2; // Show message for 2 seconds if(myMsg.counter == 0) @@ -522,39 +513,41 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position, // Precompute the message coordinates myMsg.text = message; myMsg.color = kBtnTextColor; - myMsg.showGauge = false; - myMsg.w = std::min(fontWidth * (MESSAGE_WIDTH) - HBORDER * 2, - font().getStringWidth(myMsg.text) + HBORDER * 2); myMsg.h = fontHeight + VBORDER * 2; myMsg.position = position; myMsg.enabled = true; + myMsg.dirty = true; + myMsg.surface->setSrcSize(myMsg.w, myMsg.h); myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor()); +} +#endif + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::showTextMessage(const string& message, MessagePosition position, + bool force) +{ +#ifdef GUI_SUPPORT + const int fontWidth = font().getMaxCharWidth(); + const int HBORDER = fontWidth * 1.25 / 2.0; + + myMsg.showGauge = false; + myMsg.w = std::min(fontWidth * (MESSAGE_WIDTH) - HBORDER * 2, + font().getStringWidth(message) + HBORDER * 2); + + createMessage(message, position, force); #endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::showMessage(const string& message, const string& valueText, - float value, float minValue, float maxValue) +void FrameBuffer::showGaugeMessage(const string& message, const string& valueText, + float value, float minValue, float maxValue) { #ifdef GUI_SUPPORT - // Only show messages if they've been enabled - if(myMsg.surface == nullptr || !myOSystem.settings().getBool("uimessages")) - return; - - const int fontWidth = font().getMaxCharWidth(), - fontHeight = font().getFontHeight(); - const int VBORDER = fontHeight / 4; + const int fontWidth = font().getMaxCharWidth(); const int HBORDER = fontWidth * 1.25 / 2.0; - myMsg.counter = uInt32(myOSystem.frameRate()) * 2; // Show message for 2 seconds - if(myMsg.counter == 0) - myMsg.counter = 120; - - // Precompute the message coordinates - myMsg.text = message; - myMsg.color = kBtnTextColor; myMsg.showGauge = true; if(maxValue - minValue != 0) myMsg.value = (value - minValue) / (maxValue - minValue) * 100.F; @@ -562,16 +555,12 @@ void FrameBuffer::showMessage(const string& message, const string& valueText, myMsg.value = 100.F; myMsg.valueText = valueText; myMsg.w = std::min(fontWidth * MESSAGE_WIDTH, - font().getStringWidth(myMsg.text) + font().getStringWidth(message) + fontWidth * (GAUGEBAR_WIDTH + 2) - + font().getStringWidth(myMsg.valueText)) - + HBORDER * 2; - myMsg.h = fontHeight + VBORDER * 2; - myMsg.position = MessagePosition::BottomCenter; - myMsg.enabled = true; + + font().getStringWidth(valueText)) + + HBORDER * 2; - myMsg.surface->setSrcSize(myMsg.w, myMsg.h); - myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor()); + createMessage(message, MessagePosition::BottomCenter); #endif } @@ -652,8 +641,8 @@ void FrameBuffer::toggleFrameStats(bool toggle) myOSystem.settings().setValue( myOSystem.settings().getBool("dev.settings") ? "dev.stats" : "plr.stats", myStatsEnabled); - myOSystem.frameBuffer().showMessage(string("Console info ") + - (myStatsEnabled ? "enabled" : "disabled")); + myOSystem.frameBuffer().showTextMessage(string("Console info ") + + (myStatsEnabled ? "enabled" : "disabled")); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -676,7 +665,6 @@ void FrameBuffer::enableMessages(bool enable) myStatsMsg.enabled = false; // Erase old messages on the screen - myMsg.enabled = false; myMsg.counter = 0; update(true); // Force update immediately } @@ -689,116 +677,120 @@ inline bool FrameBuffer::drawMessage() // Either erase the entire message (when time is reached), // or show again this frame if(myMsg.counter == 0) - { - myMsg.enabled = false; - return true; - } - else if(myMsg.counter < 0) { myMsg.enabled = false; return false; } - // Draw the bounded box and text - const Common::Rect& dst = myMsg.surface->dstRect(); - const int fontWidth = font().getMaxCharWidth(), - fontHeight = font().getFontHeight(); - const int VBORDER = fontHeight / 4; - const int HBORDER = fontWidth * 1.25 / 2.0; - constexpr int BORDER = 1; - - switch(myMsg.position) + if(myMsg.dirty) { - case MessagePosition::TopLeft: - myMsg.x = 5; - myMsg.y = 5; - break; + cerr << "--- draw message ---" << endl; - case MessagePosition::TopCenter: - myMsg.x = (imageRect().w() - dst.w()) >> 1; - myMsg.y = 5; - break; + // Draw the bounded box and text + const Common::Rect& dst = myMsg.surface->dstRect(); + const int fontWidth = font().getMaxCharWidth(), + fontHeight = font().getFontHeight(); + const int VBORDER = fontHeight / 4; + const int HBORDER = fontWidth * 1.25 / 2.0; + constexpr int BORDER = 1; - case MessagePosition::TopRight: - myMsg.x = imageRect().w() - dst.w() - 5; - myMsg.y = 5; - break; - - case MessagePosition::MiddleLeft: - myMsg.x = 5; - myMsg.y = (imageRect().h() - dst.h()) >> 1; - break; - - case MessagePosition::MiddleCenter: - myMsg.x = (imageRect().w() - dst.w()) >> 1; - myMsg.y = (imageRect().h() - dst.h()) >> 1; - break; - - case MessagePosition::MiddleRight: - myMsg.x = imageRect().w() - dst.w() - 5; - myMsg.y = (imageRect().h() - dst.h()) >> 1; - break; - - case MessagePosition::BottomLeft: - myMsg.x = 5; - myMsg.y = imageRect().h() - dst.h() - 5; - break; - - case MessagePosition::BottomCenter: - myMsg.x = (imageRect().w() - dst.w()) >> 1; - myMsg.y = imageRect().h() - dst.h() - 5; - break; - - case MessagePosition::BottomRight: - myMsg.x = imageRect().w() - dst.w() - 5; - myMsg.y = imageRect().h() - dst.h() - 5; - break; - } - - myMsg.surface->setDstPos(myMsg.x + imageRect().x(), myMsg.y + imageRect().y()); - myMsg.surface->fillRect(0, 0, myMsg.w, myMsg.h, kColor); - myMsg.surface->fillRect(BORDER, BORDER, myMsg.w - BORDER * 2, myMsg.h - BORDER * 2, kBtnColor); - myMsg.surface->drawString(font(), myMsg.text, HBORDER, VBORDER, - myMsg.w, myMsg.color); - - if(myMsg.showGauge) - { - constexpr int NUM_TICKMARKS = 4; - // limit gauge bar width if texts are too long - const int swidth = std::min(fontWidth * GAUGEBAR_WIDTH, - fontWidth * (MESSAGE_WIDTH - 2) - - font().getStringWidth(myMsg.text) - - font().getStringWidth(myMsg.valueText)); - const int bwidth = swidth * myMsg.value / 100.F; - const int bheight = fontHeight >> 1; - const int x = HBORDER + font().getStringWidth(myMsg.text) + fontWidth; - // align bar with bottom of text - const int y = VBORDER + font().desc().ascent - bheight; - - // draw gauge bar - myMsg.surface->fillRect(x - BORDER, y, swidth + BORDER * 2, bheight, kSliderBGColor); - myMsg.surface->fillRect(x, y + BORDER, bwidth, bheight - BORDER * 2, kSliderColor); - // draw tickmark in the middle of the bar - for(int i = 1; i < NUM_TICKMARKS; ++i) + switch(myMsg.position) { - ColorId color; - int xt = x + swidth * i / NUM_TICKMARKS; - if(bwidth < xt - x) - color = kCheckColor; // kSliderColor; - else - color = kSliderBGColor; - myMsg.surface->vLine(xt, y + bheight / 2, y + bheight - 1, color); + case MessagePosition::TopLeft: + myMsg.x = 5; + myMsg.y = 5; + break; + + case MessagePosition::TopCenter: + myMsg.x = (imageRect().w() - dst.w()) >> 1; + myMsg.y = 5; + break; + + case MessagePosition::TopRight: + myMsg.x = imageRect().w() - dst.w() - 5; + myMsg.y = 5; + break; + + case MessagePosition::MiddleLeft: + myMsg.x = 5; + myMsg.y = (imageRect().h() - dst.h()) >> 1; + break; + + case MessagePosition::MiddleCenter: + myMsg.x = (imageRect().w() - dst.w()) >> 1; + myMsg.y = (imageRect().h() - dst.h()) >> 1; + break; + + case MessagePosition::MiddleRight: + myMsg.x = imageRect().w() - dst.w() - 5; + myMsg.y = (imageRect().h() - dst.h()) >> 1; + break; + + case MessagePosition::BottomLeft: + myMsg.x = 5; + myMsg.y = imageRect().h() - dst.h() - 5; + break; + + case MessagePosition::BottomCenter: + myMsg.x = (imageRect().w() - dst.w()) >> 1; + myMsg.y = imageRect().h() - dst.h() - 5; + break; + + case MessagePosition::BottomRight: + myMsg.x = imageRect().w() - dst.w() - 5; + myMsg.y = imageRect().h() - dst.h() - 5; + break; } - // draw value text - myMsg.surface->drawString(font(), myMsg.valueText, - x + swidth + fontWidth, VBORDER, + + myMsg.surface->setDstPos(myMsg.x + imageRect().x(), myMsg.y + imageRect().y()); + myMsg.surface->fillRect(0, 0, myMsg.w, myMsg.h, kColor); + myMsg.surface->fillRect(BORDER, BORDER, myMsg.w - BORDER * 2, myMsg.h - BORDER * 2, kBtnColor); + myMsg.surface->drawString(font(), myMsg.text, HBORDER, VBORDER, myMsg.w, myMsg.color); + + if(myMsg.showGauge) + { + constexpr int NUM_TICKMARKS = 4; + // limit gauge bar width if texts are too long + const int swidth = std::min(fontWidth * GAUGEBAR_WIDTH, + fontWidth * (MESSAGE_WIDTH - 2) + - font().getStringWidth(myMsg.text) + - font().getStringWidth(myMsg.valueText)); + const int bwidth = swidth * myMsg.value / 100.F; + const int bheight = fontHeight >> 1; + const int x = HBORDER + font().getStringWidth(myMsg.text) + fontWidth; + // align bar with bottom of text + const int y = VBORDER + font().desc().ascent - bheight; + + // draw gauge bar + myMsg.surface->fillRect(x - BORDER, y, swidth + BORDER * 2, bheight, kSliderBGColor); + myMsg.surface->fillRect(x, y + BORDER, bwidth, bheight - BORDER * 2, kSliderColor); + // draw tickmark in the middle of the bar + for(int i = 1; i < NUM_TICKMARKS; ++i) + { + ColorId color; + int xt = x + swidth * i / NUM_TICKMARKS; + if(bwidth < xt - x) + color = kCheckColor; // kSliderColor; + else + color = kSliderBGColor; + myMsg.surface->vLine(xt, y + bheight / 2, y + bheight - 1, color); + } + // draw value text + myMsg.surface->drawString(font(), myMsg.valueText, + x + swidth + fontWidth, VBORDER, + myMsg.w, myMsg.color); + } + myMsg.dirty = false; + myMsg.surface->render(); + return true; } - myMsg.surface->render(); + myMsg.counter--; + myMsg.surface->render(); #endif - return true; + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -898,7 +890,6 @@ void FrameBuffer::setUIPalette() void FrameBuffer::stateChanged(EventHandlerState state) { // Make sure any onscreen messages are removed - myMsg.enabled = false; myMsg.counter = 0; update(true); // force full update @@ -1010,7 +1001,7 @@ void FrameBuffer::toggleFullscreen(bool toggle) msg << "disabled ("; msg << "Zoom " << myActiveVidMode.zoom * 100 << "%)"; - showMessage(msg.str()); + showTextMessage(msg.str()); } break; } @@ -1043,7 +1034,7 @@ void FrameBuffer::toggleAdaptRefresh(bool toggle) msg << (isAdaptRefresh ? "enabled" : "disabled"); msg << " (" << myBackend->refreshRate() << " Hz)"; - showMessage(msg.str()); + showTextMessage(msg.str()); } } #endif @@ -1069,7 +1060,7 @@ void FrameBuffer::changeOverscan(int direction) val << (overscan > 0 ? "+" : "" ) << overscan << "%"; else val << "Off"; - myOSystem.frameBuffer().showMessage("Overscan", val.str(), overscan, 0, 10); + myOSystem.frameBuffer().showGaugeMessage("Overscan", val.str(), overscan, 0, 10); } } @@ -1106,9 +1097,9 @@ void FrameBuffer::switchVideoMode(int direction) if(applyVideoMode() == FBInitStatus::Success) { if(fullScreen()) - showMessage(myActiveVidMode.description); + showTextMessage(myActiveVidMode.description); else - showMessage("Zoom", myActiveVidMode.description, myActiveVidMode.zoom, + showGaugeMessage("Zoom", myActiveVidMode.description, myActiveVidMode.zoom, supportedTIAMinZoom(), myTIAMaxZoom); } } @@ -1248,9 +1239,9 @@ void FrameBuffer::toggleGrabMouse() myGrabMouse = !myGrabMouse; setCursorState(); myOSystem.settings().setValue("grabmouse", myGrabMouse); - myOSystem.frameBuffer().showMessage(oldState != myGrabMouse ? myGrabMouse - ? "Grab mouse enabled" : "Grab mouse disabled" - : "Grab mouse not allowed while cursor shown"); + myOSystem.frameBuffer().showTextMessage(oldState != myGrabMouse ? myGrabMouse + ? "Grab mouse enabled" : "Grab mouse disabled" + : "Grab mouse not allowed while cursor shown"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index c084c9cf6..8cda8d25c 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -92,15 +92,15 @@ class FrameBuffer void updateInEmulationMode(float framesPerSecond); /** - Shows a message onscreen. + Shows a text message onscreen. @param message The message to be shown @param position Onscreen position for the message @param force Force showing this message, even if messages are disabled */ - void showMessage(const string& message, - MessagePosition position = MessagePosition::BottomCenter, - bool force = false); + void showTextMessage(const string& message, + MessagePosition position = MessagePosition::BottomCenter, + bool force = false); /** Shows a message with a gauge bar onscreen. @@ -110,8 +110,8 @@ class FrameBuffer @param minValue The minimal value of the gauge bar @param maxValue The maximal value of the gauge bar */ - void showMessage(const string& message, const string& valueText, - float value, float minValue = 0.F, float maxValue = 100.F); + void showGaugeMessage(const string& message, const string& valueText, + float value, float minValue = 0.F, float maxValue = 100.F); bool messageShown() const; @@ -375,6 +375,18 @@ class FrameBuffer */ void resetSurfaces(); + #ifdef GUI_SUPPORT + /** + Helps to create a basic message onscreen. + + @param message The message to be shown + @param position Onscreen position for the message + @param force Force showing this message, even if messages are disabled + */ + void createMessage(const string& message, MessagePosition position, + bool force = false); + #endif + /** Draw pending messages. @@ -478,6 +490,7 @@ class FrameBuffer ColorId color{kNone}; shared_ptr surface; bool enabled{false}; + bool dirty{false}; bool showGauge{false}; float value{0.0F}; string valueText; diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 611439e45..e659c1e5c 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -475,9 +475,9 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, { const string& id = myConsole->cartridge().multiCartID(); if(id == "") - myFrameBuffer->showMessage("New console created"); + myFrameBuffer->showTextMessage("New console created"); else - myFrameBuffer->showMessage("Multicart " + + myFrameBuffer->showTextMessage("Multicart " + myConsole->cartridge().detectedType() + ", loading ROM" + id); } buf << "Game console created:" << endl @@ -506,7 +506,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum, msg << myConsole->leftController().name() << "/" << myConsole->rightController().name() << " - " << myConsole->cartridge().detectedType() << " - " << myConsole->getFormatString(); - myFrameBuffer->showMessage(msg.str()); + myFrameBuffer->showTextMessage(msg.str()); } } diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx index 64c0cf027..f3fb00cdf 100644 --- a/src/emucore/QuadTari.cxx +++ b/src/emucore/QuadTari.cxx @@ -71,7 +71,7 @@ unique_ptr QuadTari::addController(const Controller::Type type, bool Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { bool devSettings = os.settings().getBool("dev.settings"); if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); + os.frameBuffer().showTextMessage(msg); }; switch(type) diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx index 3858817a7..ec9dfe020 100644 --- a/src/emucore/TIASurface.cxx +++ b/src/emucore/TIASurface.cxx @@ -184,7 +184,7 @@ void TIASurface::setNTSC(NTSCFilter::Preset preset, bool show) } myOSystem.settings().setValue("tv.filter", int(preset)); - if(show) myFB.showMessage(buf.str()); + if(show) myFB.showTextMessage(buf.str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -221,7 +221,7 @@ void TIASurface::setNTSCAdjustable(int direction) setNTSC(NTSCFilter::Preset::CUSTOM); ntsc().selectAdjustable(direction, text, valueText, value); - myOSystem.frameBuffer().showMessage(text, valueText, value); + myOSystem.frameBuffer().showGaugeMessage(text, valueText, value); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -232,7 +232,7 @@ void TIASurface::changeNTSCAdjustable(int adjustable, int direction) setNTSC(NTSCFilter::Preset::CUSTOM); ntsc().changeAdjustable(adjustable, direction, text, valueText, newValue); - myOSystem.frameBuffer().showMessage(text, valueText, newValue); + myOSystem.frameBuffer().showGaugeMessage(text, valueText, newValue); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -243,7 +243,7 @@ void TIASurface::changeCurrentNTSCAdjustable(int direction) setNTSC(NTSCFilter::Preset::CUSTOM); ntsc().changeCurrentAdjustable(direction, text, valueText, newValue); - myOSystem.frameBuffer().showMessage(text, valueText, newValue); + myOSystem.frameBuffer().showGaugeMessage(text, valueText, newValue); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -259,7 +259,7 @@ void TIASurface::setScanlineIntensity(int direction) buf << intensity << "%"; else buf << "Off"; - myFB.showMessage("Scanline intensity", buf.str(), intensity); + myFB.showGaugeMessage("Scanline intensity", buf.str(), intensity); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 9649e447c..d4f4c165b 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -127,8 +127,8 @@ int DialogContainer::addDialog(Dialog* d) const uInt32 scale = myOSystem.frameBuffer().hidpiScaleFactor(); if(uInt32(d->getWidth() * scale) > r.w() || uInt32(d->getHeight() * scale) > r.h()) - myOSystem.frameBuffer().showMessage( - "Unable to show dialog box; FIX THE CODE"); + myOSystem.frameBuffer().showTextMessage( + "Unable to show dialog box; FIX THE CODE", MessagePosition::BottomCenter, true); else { // "darken" current top dialog diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 5a3c4b1b5..57ad900d2 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -855,12 +855,12 @@ void GameInfoDialog::saveCurrentPropertiesToDisk() propfile /= myGameFile.getNameWithExt(".pro"); propfile.write(out); - instance().frameBuffer().showMessage("Properties saved to " + - propfile.getShortPath()); + instance().frameBuffer().showTextMessage("Properties saved to " + + propfile.getShortPath()); } catch(...) { - instance().frameBuffer().showMessage("Error saving properties"); + instance().frameBuffer().showTextMessage("Error saving properties"); } } diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 3f6ddcec8..8018bcb44 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -662,7 +662,7 @@ void LauncherDialog::loadRom() instance().settings().setValue("romdir", currentNode().getParent().getShortPath()); } else - instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true); + instance().frameBuffer().showTextMessage(result, MessagePosition::MiddleCenter, true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/LoggerDialog.cxx b/src/gui/LoggerDialog.cxx index bf53d80a0..3f94e093e 100644 --- a/src/gui/LoggerDialog.cxx +++ b/src/gui/LoggerDialog.cxx @@ -123,12 +123,12 @@ void LoggerDialog::saveLogFile() { stringstream out; out << Logger::instance().logMessages(); - instance().frameBuffer().showMessage("Saving log file to " + node.getShortPath()); + instance().frameBuffer().showTextMessage("Saving log file to " + node.getShortPath()); node.write(out); } catch(...) { - instance().frameBuffer().showMessage("Error saving log file to " + node.getShortPath()); + instance().frameBuffer().showTextMessage("Error saving log file to " + node.getShortPath()); } } diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx index e822504a9..1e983eb92 100644 --- a/src/gui/TimeMachineDialog.cxx +++ b/src/gui/TimeMachineDialog.cxx @@ -440,11 +440,11 @@ void TimeMachineDialog::handleCommand(CommandSender* sender, int cmd, break; case kSaveAll: - instance().frameBuffer().showMessage(instance().state().rewindManager().saveAllStates()); + instance().frameBuffer().showTextMessage(instance().state().rewindManager().saveAllStates()); break; case kLoadAll: - instance().frameBuffer().showMessage(instance().state().rewindManager().loadAllStates()); + instance().frameBuffer().showTextMessage(instance().state().rewindManager().loadAllStates()); initBar(); break; From e5f1e47f5df549de81301bd63b1fddc0a658f190 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 11:50:26 +0100 Subject: [PATCH 171/263] further minimized UI redraws when message is displayed --- src/emucore/FrameBuffer.cxx | 53 ++++++++++++++++++------------------- src/gui/DialogContainer.cxx | 19 +++++++++++-- src/gui/DialogContainer.hxx | 5 ++++ 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 66747b2a3..3af48cd15 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -322,10 +322,11 @@ void FrameBuffer::update(bool force) // - at the bottom of ::update(), to actually draw them (this must come // last, since they are always drawn on top of everything else). - // Forced full rendering is required when messages are being disabled - force |= (myMsg.enabled && myMsg.counter == 0); + // Forced rendering without drawing is required when messages are being disabled + // Only relevant for LAUNCHER, PAUSE and DEBUGGER modes + bool rerender = force || (myMsg.enabled && myMsg.counter == 0); - bool redraw = false; + bool redraw = force; switch(myOSystem.eventHandler().state()) { case EventHandlerState::NONE: @@ -341,7 +342,7 @@ void FrameBuffer::update(bool force) myPausedCount = uInt32(7 * myOSystem.frameRate()); showTextMessage("Paused", MessagePosition::MiddleCenter); } - if(force) + if(rerender) myTIASurface->render(); break; // EventHandlerState::PAUSE @@ -350,8 +351,8 @@ void FrameBuffer::update(bool force) #ifdef GUI_SUPPORT case EventHandlerState::OPTIONSMENU: { - redraw = myOSystem.menu().needsRedraw(); - if(force || redraw) + redraw |= myOSystem.menu().needsRedraw(); + if(redraw) { clear(); myTIASurface->render(); @@ -362,8 +363,8 @@ void FrameBuffer::update(bool force) case EventHandlerState::CMDMENU: { - redraw = myOSystem.commandMenu().needsRedraw(); - if(force || redraw) + redraw |= myOSystem.commandMenu().needsRedraw(); + if(redraw) { clear(); myTIASurface->render(); @@ -374,8 +375,8 @@ void FrameBuffer::update(bool force) case EventHandlerState::MESSAGEMENU: { - redraw = myOSystem.messageMenu().needsRedraw(); - if(force || redraw) + redraw |= myOSystem.messageMenu().needsRedraw(); + if(redraw) { clear(); myTIASurface->render(); @@ -386,8 +387,8 @@ void FrameBuffer::update(bool force) case EventHandlerState::TIMEMACHINE: { - redraw = myOSystem.timeMachine().needsRedraw(); - if(force || redraw) + redraw |= myOSystem.timeMachine().needsRedraw(); + if(redraw) { clear(); myTIASurface->render(); @@ -416,8 +417,8 @@ void FrameBuffer::update(bool force) r.rewindStates(1); } - force = force || success; - if(force) + redraw |= success; + if(redraw) myTIASurface->render(); // Stop playback mode at the end of the state buffer @@ -432,11 +433,11 @@ void FrameBuffer::update(bool force) case EventHandlerState::LAUNCHER: { - redraw = myOSystem.launcher().needsRedraw(); - if(force || redraw) - { + redraw |= myOSystem.launcher().needsRedraw(); + if(redraw) myOSystem.launcher().draw(force); - } + else if(rerender) + myOSystem.launcher().render(); break; // EventHandlerState::LAUNCHER } #endif @@ -444,12 +445,11 @@ void FrameBuffer::update(bool force) #ifdef DEBUGGER_SUPPORT case EventHandlerState::DEBUGGER: { - redraw = myOSystem.debugger().needsRedraw(); - if(force || redraw) - { - + redraw |= myOSystem.debugger().needsRedraw(); + if(redraw) myOSystem.debugger().draw(force); - } + else if(rerender) + myOSystem.debugger().render(); break; // EventHandlerState::DEBUGGER } #endif @@ -466,7 +466,7 @@ void FrameBuffer::update(bool force) redraw |= drawMessage(); // Push buffers to screen only when necessary - if(force || redraw) + if(redraw || rerender) myBackend->renderToScreen(); } @@ -518,7 +518,6 @@ void FrameBuffer::createMessage(const string& message, MessagePosition position, myMsg.enabled = true; myMsg.dirty = true; - myMsg.surface->setSrcSize(myMsg.w, myMsg.h); myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor()); } @@ -666,7 +665,7 @@ void FrameBuffer::enableMessages(bool enable) // Erase old messages on the screen myMsg.counter = 0; - update(true); // Force update immediately + update(); // update immediately } } @@ -892,7 +891,7 @@ void FrameBuffer::stateChanged(EventHandlerState state) // Make sure any onscreen messages are removed myMsg.counter = 0; - update(true); // force full update + update(); // update immediately } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index d4f4c165b..77e163e83 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -91,21 +91,36 @@ void DialogContainer::updateTime(uInt64 time) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DialogContainer::draw(bool full) { - cerr << "draw " << full << " " << typeid(*this).name() << endl; if(myDialogStack.empty()) return; + cerr << "draw " << full << " " << typeid(*this).name() << endl; + // Make the top dialog dirty if a full redraw is requested if(full) myDialogStack.top()->setDirty(); - // Render all dirty dialogs + // Draw and render all dirty dialogs myDialogStack.applyAll([&](Dialog*& d) { if(d->needsRedraw()) d->redraw(); }); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void DialogContainer::render() +{ + if(myDialogStack.empty()) + return; + + cerr << "render " << typeid(*this).name() << endl; + + // Render all dirty dialogs + myDialogStack.applyAll([&](Dialog*& d) { + d->render(); + }); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool DialogContainer::needsRedraw() const { diff --git a/src/gui/DialogContainer.hxx b/src/gui/DialogContainer.hxx index 1f6cce8f6..70950606d 100644 --- a/src/gui/DialogContainer.hxx +++ b/src/gui/DialogContainer.hxx @@ -124,6 +124,11 @@ class DialogContainer */ void draw(bool full = false); + /** + Render the stack of menus. + */ + void render(); + /** Answers whether a full redraw is required. */ From 9819118b5934cab775c4da0414bd99c1386597e4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 14:04:29 +0100 Subject: [PATCH 172/263] replaced shaded UI redraws with shading surface --- src/gui/Dialog.cxx | 26 +++++++++++++++++++++++--- src/gui/Dialog.hxx | 1 + src/gui/DialogContainer.cxx | 13 ++++++++----- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 9cb5accb2..6f8867cfb 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -227,8 +227,6 @@ void Dialog::redraw() center(); drawDialog(); render(); - -// return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -242,6 +240,28 @@ void Dialog::render() surface->render(); }); } + if(parent().myDialogStack.top() != this) + { + if(_shadeSurface == nullptr) + { + uInt32 data = 0xff000000; + + _shadeSurface = instance().frameBuffer().allocateSurface( + 1, 1, ScalingInterpolation::sharp, &data); + + FBSurface::Attributes& attr = _shadeSurface->attributes(); + + attr.blending = true; + attr.blendalpha = 25; // darken background dialogs by 25% + _shadeSurface->applyAttributes(); + } + + const Common::Rect& rect = _surface->dstRect(); + _shadeSurface->setDstPos(rect.x(), rect.y()); + _shadeSurface->setDstSize(rect.w(), rect.h()); + + _shadeSurface->render(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -408,7 +428,7 @@ void Dialog::drawDialog() //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; // Dialog is still on top if e.g a ContextMenu is opened - _onTop = parent().myDialogStack.top() == this + _onTop = true/*parent().myDialogStack.top() == this*/ || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this && !parent().myDialogStack.top()->hasTitle()); diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index b9a924b55..d5405ef70 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -230,6 +230,7 @@ class Dialog : public GuiObject WidgetArray _buttonGroup; shared_ptr _surface; + shared_ptr _shadeSurface; int _tabID{0}; uInt32 _max_w{0}; // maximum wanted width diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 77e163e83..98deae834 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -146,9 +146,10 @@ int DialogContainer::addDialog(Dialog* d) "Unable to show dialog box; FIX THE CODE", MessagePosition::BottomCenter, true); else { - // "darken" current top dialog - if(!myDialogStack.empty()) - myDialogStack.top()->setDirty(); + //// "shade" current top dialog + //if(!myDialogStack.empty()) + // myDialogStack.top()->setDirty(); + d->setDirty(); myDialogStack.push(d); } @@ -164,14 +165,16 @@ void DialogContainer::removeDialog() if(!myDialogStack.empty()) { - // this "undarkens" the top dialog - myDialogStack.top()->setDirty(); + //// this "unshades" the top dialog + //myDialogStack.top()->setDirty(); // Rerender all dialogs (TODO: top dialog is rendered twice) myDialogStack.applyAll([&](Dialog*& d){ //d->setDirty(); d->render(); }); + // TODO: the screen is not updated until an event happens + // FrameBuffer::myBackend->renderToScreen() doesn't help } } } From 907fc4edf3d743213b0f101ba023a2903de5771d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 14:37:50 +0100 Subject: [PATCH 173/263] minimized ContextMenu redraws fixed shading caused by ContextMenu --- src/gui/ContextMenu.cxx | 8 ++++++-- src/gui/Dialog.cxx | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index 9cf626657..a53f1c4ae 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -346,8 +346,12 @@ int ContextMenu::findItem(int x, int y) const void ContextMenu::drawCurrentSelection(int item) { // Change selection - _selectedOffset = item; - setDirty(); + if(_selectedOffset != item) + { + _selectedOffset = item; + cerr << "ContextMenu" << endl; + setDirty(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 6f8867cfb..fe0d06d37 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -240,7 +240,15 @@ void Dialog::render() surface->render(); }); } - if(parent().myDialogStack.top() != this) + + //cerr << "is ContextMenu " + // << (typeid(*parent().myDialogStack.top()) == typeid(ContextMenu)) << endl; + + // Dialog is still on top if e.g a ContextMenu is opened + if(!(parent().myDialogStack.top() == this) + && !((parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this + //&& !(typeid(*parent().myDialogStack.top()) == typeid(ContextMenu))) + && !parent().myDialogStack.top()->hasTitle()))) { if(_shadeSurface == nullptr) { @@ -432,6 +440,7 @@ void Dialog::drawDialog() || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this && !parent().myDialogStack.top()->hasTitle()); + cerr << "on top " << isOnTop() << endl; if(clearsBackground()) { // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; From 42817a61171194c480ba7216e6a18cbbbf8a501d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 15:41:40 +0100 Subject: [PATCH 174/263] Allow first click detection when Stella lost focus. --- src/common/EventHandlerSDL2.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index e5900cfba..39b3469f5 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -45,6 +45,8 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem) } Logger::debug("EventHandlerSDL2::EventHandlerSDL2 SDL_INIT_JOYSTICK"); #endif + + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -91,6 +93,7 @@ void EventHandlerSDL2::pollEvent() while(SDL_PollEvent(&myEvent)) { + cerr << myEvent.type << endl; switch(myEvent.type) { // keyboard events @@ -198,6 +201,7 @@ void EventHandlerSDL2::pollEvent() } case SDL_WINDOWEVENT: + cerr << myEvent.window.event << endl; switch(myEvent.window.event) { case SDL_WINDOWEVENT_SHOWN: From f0d6b672eaf1a4c63c7c32dba09ac1420f0c3d0c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 15:48:00 +0100 Subject: [PATCH 175/263] removed debug code --- src/common/EventHandlerSDL2.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index 39b3469f5..86d4dad89 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -93,7 +93,6 @@ void EventHandlerSDL2::pollEvent() while(SDL_PollEvent(&myEvent)) { - cerr << myEvent.type << endl; switch(myEvent.type) { // keyboard events @@ -201,7 +200,6 @@ void EventHandlerSDL2::pollEvent() } case SDL_WINDOWEVENT: - cerr << myEvent.window.event << endl; switch(myEvent.window.event) { case SDL_WINDOWEVENT_SHOWN: From c390b40a6d6cb2670dc4425969ac0e2418efd1a4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 18:14:26 +0100 Subject: [PATCH 176/263] refactored UI ticks --- src/debugger/gui/DebuggerDialog.hxx | 2 +- src/debugger/gui/RomListSettings.cxx | 2 +- src/debugger/gui/RomListSettings.hxx | 4 +-- src/emucore/FrameBuffer.cxx | 6 ++++ src/gui/ContextMenu.cxx | 2 +- src/gui/ContextMenu.hxx | 4 +-- src/gui/Dialog.cxx | 35 +++++++++++----------- src/gui/Dialog.hxx | 7 ++--- src/gui/DialogContainer.cxx | 7 +++++ src/gui/DialogContainer.hxx | 5 ++++ src/gui/EditableWidget.cxx | 6 ++-- src/gui/EditableWidget.hxx | 2 +- src/gui/GuiObject.hxx | 10 +++++-- src/gui/InputTextDialog.cxx | 4 +-- src/gui/InputTextDialog.hxx | 2 +- src/gui/LauncherDialog.hxx | 2 +- src/gui/TimeMachineDialog.cxx | 2 +- src/gui/TimeMachineDialog.hxx | 4 +-- src/gui/Widget.cxx | 44 ++++++++++------------------ src/gui/Widget.hxx | 3 +- 20 files changed, 80 insertions(+), 73 deletions(-) diff --git a/src/debugger/gui/DebuggerDialog.hxx b/src/debugger/gui/DebuggerDialog.hxx index 0affa5160..51633c825 100644 --- a/src/debugger/gui/DebuggerDialog.hxx +++ b/src/debugger/gui/DebuggerDialog.hxx @@ -76,7 +76,7 @@ class DebuggerDialog : public Dialog void saveConfig() override; private: - void center() override { positionAt(0); } + void setPosition() override { positionAt(0); } void loadConfig() override; void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/debugger/gui/RomListSettings.cxx b/src/debugger/gui/RomListSettings.cxx index 9c3baf3d2..93b555631 100644 --- a/src/debugger/gui/RomListSettings.cxx +++ b/src/debugger/gui/RomListSettings.cxx @@ -100,7 +100,7 @@ void RomListSettings::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomListSettings::center() +void RomListSettings::setPosition() { // First set position according to original coordinates surface().setDstPos(_xorig, _yorig); diff --git a/src/debugger/gui/RomListSettings.hxx b/src/debugger/gui/RomListSettings.hxx index 0845dd8ab..a589b0334 100644 --- a/src/debugger/gui/RomListSettings.hxx +++ b/src/debugger/gui/RomListSettings.hxx @@ -38,8 +38,8 @@ class RomListSettings : public Dialog, public CommandSender ('data' will be the currently selected line number in RomListWidget) */ void show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int data = -1); - /** This dialog uses its own positioning, so we override Dialog::center() */ - void center() override; + /** This dialog uses its own positioning, so we override Dialog::setPosition() */ + void setPosition() override; private: uInt32 _xorig{0}, _yorig{0}; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 3af48cd15..a151084d1 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -351,6 +351,7 @@ void FrameBuffer::update(bool force) #ifdef GUI_SUPPORT case EventHandlerState::OPTIONSMENU: { + myOSystem.menu().tick(); redraw |= myOSystem.menu().needsRedraw(); if(redraw) { @@ -363,6 +364,7 @@ void FrameBuffer::update(bool force) case EventHandlerState::CMDMENU: { + myOSystem.commandMenu().tick(); redraw |= myOSystem.commandMenu().needsRedraw(); if(redraw) { @@ -375,6 +377,7 @@ void FrameBuffer::update(bool force) case EventHandlerState::MESSAGEMENU: { + myOSystem.messageMenu().tick(); redraw |= myOSystem.messageMenu().needsRedraw(); if(redraw) { @@ -387,6 +390,7 @@ void FrameBuffer::update(bool force) case EventHandlerState::TIMEMACHINE: { + myOSystem.timeMachine().tick(); redraw |= myOSystem.timeMachine().needsRedraw(); if(redraw) { @@ -433,6 +437,7 @@ void FrameBuffer::update(bool force) case EventHandlerState::LAUNCHER: { + myOSystem.launcher().tick(); redraw |= myOSystem.launcher().needsRedraw(); if(redraw) myOSystem.launcher().draw(force); @@ -445,6 +450,7 @@ void FrameBuffer::update(bool force) #ifdef DEBUGGER_SUPPORT case EventHandlerState::DEBUGGER: { + myOSystem.debugger().tick(); redraw |= myOSystem.debugger().needsRedraw(); if(redraw) myOSystem.debugger().draw(force); diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index a53f1c4ae..ae1ee09be 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -77,7 +77,7 @@ void ContextMenu::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int ite } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ContextMenu::center() +void ContextMenu::setPosition() { // First set position according to original coordinates surface().setDstPos(_xorig, _yorig); diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index 423ef3074..f1736e517 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -71,8 +71,8 @@ class ContextMenu : public Dialog, public CommandSender const string& getSelectedName() const; const Variant& getSelectedTag() const; - /** This dialog uses its own positioning, so we override Dialog::center() */ - void center() override; + /** This dialog uses its own positioning, so we override Dialog::setPosition() */ + void setPosition() override; /** The following methods are used when we want to select *and* send a command for the new selection. They are only to be used diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index fe0d06d37..e58920e89 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -91,7 +91,7 @@ void Dialog::open() const uInt32 scale = instance().frameBuffer().hidpiScaleFactor(); _surface->setDstSize(_w * scale, _h * scale); - center(); + setPosition(); if(_myTabList.size()) // (Re)-build the focus list to use for all widgets of all tabs @@ -143,32 +143,20 @@ void Dialog::setTitle(const string& title) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Dialog::center() +void Dialog::setPosition() { positionAt(instance().settings().getInt("dialogpos")); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Dialog::setDirty() -{ - _dirty = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Dialog::isDirty() -{ - return _dirty; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Dialog::isChainDirty() const { bool dirty = false; - // Check if widget or any subwidgets are dirty + // Recursively check if dialog or any chick dialogs or widgets are dirty Widget* w = _firstWidget; - while(!dirty && w) + while(w && !dirty) { dirty |= w->needsRedraw(); w = w->_next; @@ -177,6 +165,19 @@ bool Dialog::isChainDirty() const return dirty; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::tick() +{ + // Recursively tick dialog and all child dialogs and widgets + Widget* w = _firstWidget; + + while(w) + { + w->tick(); + w = w->_next; + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::positionAt(uInt32 pos) { @@ -224,7 +225,7 @@ void Dialog::redraw() return;// false; // Draw this dialog - center(); + setPosition(); drawDialog(); render(); } diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index d5405ef70..c594d93cd 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -56,16 +56,13 @@ class Dialog : public GuiObject bool isVisible() const override { return _visible; } bool isOnTop() const { return _onTop; } - virtual void center(); + virtual void setPosition(); virtual void drawDialog(); virtual void loadConfig() { } virtual void saveConfig() { } virtual void setDefaults() { } - // A dialog being dirty indicates that its underlying surface needs to be - // redrawn and then re-rendered; this is taken care of in ::render() - void setDirty() override; - bool isDirty() override; // TODO: remove + void tick() override; bool isChainDirty() const override; void redraw(); void render(); diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 98deae834..1210e5d7c 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -107,6 +107,13 @@ void DialogContainer::draw(bool full) }); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void DialogContainer::tick() +{ + if(!myDialogStack.empty()) + myDialogStack.top()->tick(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DialogContainer::render() { diff --git a/src/gui/DialogContainer.hxx b/src/gui/DialogContainer.hxx index 70950606d..134d82e55 100644 --- a/src/gui/DialogContainer.hxx +++ b/src/gui/DialogContainer.hxx @@ -119,6 +119,11 @@ class DialogContainer */ void handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int button); + /** + Tick the dialog and all its widgets. + */ + void tick(); + /** Draw the stack of menus (full indicates to redraw all items). */ diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 4032daae3..4c3928052 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -62,8 +62,9 @@ void EditableWidget::setText(const string& str, bool) setDirty(); } + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EditableWidget::isDirty() +void EditableWidget::tick() { if(_hasFocus && _editable && isVisible() && _boss->isVisible()) { @@ -75,8 +76,7 @@ bool EditableWidget::isDirty() _dirty = true; } } - - return _dirty; + Widget::tick(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index e4dfbc2f7..345a4c618 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -67,7 +67,7 @@ class EditableWidget : public Widget, public CommandSender protected: void receivedFocusWidget() override; void lostFocusWidget() override; - bool isDirty() override; + void tick() override; virtual void startEditMode() { setFlags(Widget::FLAG_WANTS_RAWDATA); } virtual void endEditMode() { clearFlags(Widget::FLAG_WANTS_RAWDATA); } diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index 811f1569b..581d498aa 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -91,11 +91,15 @@ class GuiObject : public CommandReceiver virtual void setHeight(int h) { _h = h; } virtual bool isVisible() const = 0; - virtual void setDirty() = 0; + virtual void setDirty() { _dirty = true; } virtual void clearDirty() { _dirty = false; } - virtual bool isDirty() { return _dirty; } + + virtual void tick() = 0; + virtual bool isDirty() const { return _dirty; } virtual bool isChainDirty() const = 0; - virtual bool needsRedraw() { return isDirty() || isChainDirty(); }; + // The GUI indicates if its underlying surface needs to be redrawn + // and then re-rendered + virtual bool needsRedraw() { return isDirty() || isChainDirty(); } void setFlags(uInt32 flags) { diff --git a/src/gui/InputTextDialog.cxx b/src/gui/InputTextDialog.cxx index 12e7a66d4..54b656a67 100644 --- a/src/gui/InputTextDialog.cxx +++ b/src/gui/InputTextDialog.cxx @@ -130,7 +130,7 @@ void InputTextDialog::show(uInt32 x, uInt32 y, const Common::Rect& bossRect) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void InputTextDialog::center() +void InputTextDialog::setPosition() { if(!myEnableCenter) { @@ -144,7 +144,7 @@ void InputTextDialog::center() surface().setDstPos(myXOrig, myYOrig); } else - Dialog::center(); + Dialog::setPosition(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/InputTextDialog.hxx b/src/gui/InputTextDialog.hxx index e89e00651..a06ca4446 100644 --- a/src/gui/InputTextDialog.hxx +++ b/src/gui/InputTextDialog.hxx @@ -58,7 +58,7 @@ class InputTextDialog : public Dialog, public CommandSender void handleCommand(CommandSender* sender, int cmd, int data, int id) override; /** This dialog uses its own positioning, so we override Dialog::center() */ - void center() override; + void setPosition() override; private: vector myInput; diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index 0dd9b898d..cc265928b 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -101,7 +101,7 @@ class LauncherDialog : public Dialog static constexpr int MIN_ROMINFO_ROWS = 7; // full lines static constexpr int MIN_ROMINFO_LINES = 4; // extra lines - void center() override { positionAt(0); } + void setPosition() override { positionAt(0); } void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx index 1e983eb92..8e550d2a9 100644 --- a/src/gui/TimeMachineDialog.cxx +++ b/src/gui/TimeMachineDialog.cxx @@ -297,7 +297,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void TimeMachineDialog::center() +void TimeMachineDialog::setPosition() { // Place on the bottom of the screen, centered horizontally const Common::Size& screen = instance().frameBuffer().screenSize(); diff --git a/src/gui/TimeMachineDialog.hxx b/src/gui/TimeMachineDialog.hxx index a4a489b79..1d15d6b15 100644 --- a/src/gui/TimeMachineDialog.hxx +++ b/src/gui/TimeMachineDialog.hxx @@ -44,8 +44,8 @@ class TimeMachineDialog : public Dialog /** initialize timeline bar */ void initBar(); - /** This dialog uses its own positioning, so we override Dialog::center() */ - void center() override; + /** This dialog uses its own positioning, so we override Dialog::setPosition() */ + void setPosition() override; /** convert cycles into time */ string getTimeString(uInt64 cycles); diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 69c94b3ed..951a60282 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -51,48 +51,36 @@ Widget::~Widget() _focusList.clear(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Widget::setDirty() -{ - // A widget being dirty indicates that its parent dialog is dirty - // So we inform the parent about it - //_boss->dialog().setDirty(); - //cerr << "set dirty " << typeid(*this).name() << endl; - - _dirty = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Widget::isDirty() -{ - //string name = typeid(*this).name(); - //if(_dirty && name == "class TabWidget") - // cerr << "is dirty " << typeid(*this).name() << endl; - - return _dirty; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Widget::isChainDirty() const { - string name = typeid(*this).name(); - if(_dirty && name == "class TabWidget") - cerr << "is chain dirty " << typeid(*this).name() << endl; - bool dirty = false; - // Check if widget or any subwidgets are dirty + // Recursively check if widget or any child dialogs or widgets are dirty Widget* w = _firstWidget; - while(!dirty && w) + while(w && !dirty) { - dirty |= w->isDirty(); + dirty |= w->needsRedraw(); w = w->_next; } return dirty; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::tick() +{ + // Recursively tick widget and all child dialogs and widgets + Widget* w = _firstWidget; + + while(w) + { + w->tick(); + w = w->_next; + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Widget::draw() { diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 3e70523c0..6a505e8df 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -69,8 +69,7 @@ class Widget : public GuiObject virtual bool handleJoyHat(int stick, int hat, JoyHatDir hdir, int button = JOY_CTRL_NONE) { return false; } virtual bool handleEvent(Event::Type event) { return false; } - void setDirty() override; - bool isDirty() override; // TODO: remove + void tick() override; bool isChainDirty() const override; void draw() override; void receivedFocus(); From 1a5a0b5286cfd67a403a9ccbd16d2e7fa85f77fd Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 12 Nov 2020 19:46:28 +0100 Subject: [PATCH 177/263] fixed AboutDialog widget overlapping --- src/gui/AboutDialog.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/AboutDialog.cxx b/src/gui/AboutDialog.cxx index db088d923..426adbeeb 100644 --- a/src/gui/AboutDialog.cxx +++ b/src/gui/AboutDialog.cxx @@ -67,11 +67,12 @@ AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent, addCancelWidget(b); xpos = HBORDER; ypos = _th + VBORDER + (buttonHeight - fontHeight) / 2; - myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - xpos * 2, fontHeight, - "", TextAlign::Center); + int bwidth = font.getStringWidth("What's New" + ELLIPSIS) + fontWidth * 2.5; + + myTitle = new StaticTextWidget(this, font, xpos + bwidth, ypos, _w - (xpos + bwidth) * 2, + fontHeight, "", TextAlign::Center); myTitle->setTextColor(kTextColorEm); - int bwidth = font.getStringWidth("What's New" + ELLIPSIS) + fontWidth * 2.5; myWhatsNewButton = new ButtonWidget(this, font, _w - HBORDER - bwidth, ypos - (buttonHeight - fontHeight) / 2, bwidth, buttonHeight, "What's New" + ELLIPSIS, kWhatsNew); From ebd88377296ea101afa6bc7a6f6d8d1b0258efe5 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 12 Nov 2020 18:04:56 -0330 Subject: [PATCH 178/263] Fix compile warning. --- src/emucore/FBSurface.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index d72ffdd64..ea851e6e6 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -323,7 +323,7 @@ class FBSurface This method should be called to reset the surface to empty pixels / colour black. */ - virtual void invalidate() {}; + virtual void invalidate() {} /** This method should be called to reset a surface area to empty From c787e940f2fa57df69665b66d8d6542322cb4dbf Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 08:58:19 +0100 Subject: [PATCH 179/263] fixed rendering, all dialogs are always re-rendered --- src/emucore/FrameBuffer.hxx | 7 +++++- src/gui/Dialog.cxx | 22 ++++++++-------- src/gui/Dialog.hxx | 5 ++++ src/gui/DialogContainer.cxx | 26 ++++++++----------- src/gui/ToolTip.cxx | 40 ++++++++++++++++++++++++++++++ src/gui/ToolTip.hxx | 39 +++++++++++++++++++++++++++++ src/gui/Widget.cxx | 21 +++++++++++----- src/gui/Widget.hxx | 4 +++ src/windows/Stella.vcxproj | 2 ++ src/windows/Stella.vcxproj.filters | 6 +++++ 10 files changed, 139 insertions(+), 33 deletions(-) create mode 100644 src/gui/ToolTip.cxx create mode 100644 src/gui/ToolTip.hxx diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 8cda8d25c..9d6f3e930 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -88,9 +88,14 @@ class FrameBuffer /** There is a dedicated update method for emulation mode. - */ + */ void updateInEmulationMode(float framesPerSecond); + /** + Render backend to screen. + */ + void renderToScreen() { myBackend->renderToScreen(); } + /** Shows a text message onscreen. diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index e58920e89..b483d6e96 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -110,8 +110,6 @@ void Dialog::open() loadConfig(); // has to be done AFTER (re)building the focus list _visible = true; - - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -227,12 +225,14 @@ void Dialog::redraw() // Draw this dialog setPosition(); drawDialog(); - render(); + // full rendering is caused in dialog container } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::render() { + cerr << " render " << typeid(*this).name() << endl; + // Update dialog surface; also render any extra surfaces // Extra surfaces must be rendered afterwards, so they are drawn on top if(_surface->render()) @@ -242,15 +242,17 @@ void Dialog::render() }); } - //cerr << "is ContextMenu " - // << (typeid(*parent().myDialogStack.top()) == typeid(ContextMenu)) << endl; + // Dialog is still on top if e.g a dialog without title is opened + // (e.g. ContextMenu) + bool onTop = parent().myDialogStack.top() == this + || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this + && !parent().myDialogStack.top()->hasTitle()); + //&& typeid(*parent().myDialogStack.top()) == typeid(ContextMenu)) - // Dialog is still on top if e.g a ContextMenu is opened - if(!(parent().myDialogStack.top() == this) - && !((parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this - //&& !(typeid(*parent().myDialogStack.top()) == typeid(ContextMenu))) - && !parent().myDialogStack.top()->hasTitle()))) + if(!onTop) { + cerr << " shade " << typeid(*this).name() << endl; + if(_shadeSurface == nullptr) { uInt32 data = 0xff000000; diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index c594d93cd..4fc48b7fc 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -119,6 +119,10 @@ class Dialog : public GuiObject */ bool shouldResize(uInt32& w, uInt32& h) const; + //bool enableToolTip(); + //void showToolTip(int x, int y); + //void hideToolTip(); + protected: void draw() override { } void releaseFocus() override; @@ -197,6 +201,7 @@ class Dialog : public GuiObject string _title; int _th{0}; int _layer{0}; + int _toolTipTimer{0}; Common::FixedStack> mySurfaceStack; diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 1210e5d7c..50db35d3f 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -97,14 +97,16 @@ void DialogContainer::draw(bool full) cerr << "draw " << full << " " << typeid(*this).name() << endl; // Make the top dialog dirty if a full redraw is requested - if(full) - myDialogStack.top()->setDirty(); + //if(full) + // myDialogStack.top()->setDirty(); // Draw and render all dirty dialogs myDialogStack.applyAll([&](Dialog*& d) { if(d->needsRedraw()) d->redraw(); }); + // Always render all surfaces, bottom to top + render(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -120,9 +122,9 @@ void DialogContainer::render() if(myDialogStack.empty()) return; - cerr << "render " << typeid(*this).name() << endl; + cerr << "full re-render " << typeid(*this).name() << endl; - // Render all dirty dialogs + // Render all dialogs myDialogStack.applyAll([&](Dialog*& d) { d->render(); }); @@ -153,10 +155,6 @@ int DialogContainer::addDialog(Dialog* d) "Unable to show dialog box; FIX THE CODE", MessagePosition::BottomCenter, true); else { - //// "shade" current top dialog - //if(!myDialogStack.empty()) - // myDialogStack.top()->setDirty(); - d->setDirty(); myDialogStack.push(d); } @@ -168,20 +166,16 @@ void DialogContainer::removeDialog() { if(!myDialogStack.empty()) { + cerr << "remove dialog" << endl; myDialogStack.pop(); if(!myDialogStack.empty()) { - //// this "unshades" the top dialog - //myDialogStack.top()->setDirty(); - - // Rerender all dialogs (TODO: top dialog is rendered twice) + // Rerender all dialogs myDialogStack.applyAll([&](Dialog*& d){ - //d->setDirty(); - d->render(); + d->render(); }); - // TODO: the screen is not updated until an event happens - // FrameBuffer::myBackend->renderToScreen() doesn't help + myOSystem.frameBuffer().renderToScreen(); } } } diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx new file mode 100644 index 000000000..53cbea0c3 --- /dev/null +++ b/src/gui/ToolTip.cxx @@ -0,0 +1,40 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "OSystem.hxx" +#include "Font.hxx" +#include "Dialog.hxx" +#include "DialogContainer.hxx" + +#include "ToolTip.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ToolTip::ToolTip(OSystem& instance, DialogContainer& parent, + const GUI::Font& font) + : Dialog(instance, parent, font) +{ + const int lineHeight = font.getLineHeight(), + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(), + buttonWidth = font.getStringWidth("Previous") + fontWidth * 2.5, + buttonHeight = font.getLineHeight() * 1.25; + const int VBORDER = fontHeight / 2; + const int HBORDER = fontWidth * 1.25; + const int VGAP = fontHeight / 4; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx new file mode 100644 index 000000000..2066bd3df --- /dev/null +++ b/src/gui/ToolTip.hxx @@ -0,0 +1,39 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef TOOL_TIP_HXX +#define TOOL_TIP_HXX + +class OSystem; +class DialogContainer; + +/** + * Class for providing tooltip functionality + * + * @author Thomas Jentzsch + */ +class ToolTip : public Dialog +{ + public: + + public: + ToolTip(OSystem& instance, DialogContainer& parent, + const GUI::Font& font); + ~ToolTip() override = default; +}; + +#endif diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 951a60282..1cacda9d6 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -71,13 +71,22 @@ bool Widget::isChainDirty() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Widget::tick() { - // Recursively tick widget and all child dialogs and widgets - Widget* w = _firstWidget; - - while(w) + if(isEnabled()) { - w->tick(); - w = w->_next; + //if(_hasFocus && hasToolTip()) + //{ + // if(dialog().enableToolTip()) + // dialog().showToolTip(10, 10); + //} + + // Recursively tick widget and all child dialogs and widgets + Widget* w = _firstWidget; + + while(w) + { + w->tick(); + w = w->_next; + } } } diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 6a505e8df..13eefdbf7 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -99,6 +99,9 @@ class Widget : public GuiObject void setBGColorHi(ColorId color) { _bgcolorhi = color; setDirty(); } void setShadowColor(ColorId color) { _shadowcolor = color; setDirty(); } + void setToolTip(const string& text) { _toolTipText = text; } + bool hasToolTip() const { return !_toolTipText.empty(); } + virtual void loadConfig() { } protected: @@ -130,6 +133,7 @@ class Widget : public GuiObject ColorId _textcolorhi{kTextColorHi}; ColorId _textcolorlo{kBGColorLo}; ColorId _shadowcolor{kShadowColor}; + string _toolTipText; public: static Widget* findWidgetInChain(Widget* start, int x, int y); diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 5f0bd9126..f9b5d3499 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -786,6 +786,7 @@ + @@ -1838,6 +1839,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 8dca2be2e..550419e9a 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1032,6 +1032,9 @@ Source Files\gui + + Source Files\gui +
    @@ -2123,6 +2126,9 @@ Header Files\gui + + Header Files\gui + From 15576fe6b1ea6626d6405fa8b34462ae7e7be1d1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 09:36:57 +0100 Subject: [PATCH 180/263] fixed forced full redraws force full UI redraw when UI palette changes --- src/emucore/FrameBuffer.cxx | 2 ++ src/gui/Dialog.cxx | 9 ++++++--- src/gui/Dialog.hxx | 2 +- src/gui/DialogContainer.cxx | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index a151084d1..2622b8fe9 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -889,6 +889,8 @@ void FrameBuffer::setUIPalette() myFullPalette[j] = mapRGB(r, g, b); } FBSurface::setPalette(myFullPalette); + if(&myOSystem.eventHandler()) + update(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index b483d6e96..e1bf15f3e 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -217,10 +217,13 @@ void Dialog::positionAt(uInt32 pos) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Dialog::redraw() +void Dialog::redraw(bool force) { - if(!isVisible() || !needsRedraw()) - return;// false; + if(!isVisible()) + return; + + if(force) + setDirty(); // Draw this dialog setPosition(); diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 4fc48b7fc..abb22911a 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -64,7 +64,7 @@ class Dialog : public GuiObject void tick() override; bool isChainDirty() const override; - void redraw(); + void redraw(bool force = false); void render(); void addFocusWidget(Widget* w) override; diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 50db35d3f..7b001cb06 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -102,8 +102,8 @@ void DialogContainer::draw(bool full) // Draw and render all dirty dialogs myDialogStack.applyAll([&](Dialog*& d) { - if(d->needsRedraw()) - d->redraw(); + if(full || d->needsRedraw()) + d->redraw(full); }); // Always render all surfaces, bottom to top render(); From 7c962fbfe7c80d602b3524a5fe2bd7ed5f52b2c4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 10:03:03 +0100 Subject: [PATCH 181/263] avoid full update when window gets exposed (test) --- src/emucore/EventHandler.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 9e7c9ea5f..cb372c7f9 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -323,7 +323,8 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int) { case SystemEvent::WINDOW_EXPOSED: case SystemEvent::WINDOW_RESIZED: - myOSystem.frameBuffer().update(true); // force full update + //myOSystem.frameBuffer().update(true); // force full update + myOSystem.frameBuffer().update(); break; #ifdef BSPF_UNIX case SystemEvent::WINDOW_FOCUS_GAINED: From 36f3810e405829d994e5ad1056f3be721d5045d9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 11:18:25 +0100 Subject: [PATCH 182/263] fixed missing render when a stacked dialog was closed in emulation --- src/emucore/FrameBuffer.cxx | 30 +++++++++++++++++++----------- src/emucore/FrameBuffer.hxx | 9 ++++++--- src/gui/DialogContainer.cxx | 10 ++-------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 2622b8fe9..ffc827ba9 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -311,7 +311,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::update(bool force) +void FrameBuffer::update(bool forceRedraw) { // Onscreen messages are a special case and require different handling than // other objects; they aren't UI dialogs in the normal sense nor are they @@ -322,11 +322,12 @@ void FrameBuffer::update(bool force) // - at the bottom of ::update(), to actually draw them (this must come // last, since they are always drawn on top of everything else). - // Forced rendering without drawing is required when messages are being disabled - // Only relevant for LAUNCHER, PAUSE and DEBUGGER modes - bool rerender = force || (myMsg.enabled && myMsg.counter == 0); + // Forced render without draw required if messages or dialogs were closed + // Note: For dialogs only relevant when two or more dialogs were stacked + bool rerender = forceRedraw || myPendingRender; + myPendingRender = false; - bool redraw = force; + bool redraw = forceRedraw; switch(myOSystem.eventHandler().state()) { case EventHandlerState::NONE: @@ -357,7 +358,13 @@ void FrameBuffer::update(bool force) { clear(); myTIASurface->render(); - myOSystem.menu().draw(force); + myOSystem.menu().draw(forceRedraw); + } + else if(rerender) + { + clear(); + myTIASurface->render(); + myOSystem.menu().render(); } break; // EventHandlerState::OPTIONSMENU } @@ -370,7 +377,7 @@ void FrameBuffer::update(bool force) { clear(); myTIASurface->render(); - myOSystem.commandMenu().draw(force); + myOSystem.commandMenu().draw(forceRedraw); } break; // EventHandlerState::CMDMENU } @@ -383,7 +390,7 @@ void FrameBuffer::update(bool force) { clear(); myTIASurface->render(); - myOSystem.messageMenu().draw(force); + myOSystem.messageMenu().draw(forceRedraw); } break; // EventHandlerState::MESSAGEMENU } @@ -396,7 +403,7 @@ void FrameBuffer::update(bool force) { clear(); myTIASurface->render(); - myOSystem.timeMachine().draw(force); + myOSystem.timeMachine().draw(forceRedraw); } break; // EventHandlerState::TIMEMACHINE } @@ -440,7 +447,7 @@ void FrameBuffer::update(bool force) myOSystem.launcher().tick(); redraw |= myOSystem.launcher().needsRedraw(); if(redraw) - myOSystem.launcher().draw(force); + myOSystem.launcher().draw(forceRedraw); else if(rerender) myOSystem.launcher().render(); break; // EventHandlerState::LAUNCHER @@ -453,7 +460,7 @@ void FrameBuffer::update(bool force) myOSystem.debugger().tick(); redraw |= myOSystem.debugger().needsRedraw(); if(redraw) - myOSystem.debugger().draw(force); + myOSystem.debugger().draw(forceRedraw); else if(rerender) myOSystem.debugger().render(); break; // EventHandlerState::DEBUGGER @@ -684,6 +691,7 @@ inline bool FrameBuffer::drawMessage() if(myMsg.counter == 0) { myMsg.enabled = false; + myPendingRender = true; return false; } diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 9d6f3e930..78106f8c0 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -84,7 +84,7 @@ class FrameBuffer Updates the display, which depending on the current mode could mean drawing the TIA, any pending menus, etc. */ - void update(bool force = false); + void update(bool forceRedraw = false); /** There is a dedicated update method for emulation mode. @@ -92,9 +92,9 @@ class FrameBuffer void updateInEmulationMode(float framesPerSecond); /** - Render backend to screen. + Set pending rendering flag. */ - void renderToScreen() { myBackend->renderToScreen(); } + void setPendingRender() { myPendingRender = true; } /** Shows a text message onscreen. @@ -460,6 +460,9 @@ class FrameBuffer // Supported renderers VariantList myRenderers; + // Flag for pending render + bool myPendingRender{false}; + // The VideoModeHandler class takes responsibility for all video // mode functionality VideoModeHandler myVidModeHandler; diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 7b001cb06..c2011e7e0 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -169,14 +169,8 @@ void DialogContainer::removeDialog() cerr << "remove dialog" << endl; myDialogStack.pop(); - if(!myDialogStack.empty()) - { - // Rerender all dialogs - myDialogStack.applyAll([&](Dialog*& d){ - d->render(); - }); - myOSystem.frameBuffer().renderToScreen(); - } + // Inform the frame buffer that it has to render all surfaces + myOSystem.frameBuffer().setPendingRender(); } } From 9900564862698914980e6c6a23617ac4e160d467 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 11:19:48 +0100 Subject: [PATCH 183/263] disabled palette display if without console --- src/gui/VideoAudioDialog.cxx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index f68be6df8..ba141cbeb 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -1157,10 +1157,11 @@ void VideoAudioDialog::addPalette(int x, int y, int w, int h) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void VideoAudioDialog::colorPalette() { + constexpr int NUM_LUMA = 8; + constexpr int NUM_CHROMA = 16; + if(instance().hasConsole()) { - constexpr int NUM_LUMA = 8; - constexpr int NUM_CHROMA = 16; const int order[2][NUM_CHROMA] = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, @@ -1176,11 +1177,14 @@ void VideoAudioDialog::colorPalette() ss << Common::Base::HEX1 << std::uppercase << color; myColorLbl[idx]->setLabel(ss.str()); for(int lum = 0; lum < NUM_LUMA; ++lum) - { myColor[idx][lum]->setColor(color * NUM_CHROMA + lum * 2); // skip grayscale colors - } } } + else + // disable palette + for(int idx = 0; idx < NUM_CHROMA; ++idx) + for(int lum = 0; lum < NUM_LUMA; ++lum) + myColor[idx][lum]->setEnabled(false); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From bcbf0072eafbecc6c7e9a69beae9c2cfb0cb4c0a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 14:24:52 +0100 Subject: [PATCH 184/263] fixed initial focus display --- src/emucore/EventHandler.cxx | 1 + src/gui/Dialog.cxx | 22 +++++++++++----------- src/gui/Widget.cxx | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index cb372c7f9..59c17c8a8 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -324,6 +324,7 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int) case SystemEvent::WINDOW_EXPOSED: case SystemEvent::WINDOW_RESIZED: //myOSystem.frameBuffer().update(true); // force full update + // TODO: test and maybe force a render update instead myOSystem.frameBuffer().update(); break; #ifdef BSPF_UNIX diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index e1bf15f3e..95379398a 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -476,17 +476,6 @@ void Dialog::drawDialog() clearDirty(); } - // Draw outlines for focused widgets - // Don't change focus, since this will trigger lost and received - // focus events - if(_focusedWidget) - { - _focusedWidget = Widget::setFocusForChain(this, getFocusList(), - _focusedWidget, 0, false); - // if(_focusedWidget) - // _focusedWidget->draw(); // make sure the highlight color is drawn initially - } - Widget* w = _firstWidget; // Draw all children @@ -498,6 +487,17 @@ void Dialog::drawDialog() w->draw(); w = w->_next; } + + // Draw outlines for focused widgets + // Don't change focus, since this will trigger lost and received + // focus events + if(_focusedWidget) + { + _focusedWidget = Widget::setFocusForChain(this, getFocusList(), + _focusedWidget, 0, false); + //if(_focusedWidget) + // _focusedWidget->draw(); // make sure the highlight color is drawn initially + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 1cacda9d6..93331cea1 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -269,7 +269,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr, s.frameRect(x, y, w, h, onTop ? kDlgColor : kBGColorLo); - tmp->setDirty(); + //tmp->setDirty(); } } @@ -325,7 +325,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr, if (onTop) s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed); - tmp->setDirty(); + //tmp->setDirty(); return tmp; } From d656598fa34184afca2b761a44b5553f9640da96 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 13 Nov 2020 10:05:11 -0330 Subject: [PATCH 185/263] Update Xcode for class addition. Comment out code that causes a crash on Mac. --- src/emucore/FrameBuffer.cxx | 4 ++-- src/macos/stella.xcodeproj/project.pbxproj | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index ffc827ba9..de1156200 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -897,8 +897,8 @@ void FrameBuffer::setUIPalette() myFullPalette[j] = mapRGB(r, g, b); } FBSurface::setPalette(myFullPalette); - if(&myOSystem.eventHandler()) - update(true); +// if(&myOSystem.eventHandler()) +// update(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index 4452ddce2..a23a0b173 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -531,6 +531,8 @@ DCBDDE9B1D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBDDE991D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx */; }; DCBDDE9E1D6A5F2F009DF1E9 /* Cart3EPlus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCBDDE9C1D6A5F2F009DF1E9 /* Cart3EPlus.cxx */; }; DCBDDE9F1D6A5F2F009DF1E9 /* Cart3EPlus.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */; }; + DCC2FDF5255EB82500FA5E81 /* ToolTip.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */; }; + DCC2FDF6255EB82500FA5E81 /* ToolTip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */; }; DCC527D110B9DA19005E1287 /* Device.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527C910B9DA19005E1287 /* Device.hxx */; }; DCC527D210B9DA19005E1287 /* M6502.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC527CA10B9DA19005E1287 /* M6502.cxx */; }; DCC527D310B9DA19005E1287 /* M6502.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527CB10B9DA19005E1287 /* M6502.hxx */; }; @@ -1298,6 +1300,8 @@ DCBDDE991D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EPlusWidget.hxx; sourceTree = ""; }; DCBDDE9C1D6A5F2F009DF1E9 /* Cart3EPlus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cart3EPlus.cxx; sourceTree = ""; }; DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EPlus.hxx; sourceTree = ""; }; + DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ToolTip.hxx; sourceTree = ""; }; + DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToolTip.cxx; sourceTree = ""; }; DCC527C910B9DA19005E1287 /* Device.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Device.hxx; sourceTree = ""; }; DCC527CA10B9DA19005E1287 /* M6502.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = M6502.cxx; sourceTree = ""; }; DCC527CB10B9DA19005E1287 /* M6502.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = M6502.hxx; sourceTree = ""; }; @@ -2167,6 +2171,8 @@ DCA82C6E1FEB4E780059340F /* TimeMachine.hxx */, DCA82C6F1FEB4E780059340F /* TimeMachineDialog.cxx */, DCA82C701FEB4E780059340F /* TimeMachineDialog.hxx */, + DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */, + DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */, DC8078E60B4BD697005E9305 /* UIDialog.cxx */, DC8078E70B4BD697005E9305 /* UIDialog.hxx */, DCBA539825557E2800087DD7 /* UndoHandler.cxx */, @@ -2651,6 +2657,7 @@ DC5D1AA7102C6FC900E59AC1 /* Stack.hxx in Headers */, DCF7B0DE10A762FC007A2870 /* CartF0.hxx in Headers */, DCF7B0E010A762FC007A2870 /* CartFA.hxx in Headers */, + DCC2FDF5255EB82500FA5E81 /* ToolTip.hxx in Headers */, DCC527D110B9DA19005E1287 /* Device.hxx in Headers */, DC6F394E21B897F300897AD8 /* ThreadDebugging.hxx in Headers */, DCC527D310B9DA19005E1287 /* M6502.hxx in Headers */, @@ -3205,6 +3212,7 @@ DCAACB0E188D636F00A4D282 /* Cart4KSCWidget.cxx in Sources */, DCB60AD02543100900A5C1D2 /* FBBackendSDL2.cxx in Sources */, DCAACB10188D636F00A4D282 /* CartBFSCWidget.cxx in Sources */, + DCC2FDF6255EB82500FA5E81 /* ToolTip.cxx in Sources */, DCAACB12188D636F00A4D282 /* CartBFWidget.cxx in Sources */, DCAACB14188D636F00A4D282 /* CartDFSCWidget.cxx in Sources */, DCAACB16188D636F00A4D282 /* CartDFWidget.cxx in Sources */, From 2505201b4b3125d0251356ae09036d21f498c0d7 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 16:00:19 +0100 Subject: [PATCH 186/263] fixed UI palette update crash fixed garbage when switching state in fullscreen modes --- src/emucore/EventHandler.cxx | 1 + src/emucore/FrameBuffer.cxx | 20 +++++++++++++------- src/emucore/FrameBuffer.hxx | 5 +++++ src/gui/DialogContainer.cxx | 3 +++ src/gui/StellaSettingsDialog.cxx | 1 + src/gui/UIDialog.cxx | 1 + 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 59c17c8a8..3164a92a4 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -2320,6 +2320,7 @@ bool EventHandler::enterDebugMode() } myOverlay->reStack(); myOSystem.sound().mute(true); + #else myOSystem.frameBuffer().showTextMessage("Debugger support not included", MessagePosition::BottomCenter, true); diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index de1156200..c51cdbbce 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -270,7 +270,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, #ifdef GUI_SUPPORT // Erase any messages from a previous run - myMsg.counter = 0; + myMsg.enabled = false; // Create surfaces for TIA statistics and general messages const GUI::Font& f = hidpiEnabled() ? infoFont() : font(); @@ -677,11 +677,19 @@ void FrameBuffer::enableMessages(bool enable) myStatsMsg.enabled = false; // Erase old messages on the screen - myMsg.counter = 0; + hideMessage(); + update(); // update immediately } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FrameBuffer::hideMessage() +{ + myPendingRender = myMsg.enabled; + myMsg.enabled = false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - inline bool FrameBuffer::drawMessage() { @@ -690,8 +698,7 @@ inline bool FrameBuffer::drawMessage() // or show again this frame if(myMsg.counter == 0) { - myMsg.enabled = false; - myPendingRender = true; + hideMessage(); return false; } @@ -897,15 +904,13 @@ void FrameBuffer::setUIPalette() myFullPalette[j] = mapRGB(r, g, b); } FBSurface::setPalette(myFullPalette); -// if(&myOSystem.eventHandler()) -// update(true); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::stateChanged(EventHandlerState state) { // Make sure any onscreen messages are removed - myMsg.counter = 0; + hideMessage(); update(); // update immediately } @@ -1169,6 +1174,7 @@ FBInitStatus FrameBuffer::applyVideoMode() resetSurfaces(); setCursorState(); + myPendingRender = true; } else Logger::error("ERROR: Couldn't initialize video subsystem"); diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index 78106f8c0..e5e6bd1b6 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -399,6 +399,11 @@ class FrameBuffer */ bool drawMessage(); + /** + Hide pending messages. + */ + void hideMessage(); + /** Draws the frame stats overlay. */ diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index c2011e7e0..1c75273b4 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -181,6 +181,9 @@ void DialogContainer::reStack() while(!myDialogStack.empty()) myDialogStack.top()->close(); + // Make sure that all surfaces are cleared + myOSystem.frameBuffer().clear(); + baseDialog()->open(); // Reset all continuous events diff --git a/src/gui/StellaSettingsDialog.cxx b/src/gui/StellaSettingsDialog.cxx index fc3d3e4d9..dbd2ac09c 100644 --- a/src/gui/StellaSettingsDialog.cxx +++ b/src/gui/StellaSettingsDialog.cxx @@ -268,6 +268,7 @@ void StellaSettingsDialog::saveConfig() settings.setValue("uipalette", myThemePopup->getSelectedTag().toString()); instance().frameBuffer().setUIPalette(); + instance().frameBuffer().update(true); // Dialog position settings.setValue("dialogpos", myPositionPopup->getSelectedTag().toString()); diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx index 1b64d73f2..1a75ee440 100644 --- a/src/gui/UIDialog.cxx +++ b/src/gui/UIDialog.cxx @@ -441,6 +441,7 @@ void UIDialog::saveConfig() settings.setValue("uipalette", myPalettePopup->getSelectedTag().toString()); instance().frameBuffer().setUIPalette(); + instance().frameBuffer().update(true); // Dialog font settings.setValue("dialogfont", From db55dc44208a87dbc8806ea2b347dba7495f3e12 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 16:12:33 +0100 Subject: [PATCH 187/263] improved fullscreen message in debugger mode --- src/emucore/FrameBuffer.cxx | 38 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index c51cdbbce..823b864c1 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -927,10 +927,10 @@ string FrameBuffer::getDisplayKey() case BufferType::Emulator: return "display"; - #ifdef DEBUGGER_SUPPORT + #ifdef DEBUGGER_SUPPORT case BufferType::Debugger: return "dbg.display"; - #endif + #endif default: return ""; @@ -949,10 +949,10 @@ string FrameBuffer::getPositionKey() case BufferType::Emulator: return "windowedpos"; - #ifdef DEBUGGER_SUPPORT + #ifdef DEBUGGER_SUPPORT case BufferType::Debugger: return "dbg.pos"; - #endif + #endif default: return ""; @@ -963,10 +963,10 @@ string FrameBuffer::getPositionKey() void FrameBuffer::saveCurrentWindowPosition() { myOSystem.settings().setValue( - getDisplayKey(), myBackend->getCurrentDisplayIndex()); + getDisplayKey(), myBackend->getCurrentDisplayIndex()); if(myBackend->isCurrentWindowPositioned()) myOSystem.settings().setValue( - getPositionKey(), myBackend->getCurrentWindowPos()); + getPositionKey(), myBackend->getCurrentWindowPos()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1001,7 +1001,9 @@ void FrameBuffer::setFullscreen(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameBuffer::toggleFullscreen(bool toggle) { - switch(myOSystem.eventHandler().state()) + EventHandlerState state = myOSystem.eventHandler().state(); + + switch(state) { case EventHandlerState::LAUNCHER: case EventHandlerState::EMULATION: @@ -1011,16 +1013,26 @@ void FrameBuffer::toggleFullscreen(bool toggle) const bool isFullscreen = toggle ? !fullScreen() : fullScreen(); setFullscreen(isFullscreen); - if(myBufferType != BufferType::Launcher) + if(state != EventHandlerState::LAUNCHER) { ostringstream msg; msg << "Fullscreen "; - if(isFullscreen) - msg << "enabled (" << myBackend->refreshRate() << " Hz, "; - else - msg << "disabled ("; - msg << "Zoom " << myActiveVidMode.zoom * 100 << "%)"; + if(state != EventHandlerState::DEBUGGER) + { + if(isFullscreen) + msg << "enabled (" << myBackend->refreshRate() << " Hz, "; + else + msg << "disabled ("; + msg << "Zoom " << myActiveVidMode.zoom * 100 << "%)"; + } + else + { + if(isFullscreen) + msg << "enabled"; + else + msg << "disabled"; + } showTextMessage(msg.str()); } break; From ed13b214026675e087a44f8c805461642429d5e3 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 13 Nov 2020 19:53:19 +0100 Subject: [PATCH 188/263] added a full render when event WINDOW_EXPOSED and WINDOW_RESIZED are handled stopped screen from changing frames when 'Pause' is displayed --- src/emucore/EventHandler.cxx | 5 ++--- src/emucore/FrameBuffer.cxx | 13 ++++++++----- src/emucore/FrameBuffer.hxx | 8 +++++++- src/gui/StellaSettingsDialog.cxx | 2 +- src/gui/UIDialog.cxx | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 3164a92a4..7d241101e 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -323,9 +323,8 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int) { case SystemEvent::WINDOW_EXPOSED: case SystemEvent::WINDOW_RESIZED: - //myOSystem.frameBuffer().update(true); // force full update - // TODO: test and maybe force a render update instead - myOSystem.frameBuffer().update(); + // Force full render update + myOSystem.frameBuffer().update(FrameBuffer::UpdateMode::RERENDER); break; #ifdef BSPF_UNIX case SystemEvent::WINDOW_FOCUS_GAINED: diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 823b864c1..fce9cdae4 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -311,7 +311,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FrameBuffer::update(bool forceRedraw) +void FrameBuffer::update(UpdateMode mode) { // Onscreen messages are a special case and require different handling than // other objects; they aren't UI dialogs in the normal sense nor are they @@ -322,12 +322,15 @@ void FrameBuffer::update(bool forceRedraw) // - at the bottom of ::update(), to actually draw them (this must come // last, since they are always drawn on top of everything else). + bool forceRedraw = mode & UpdateMode::REDRAW; + bool redraw = forceRedraw; + // Forced render without draw required if messages or dialogs were closed // Note: For dialogs only relevant when two or more dialogs were stacked - bool rerender = forceRedraw || myPendingRender; + bool rerender = (mode & (UpdateMode::REDRAW | UpdateMode::RERENDER)) + || myPendingRender; myPendingRender = false; - bool redraw = forceRedraw; switch(myOSystem.eventHandler().state()) { case EventHandlerState::NONE: @@ -342,10 +345,10 @@ void FrameBuffer::update(bool forceRedraw) { myPausedCount = uInt32(7 * myOSystem.frameRate()); showTextMessage("Paused", MessagePosition::MiddleCenter); + myTIASurface->render(); } if(rerender) myTIASurface->render(); - break; // EventHandlerState::PAUSE } @@ -857,7 +860,7 @@ void FrameBuffer::resetSurfaces() freeSurfaces(); reloadSurfaces(); - update(true); // force full update + update(UpdateMode::REDRAW); // force full update } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx index e5e6bd1b6..0971873f2 100644 --- a/src/emucore/FrameBuffer.hxx +++ b/src/emucore/FrameBuffer.hxx @@ -55,6 +55,12 @@ class FrameBuffer // Zoom level step interval static constexpr float ZOOM_STEPS = 0.25; + enum UpdateMode { + NONE = 0, + REDRAW = 1, + RERENDER = 2 + }; + public: FrameBuffer(OSystem& osystem); ~FrameBuffer(); @@ -84,7 +90,7 @@ class FrameBuffer Updates the display, which depending on the current mode could mean drawing the TIA, any pending menus, etc. */ - void update(bool forceRedraw = false); + void update(UpdateMode mode = UpdateMode::NONE); /** There is a dedicated update method for emulation mode. diff --git a/src/gui/StellaSettingsDialog.cxx b/src/gui/StellaSettingsDialog.cxx index dbd2ac09c..06ff03b3e 100644 --- a/src/gui/StellaSettingsDialog.cxx +++ b/src/gui/StellaSettingsDialog.cxx @@ -268,7 +268,7 @@ void StellaSettingsDialog::saveConfig() settings.setValue("uipalette", myThemePopup->getSelectedTag().toString()); instance().frameBuffer().setUIPalette(); - instance().frameBuffer().update(true); + instance().frameBuffer().update(FrameBuffer::UpdateMode::REDRAW); // Dialog position settings.setValue("dialogpos", myPositionPopup->getSelectedTag().toString()); diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx index 1a75ee440..12f710bc0 100644 --- a/src/gui/UIDialog.cxx +++ b/src/gui/UIDialog.cxx @@ -441,7 +441,7 @@ void UIDialog::saveConfig() settings.setValue("uipalette", myPalettePopup->getSelectedTag().toString()); instance().frameBuffer().setUIPalette(); - instance().frameBuffer().update(true); + instance().frameBuffer().update(FrameBuffer::UpdateMode::REDRAW); // Dialog font settings.setValue("dialogfont", From f52e834455955d7c906dd180cc8afa7edd9d4513 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 14 Nov 2020 09:43:41 +0100 Subject: [PATCH 189/263] fixed breakpoints setting in RomListWidget improved drawing of breakpoints in RomListWidget made RomListWidget redraw regularly only if in edit mode --- src/debugger/gui/RomListWidget.cxx | 32 +++++++++++++++--------------- src/debugger/gui/RomListWidget.hxx | 1 - src/debugger/gui/RomWidget.cxx | 4 ---- src/gui/Dialog.cxx | 10 +++++++--- src/gui/Dialog.hxx | 1 + src/gui/EditableWidget.cxx | 2 +- src/gui/EditableWidget.hxx | 1 + src/gui/GuiObject.hxx | 11 ++++++---- src/gui/Widget.cxx | 7 +++++++ src/gui/Widget.hxx | 1 + 10 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 20fc53052..3504b2b37 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -39,6 +39,8 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, _textcolor = kTextColor; _textcolorhi = kTextColor; + _editMode = false; + _cols = w / _fontWidth; _rows = h / _lineHeight; @@ -480,20 +482,18 @@ void RomListWidget::drawWidget(bool hilite) codeDisasmW = actualWidth; xpos = _x + CheckboxWidget::boxSize(_font) + 10; ypos = _y + 2; - for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _lineHeight) + for(i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _lineHeight) { ColorId bytesColor = textColor; - // Draw checkboxes for correct lines (takes scrolling into account) + // Mark checkboxes dirty for correct lines (takes scrolling into account) myCheckList[i]->setState(instance().debugger(). checkBreakPoint(dlist[pos].address, instance().debugger().cartDebug().getBank(dlist[pos].address))); - myCheckList[i]->setDirty(); - myCheckList[i]->draw(); // Draw highlighted item in a frame - if (_highlightedItem == pos) + if(_highlightedItem == pos) s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _lineHeight, onTop ? kWidColorHi : kBGColorLo); // Draw the selected item inverted, on a highlighted background. @@ -510,31 +510,31 @@ void RomListWidget::drawWidget(bool hilite) // Draw labels s.drawString(_font, dlist[pos].label, xpos, ypos, _labelWidth, - dlist[pos].hllabel ? textColor : kColor); + dlist[pos].hllabel ? textColor : kColor); // Bytes are only editable if they represent code, graphics, or accessible data // Otherwise, the disassembly should get all remaining space - if(dlist[pos].type & (Device::CODE|Device::GFX|Device::PGFX| - Device::COL|Device::PCOL|Device::BCOL|Device::DATA)) + if(dlist[pos].type & (Device::CODE | Device::GFX | Device::PGFX | + Device::COL | Device::PCOL | Device::BCOL | Device::DATA)) { if(dlist[pos].type == Device::CODE) { // Draw mnemonic s.drawString(_font, dlist[pos].disasm.substr(0, 7), xpos + _labelWidth, ypos, - 7 * _fontWidth, textColor); + 7 * _fontWidth, textColor); // Draw operand - if (dlist[pos].disasm.length() > 8) + if(dlist[pos].disasm.length() > 8) s.drawString(_font, dlist[pos].disasm.substr(8), xpos + _labelWidth + 7 * _fontWidth, ypos, - codeDisasmW - 7 * _fontWidth, textColor); + codeDisasmW - 7 * _fontWidth, textColor); // Draw cycle count s.drawString(_font, dlist[pos].ccount, xpos + _labelWidth + codeDisasmW, ypos, - cycleCountW, textColor); + cycleCountW, textColor); } else { // Draw disassembly only s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos, - noCodeDisasmW - 4, kTextColor); + noCodeDisasmW - 4, kTextColor); } // Draw separator @@ -542,11 +542,11 @@ void RomListWidget::drawWidget(bool hilite) // Draw bytes { - if (_selectedItem == pos && _editMode) + if(_selectedItem == pos && _editMode) { adjustOffset(); s.drawString(_font, editString(), _x + r.x(), ypos, r.w(), textColor, - TextAlign::Left, -_editScrollOffset, false); + TextAlign::Left, -_editScrollOffset, false); drawCaretSelection(); } @@ -560,7 +560,7 @@ void RomListWidget::drawWidget(bool hilite) { // Draw disassembly, giving it all remaining horizontal space s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos, - noTypeDisasmW, textColor); + noTypeDisasmW, textColor); } } } diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx index 40abb0adf..ec557f606 100644 --- a/src/debugger/gui/RomListWidget.hxx +++ b/src/debugger/gui/RomListWidget.hxx @@ -96,7 +96,6 @@ class RomListWidget : public EditableWidget int _currentPos{0}; // position of first line in visible window int _selectedItem{-1}; int _highlightedItem{-1}; - bool _editMode{false}; StellaKey _currentKeyDown{KBDK_UNKNOWN}; Common::Base::Fmt _base{Common::Base::Fmt::_DEFAULT}; // base used during editing diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx index 87572d6ed..0454ef16d 100644 --- a/src/debugger/gui/RomWidget.cxx +++ b/src/debugger/gui/RomWidget.cxx @@ -90,10 +90,6 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) case RomListWidget::kBPointChangedCmd: // 'data' is the line in the disassemblylist to be accessed toggleBreak(data); - // Refresh the romlist, since the breakpoint may not have - // actually changed - myRomList->setDirty(); - myRomList->draw(); break; case RomListWidget::kRomChangedCmd: diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 95379398a..215289771 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -476,13 +476,17 @@ void Dialog::drawDialog() clearDirty(); } + // Draw all children + drawChain(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::drawChain() +{ Widget* w = _firstWidget; - // Draw all children - w = _firstWidget; while(w) { - // only redraw changed widgets if(w->needsRedraw()) w->draw(); w = w->_next; diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index abb22911a..de81b4a1d 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -65,6 +65,7 @@ class Dialog : public GuiObject void tick() override; bool isChainDirty() const override; void redraw(bool force = false); + void drawChain() override; void render(); void addFocusWidget(Widget* w) override; diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 4c3928052..8e19cb0a2 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -66,7 +66,7 @@ void EditableWidget::setText(const string& str, bool) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::tick() { - if(_hasFocus && _editable && isVisible() && _boss->isVisible()) + if(_hasFocus && isEditable() && _editMode && isVisible() && _boss->isVisible()) { _caretTimer++; if(_caretTimer > 40) // switch every 2/3rd seconds diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 345a4c618..8ebf1791c 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -123,6 +123,7 @@ class EditableWidget : public Widget, public CommandSender protected: int _editScrollOffset{0}; + bool _editMode{true}; private: TextFilter _filter; diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index 581d498aa..893686e5f 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -91,16 +91,18 @@ class GuiObject : public CommandReceiver virtual void setHeight(int h) { _h = h; } virtual bool isVisible() const = 0; - virtual void setDirty() { _dirty = true; } - virtual void clearDirty() { _dirty = false; } - virtual void tick() = 0; - virtual bool isDirty() const { return _dirty; } + void setDirty() { _dirty = true; } + void clearDirty() { _dirty = false; } + bool isDirty() const { return _dirty; } virtual bool isChainDirty() const = 0; + // The GUI indicates if its underlying surface needs to be redrawn // and then re-rendered virtual bool needsRedraw() { return isDirty() || isChainDirty(); } + virtual void tick() = 0; + void setFlags(uInt32 flags) { uInt32 oldFlags = _flags; @@ -140,6 +142,7 @@ class GuiObject : public CommandReceiver protected: virtual void releaseFocus() = 0; virtual void draw() = 0; + virtual void drawChain() = 0; private: OSystem& myOSystem; diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 93331cea1..e04da70d9 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -157,7 +157,14 @@ void Widget::draw() clearDirty(); // Draw all children + drawChain(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::drawChain() +{ Widget* w = _firstWidget; + while(w) { if(w->needsRedraw()) diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 13eefdbf7..38f8fecfa 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -72,6 +72,7 @@ class Widget : public GuiObject void tick() override; bool isChainDirty() const override; void draw() override; + void drawChain() override; void receivedFocus(); void lostFocus(); void addFocusWidget(Widget* w) override { _focusList.push_back(w); } From a81ab40f5845cf212a4786b8118f53ae9668586b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 14 Nov 2020 10:03:29 +0100 Subject: [PATCH 190/263] removed special colors and drawing for Dialog in background --- src/emucore/FrameBuffer.cxx | 10 ++++------ src/emucore/FrameBufferConstants.hxx | 4 +--- src/gui/Dialog.cxx | 15 ++++----------- src/gui/Dialog.hxx | 3 +-- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index fce9cdae4..91cabfe3e 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -1326,8 +1326,6 @@ void FrameBuffer::toggleGrabMouse() kColorInfo TIA output position color kColorTitleBar Title bar color kColorTitleText Title text color - kColorTitleBarLo Disabled title bar color - kColorTitleTextLo Disabled title text color */ UIPaletteArray FrameBuffer::ourStandardUIPalette = { { 0x686868, 0x000000, 0xa38c61, 0xdccfa5, 0x404040, // base @@ -1338,7 +1336,7 @@ UIPaletteArray FrameBuffer::ourStandardUIPalette = { 0xac3410, 0xd55941, // scrollbar 0xc80000, 0xffff80, 0xc8c8ff, 0xc80000, // debugger 0xac3410, 0xd55941, 0xdccfa5, 0xf0f0cf, 0xa38c61, // slider - 0xffffff, 0xac3410, 0xf0f0cf, 0x686868, 0xdccfa5 // other + 0xffffff, 0xac3410, 0xf0f0cf // other } }; @@ -1351,7 +1349,7 @@ UIPaletteArray FrameBuffer::ourClassicUIPalette = { 0x20a020, 0x00ff00, // scrollbar 0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000, // debugger 0x20a020, 0x00ff00, 0x404040, 0x686868, 0x404040, // slider - 0x00ff00, 0x20a020, 0x000000, 0x686868, 0x404040 // other + 0x00ff00, 0x20a020, 0x000000 // other } }; @@ -1364,7 +1362,7 @@ UIPaletteArray FrameBuffer::ourLightUIPalette = { 0xc0c0c0, 0x808080, // scrollbar 0xffc0c0, 0x000000, 0xe00000, 0xc00000, // debugger 0x333333, 0x0078d7, 0xc0c0c0, 0xffffff, 0xc0c0c0, // slider 0xBDDEF9| 0xe1e1e1 | 0xffffff - 0xffffff, 0x333333, 0xf0f0f0, 0x808080, 0xc0c0c0 // other + 0xffffff, 0x333333, 0xf0f0f0 // other } }; @@ -1377,6 +1375,6 @@ UIPaletteArray FrameBuffer::ourDarkUIPalette = { 0x3c3c3c, 0x646464, // scrollbar 0x7f2020, 0xc0c0c0, 0xe00000, 0xc00000, // debugger 0x989898, 0x0059a3, 0x3c3c3c, 0x000000, 0x3c3c3c, // slider - 0x000000, 0x989898, 0x202020, 0x646464, 0x3c3c3c // other + 0x000000, 0x989898, 0x202020 // other } }; diff --git a/src/emucore/FrameBufferConstants.hxx b/src/emucore/FrameBufferConstants.hxx index 134086a0a..7896fd04c 100644 --- a/src/emucore/FrameBufferConstants.hxx +++ b/src/emucore/FrameBufferConstants.hxx @@ -109,9 +109,7 @@ static constexpr ColorId kColorInfo = 287, kColorTitleBar = 288, kColorTitleText = 289, - kColorTitleBarLo = 290, - kColorTitleTextLo = 291, - kNumColors = 292, + kNumColors = 290, kNone = 0 // placeholder to represent default/no color ; diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 215289771..a2b9c14e3 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -441,26 +441,19 @@ void Dialog::drawDialog() { //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; - // Dialog is still on top if e.g a ContextMenu is opened - _onTop = true/*parent().myDialogStack.top() == this*/ - || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this - && !parent().myDialogStack.top()->hasTitle()); - - cerr << "on top " << isOnTop() << endl; if(clearsBackground()) { // cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl; if(hasBackground()) - s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo); + s.fillRect(_x, _y + _th, _w, _h - _th, kDlgColor); else s.invalidateRect(_x, _y + _th, _w, _h - _th); if(_th) { - s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo); + s.fillRect(_x, _y, _w, _th, kColorTitleBar); s.drawString(_font, _title, _x + _font.getMaxCharWidth() * 1.25, _y + _font.getFontHeight() / 6, - _font.getStringWidth(_title), - _onTop ? kColorTitleText : kColorTitleTextLo); + _font.getStringWidth(_title), kColorTitleText); } } else { @@ -468,7 +461,7 @@ void Dialog::drawDialog() cerr << "invalidate " << typeid(*this).name() << endl; } if(hasBorder()) // currently only used by Dialog itself - s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor); + s.frameRect(_x, _y, _w, _h, kColor); // Make all child widgets dirty Widget::setDirtyInChain(_firstWidget); diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index de81b4a1d..3966e5db9 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -54,7 +54,7 @@ class Dialog : public GuiObject void close(); bool isVisible() const override { return _visible; } - bool isOnTop() const { return _onTop; } + bool isOnTop() const { return true; } // TODO: remove virtual void setPosition(); virtual void drawDialog(); @@ -197,7 +197,6 @@ class Dialog : public GuiObject Widget* _cancelWidget{nullptr}; bool _visible{false}; - bool _onTop{true}; bool _processCancel{false}; string _title; int _th{0}; From 1c5d31db6004bc4e17dad2b42e57c51ae64f739c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 14 Nov 2020 12:07:44 +0100 Subject: [PATCH 191/263] improved dirty chain detection --- src/gui/Dialog.cxx | 52 +++++++++++++++++++------------------- src/gui/Dialog.hxx | 6 +++-- src/gui/EditableWidget.cxx | 2 +- src/gui/GuiObject.hxx | 7 +++-- src/gui/Widget.cxx | 29 ++++++++++++--------- src/gui/Widget.hxx | 4 ++- 6 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index a2b9c14e3..84c4c9dac 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -147,20 +147,15 @@ void Dialog::setPosition() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Dialog::isChainDirty() const +void Dialog::setDirty() { - bool dirty = false; + _dirty = true; +} - // Recursively check if dialog or any chick dialogs or widgets are dirty - Widget* w = _firstWidget; - - while(w && !dirty) - { - dirty |= w->needsRedraw(); - w = w->_next; - } - - return dirty; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::setDirtyChain() +{ + _dirtyChain = true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -440,6 +435,7 @@ void Dialog::drawDialog() if(isDirty()) { //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; + cerr << "d"; if(clearsBackground()) { @@ -458,7 +454,7 @@ void Dialog::drawDialog() } else { s.invalidate(); - cerr << "invalidate " << typeid(*this).name() << endl; + //cerr << "invalidate " << typeid(*this).name() << endl; } if(hasBorder()) // currently only used by Dialog itself s.frameRect(_x, _y, _w, _h, kColor); @@ -471,19 +467,6 @@ void Dialog::drawDialog() // Draw all children drawChain(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Dialog::drawChain() -{ - Widget* w = _firstWidget; - - while(w) - { - if(w->needsRedraw()) - w->draw(); - w = w->_next; - } // Draw outlines for focused widgets // Don't change focus, since this will trigger lost and received @@ -497,6 +480,23 @@ void Dialog::drawChain() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Dialog::drawChain() +{ + // Clear chain *before* drawing, because some widgets may set it again when + // being drawn (e.g. RomListWidget) + clearDirtyChain(); + + Widget* w = _firstWidget; + + while(w) + { + if(w->needsRedraw()) + w->draw(); + w = w->_next; + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::handleText(char text) { diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 3966e5db9..0d0c57bc3 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -62,12 +62,14 @@ class Dialog : public GuiObject virtual void saveConfig() { } virtual void setDefaults() { } - void tick() override; - bool isChainDirty() const override; + void setDirty() override; + void setDirtyChain() override; void redraw(bool force = false); void drawChain() override; void render(); + void tick() override; + void addFocusWidget(Widget* w) override; void addToFocusList(WidgetArray& list) override; void addToFocusList(WidgetArray& list, TabWidget* w, int tabId); diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 8e19cb0a2..3e86ea947 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -73,7 +73,7 @@ void EditableWidget::tick() { _caretTimer = 0; _caretEnabled = !_caretEnabled; - _dirty = true; + setDirty(); } } Widget::tick(); diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index 893686e5f..c276698f8 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -92,10 +92,12 @@ class GuiObject : public CommandReceiver virtual bool isVisible() const = 0; - void setDirty() { _dirty = true; } + virtual void setDirty() = 0; + virtual void setDirtyChain() = 0; void clearDirty() { _dirty = false; } + void clearDirtyChain() { _dirtyChain = false; } bool isDirty() const { return _dirty; } - virtual bool isChainDirty() const = 0; + bool isChainDirty() const { return _dirtyChain; } // The GUI indicates if its underlying surface needs to be redrawn // and then re-rendered @@ -152,6 +154,7 @@ class GuiObject : public CommandReceiver protected: int _x{0}, _y{0}, _w{0}, _h{0}; bool _dirty{false}; + bool _dirtyChain{false}; uInt32 _flags{0}; Widget* _firstWidget{nullptr}; diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index e04da70d9..f33d27146 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -52,20 +52,21 @@ Widget::~Widget() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Widget::isChainDirty() const +void Widget::setDirty() { - bool dirty = false; + _dirty = true; - // Recursively check if widget or any child dialogs or widgets are dirty - Widget* w = _firstWidget; + // Inform the parent object that its children chain is dirty + _boss->setDirtyChain(); +} - while(w && !dirty) - { - dirty |= w->needsRedraw(); - w = w->_next; - } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setDirtyChain() +{ + _dirtyChain = true; - return dirty; + // Inform the parent object that its children chain is dirty + _boss->setDirtyChain(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -98,7 +99,8 @@ void Widget::draw() if(isDirty()) { - cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; + //cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; + cerr << "w"; FBSurface& s = _boss->dialog().surface(); @@ -163,6 +165,10 @@ void Widget::draw() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Widget::drawChain() { + // Clear chain *before* drawing, because some widgets may set it again when + // being drawn (e.g. RomListWidget) + clearDirtyChain(); + Widget* w = _firstWidget; while(w) @@ -508,7 +514,6 @@ void ButtonWidget::setBitmap(const uInt32* bitmap, int bmw, int bmh) _bmh = bmh; _bmw = bmw; - cerr << "setBitmap" << endl; setDirty(); } diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 38f8fecfa..5ee8ef0b1 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -70,7 +70,9 @@ class Widget : public GuiObject virtual bool handleEvent(Event::Type event) { return false; } void tick() override; - bool isChainDirty() const override; + + void setDirty() override; + void setDirtyChain() override; void draw() override; void drawChain() override; void receivedFocus(); From eca862b2403fd48a2a06b3c4dcc87bd2f979a31c Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 14 Nov 2020 20:41:06 -0330 Subject: [PATCH 192/263] Eliminate graphical garbage in background in fullscreen mode for Linux/Mac. --- src/gui/DialogContainer.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 1c75273b4..e7fb0b81d 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -124,6 +124,10 @@ void DialogContainer::render() cerr << "full re-render " << typeid(*this).name() << endl; + // Make sure we start in a clean state (with zero'ed buffers) + if(!myOSystem.eventHandler().inTIAMode()) + myOSystem.frameBuffer().clear(); + // Render all dialogs myDialogStack.applyAll([&](Dialog*& d) { d->render(); From a030bc30b890d1252a60b25720e2e335a97fc552 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 14 Nov 2020 22:35:05 -0330 Subject: [PATCH 193/263] Optimize/simplify dialog shading slightly - move creation to c'tor - apply position and size with one method instead of two --- src/common/FBSurfaceSDL2.cxx | 40 ++++++++++++++---------- src/common/FBSurfaceSDL2.hxx | 49 ++++++++++++++++++++++-------- src/emucore/FBSurface.hxx | 3 ++ src/gui/Dialog.cxx | 33 +++++++++----------- src/libretro/FBSurfaceLIBRETRO.hxx | 3 ++ 5 files changed, 80 insertions(+), 48 deletions(-) diff --git a/src/common/FBSurfaceSDL2.cxx b/src/common/FBSurfaceSDL2.cxx index 398c773ba..7f0ddb7d7 100644 --- a/src/common/FBSurfaceSDL2.cxx +++ b/src/common/FBSurfaceSDL2.cxx @@ -104,41 +104,49 @@ const Common::Rect& FBSurfaceSDL2::dstRect() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceSDL2::setSrcPos(uInt32 x, uInt32 y) { - if(x != static_cast(mySrcR.x) || y != static_cast(mySrcR.y)) - { - setSrcPosInternal(x, y); + if(setSrcPosInternal(x, y)) reinitializeBlitter(); - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceSDL2::setSrcSize(uInt32 w, uInt32 h) { - if(w != static_cast(mySrcR.w) || h != static_cast(mySrcR.h)) - { - setSrcSizeInternal(w, h); + if(setSrcSizeInternal(w, h)) + reinitializeBlitter(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FBSurfaceSDL2::setSrcRect(const Common::Rect& r) +{ + const bool posChanged = setSrcPosInternal(r.x(), r.y()), + sizeChanged = setSrcSizeInternal(r.w(), r.h()); + + if(posChanged || sizeChanged) reinitializeBlitter(); - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceSDL2::setDstPos(uInt32 x, uInt32 y) { - if(x != static_cast(myDstR.x) || y != static_cast(myDstR.y)) - { - setDstPosInternal(x, y); + if(setDstPosInternal(x, y)) reinitializeBlitter(); - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceSDL2::setDstSize(uInt32 w, uInt32 h) { - if(w != static_cast(myDstR.w) || h != static_cast(myDstR.h)) - { - setDstSizeInternal(w, h); + if(setDstSizeInternal(w, h)) + reinitializeBlitter(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FBSurfaceSDL2::setDstRect(const Common::Rect& r) +{ + const bool posChanged = setDstPosInternal(r.x(), r.y()), + sizeChanged = setDstSizeInternal(r.w(), r.h()); + + if(posChanged || sizeChanged) reinitializeBlitter(); - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/FBSurfaceSDL2.hxx b/src/common/FBSurfaceSDL2.hxx index c19808f27..d8bfa0029 100644 --- a/src/common/FBSurfaceSDL2.hxx +++ b/src/common/FBSurfaceSDL2.hxx @@ -48,8 +48,11 @@ class FBSurfaceSDL2 : public FBSurface const Common::Rect& dstRect() const override; void setSrcPos(uInt32 x, uInt32 y) override; void setSrcSize(uInt32 w, uInt32 h) override; + void setSrcRect(const Common::Rect& r) override; void setDstPos(uInt32 x, uInt32 y) override; void setDstSize(uInt32 w, uInt32 h) override; + void setDstRect(const Common::Rect& r) override; + void setVisible(bool visible) override; void translateCoords(Int32& x, Int32& y) const override; @@ -67,21 +70,41 @@ class FBSurfaceSDL2 : public FBSurface void applyAttributes() override; private: - inline void setSrcPosInternal(uInt32 x, uInt32 y) { - mySrcR.x = x; mySrcR.y = y; - mySrcGUIR.moveTo(x, y); + inline bool setSrcPosInternal(uInt32 x, uInt32 y) { + if(x != static_cast(mySrcR.x) || y != static_cast(mySrcR.y)) + { + mySrcR.x = x; mySrcR.y = y; + mySrcGUIR.moveTo(x, y); + return true; + } + return false; } - inline void setSrcSizeInternal(uInt32 w, uInt32 h) { - mySrcR.w = w; mySrcR.h = h; - mySrcGUIR.setWidth(w); mySrcGUIR.setHeight(h); + inline bool setSrcSizeInternal(uInt32 w, uInt32 h) { + if(w != static_cast(mySrcR.w) || h != static_cast(mySrcR.h)) + { + mySrcR.w = w; mySrcR.h = h; + mySrcGUIR.setWidth(w); mySrcGUIR.setHeight(h); + return true; + } + return false; } - inline void setDstPosInternal(uInt32 x, uInt32 y) { - myDstR.x = x; myDstR.y = y; - myDstGUIR.moveTo(x, y); + inline bool setDstPosInternal(uInt32 x, uInt32 y) { + if(x != static_cast(myDstR.x) || y != static_cast(myDstR.y)) + { + myDstR.x = x; myDstR.y = y; + myDstGUIR.moveTo(x, y); + return true; + } + return false; } - inline void setDstSizeInternal(uInt32 w, uInt32 h) { - myDstR.w = w; myDstR.h = h; - myDstGUIR.setWidth(w); myDstGUIR.setHeight(h); + inline bool setDstSizeInternal(uInt32 w, uInt32 h) { + if(w != static_cast(myDstR.w) || h != static_cast(myDstR.h)) + { + myDstR.w = w; myDstR.h = h; + myDstGUIR.setWidth(w); myDstGUIR.setHeight(h); + return true; + } + return false; } void createSurface(uInt32 width, uInt32 height, const uInt32* data); @@ -103,7 +126,7 @@ class FBSurfaceSDL2 : public FBSurface {ScalingInterpolation::none}; SDL_Surface* mySurface{nullptr}; - SDL_Rect mySrcR{0, 0, 0, 0}, myDstR{0, 0, 0, 0}; + SDL_Rect mySrcR{-1, -1, -1, -1}, myDstR{-1, -1, -1, -1}; bool myIsVisible{true}; bool myIsStatic{false}; diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index ea851e6e6..71bddc289 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -292,11 +292,14 @@ class FBSurface These methods set the origin point and width/height for the specified service. They are defined as separate x/y and w/h methods since these items are sometimes set separately. + Other times they are set together, so we can use a Rect instead. */ virtual void setSrcPos(uInt32 x, uInt32 y) = 0; virtual void setSrcSize(uInt32 w, uInt32 h) = 0; + virtual void setSrcRect(const Common::Rect& r) = 0; virtual void setDstPos(uInt32 x, uInt32 y) = 0; virtual void setDstSize(uInt32 w, uInt32 h) = 0; + virtual void setDstRect(const Common::Rect& r) = 0; /** This method should be called to enable/disable showing the surface diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 84c4c9dac..6a0e96899 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -53,6 +53,18 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font { _flags = Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG; setTitle(title); + + // Create shading surface + uInt32 data = 0xff000000; + + _shadeSurface = instance.frameBuffer().allocateSurface( + 1, 1, ScalingInterpolation::sharp, &data); + + FBSurface::Attributes& attr = _shadeSurface->attributes(); + + attr.blending = true; + attr.blendalpha = 25; // darken background dialogs by 25% + _shadeSurface->applyAttributes(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -223,7 +235,7 @@ void Dialog::redraw(bool force) // Draw this dialog setPosition(); drawDialog(); - // full rendering is caused in dialog container + // full rendering is caused in dialog container } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -251,24 +263,7 @@ void Dialog::render() { cerr << " shade " << typeid(*this).name() << endl; - if(_shadeSurface == nullptr) - { - uInt32 data = 0xff000000; - - _shadeSurface = instance().frameBuffer().allocateSurface( - 1, 1, ScalingInterpolation::sharp, &data); - - FBSurface::Attributes& attr = _shadeSurface->attributes(); - - attr.blending = true; - attr.blendalpha = 25; // darken background dialogs by 25% - _shadeSurface->applyAttributes(); - } - - const Common::Rect& rect = _surface->dstRect(); - _shadeSurface->setDstPos(rect.x(), rect.y()); - _shadeSurface->setDstSize(rect.w(), rect.h()); - + _shadeSurface->setDstRect(_surface->dstRect()); _shadeSurface->render(); } } diff --git a/src/libretro/FBSurfaceLIBRETRO.hxx b/src/libretro/FBSurfaceLIBRETRO.hxx index 3918ff673..f6bf3320b 100644 --- a/src/libretro/FBSurfaceLIBRETRO.hxx +++ b/src/libretro/FBSurfaceLIBRETRO.hxx @@ -44,8 +44,11 @@ class FBSurfaceLIBRETRO : public FBSurface const Common::Rect& dstRect() const override { return myDstGUIR; } void setSrcPos(uInt32 x, uInt32 y) override { } void setSrcSize(uInt32 w, uInt32 h) override { } + void setSrcRect(const Common::Rect& r) override { } void setDstPos(uInt32 x, uInt32 y) override { } void setDstSize(uInt32 w, uInt32 h) override { } + void setDstRect(const Common::Rect& r) override { } + void setVisible(bool visible) override { } void translateCoords(Int32& x, Int32& y) const override { } From a65e6eab99066fccf1dd062a758e63973202afb8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 15 Nov 2020 08:59:18 +0100 Subject: [PATCH 194/263] fixed garbage in fullscreen mode fixed breakpoints flickering in RomListWidget fixed palette update in VideoAudioDialog --- src/debugger/gui/RomListWidget.cxx | 2 ++ src/gui/DialogContainer.cxx | 4 ++++ src/gui/VideoAudioDialog.cxx | 9 +++++++++ 3 files changed, 15 insertions(+) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 3504b2b37..473df388e 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -491,6 +491,8 @@ void RomListWidget::drawWidget(bool hilite) checkBreakPoint(dlist[pos].address, instance().debugger().cartDebug().getBank(dlist[pos].address))); myCheckList[i]->setDirty(); + // draw immediately, because chain order is not deterministic + myCheckList[i]->draw(); // Draw highlighted item in a frame if(_highlightedItem == pos) diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index e7fb0b81d..0f7713d0d 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -122,6 +122,10 @@ void DialogContainer::render() if(myDialogStack.empty()) return; + // Make sure we start in a clean state (with zero'ed buffers) + if(!myOSystem.eventHandler().inTIAMode()) + myOSystem.frameBuffer().clear(); + cerr << "full re-render " << typeid(*this).name() << endl; // Make sure we start in a clean state (with zero'ed buffers) diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index ba141cbeb..86db273b9 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -959,7 +959,16 @@ void VideoAudioDialog::handlePaletteUpdate() instance().frameBuffer().tiaSurface().paletteHandler().setAdjustables(paletteAdj); if(instance().hasConsole()) + { instance().frameBuffer().tiaSurface().paletteHandler().setPalette(); + + constexpr int NUM_LUMA = 8; + constexpr int NUM_CHROMA = 16; + + for(int idx = 0; idx < NUM_CHROMA; ++idx) + for(int lum = 0; lum < NUM_LUMA; ++lum) + myColor[idx][lum]->setDirty(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From ccdd167fca19ff8d4f4cac800f2d8154a19cf7e1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 15 Nov 2020 11:03:55 +0100 Subject: [PATCH 195/263] removed duplicate _editMode variable fixed missing redraws when StringListWidgets gain focus prevent focus for disabled widget --- src/gui/Dialog.cxx | 4 ++-- src/gui/DialogContainer.cxx | 6 +----- src/gui/EditableWidget.cxx | 2 -- src/gui/ListWidget.cxx | 2 ++ src/gui/ListWidget.hxx | 1 - src/gui/OptionsDialog.hxx | 2 +- src/gui/StringListWidget.hxx | 3 +++ 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 6a0e96899..18dd20cbf 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -361,7 +361,7 @@ void Dialog::setFocus(Widget* w) { // If the click occured inside a widget which is not the currently // focused one, change the focus to that widget. - if(w && w != _focusedWidget && w->wantsFocus()) + if(w && w != _focusedWidget && w->wantsFocus() && w->isEnabled()) { // Redraw widgets for new focus _focusedWidget = Widget::setFocusForChain(this, getFocusList(), w, 0); @@ -427,10 +427,10 @@ void Dialog::drawDialog() FBSurface& s = surface(); + cerr << endl << "d"; if(isDirty()) { //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; - cerr << "d"; if(clearsBackground()) { diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 0f7713d0d..fcdac91a9 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -122,10 +122,6 @@ void DialogContainer::render() if(myDialogStack.empty()) return; - // Make sure we start in a clean state (with zero'ed buffers) - if(!myOSystem.eventHandler().inTIAMode()) - myOSystem.frameBuffer().clear(); - cerr << "full re-render " << typeid(*this).name() << endl; // Make sure we start in a clean state (with zero'ed buffers) @@ -174,7 +170,7 @@ void DialogContainer::removeDialog() { if(!myDialogStack.empty()) { - cerr << "remove dialog" << endl; + cerr << "remove dialog " << typeid(*myDialogStack.top()).name() << endl; myDialogStack.pop(); // Inform the frame buffer that it has to render all surfaces diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 3e86ea947..d6c35fa55 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -100,8 +100,6 @@ void EditableWidget::receivedFocusWidget() { _caretTimer = 0; _caretEnabled = true; - - Widget::receivedFocusWidget(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ListWidget.cxx b/src/gui/ListWidget.cxx index d8b0bc458..1cf6c7e0d 100644 --- a/src/gui/ListWidget.cxx +++ b/src/gui/ListWidget.cxx @@ -36,6 +36,8 @@ ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font, _textcolor = kTextColor; _textcolorhi = kTextColor; + _editMode = false; + _cols = w / _fontWidth; _rows = h / _lineHeight; diff --git a/src/gui/ListWidget.hxx b/src/gui/ListWidget.hxx index 96d4f036c..1fba03f01 100644 --- a/src/gui/ListWidget.hxx +++ b/src/gui/ListWidget.hxx @@ -99,7 +99,6 @@ class ListWidget : public EditableWidget int _currentPos{0}; int _selectedItem{-1}; int _highlightedItem{-1}; - bool _editMode{false}; bool _useScrollbar{true}; ScrollBarWidget* _scrollBar{nullptr}; diff --git a/src/gui/OptionsDialog.hxx b/src/gui/OptionsDialog.hxx index 55d4d4b0d..bd13c3f37 100644 --- a/src/gui/OptionsDialog.hxx +++ b/src/gui/OptionsDialog.hxx @@ -52,7 +52,7 @@ class OptionsDialog : public Dialog void handleCommand(CommandSender* sender, int cmd, int data, int id) override; private: - unique_ptr myVideoDialog; + unique_ptr myVideoDialog; unique_ptr myEmulationDialog; unique_ptr myInputDialog; unique_ptr myUIDialog; diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx index eed279aeb..ee3b56e97 100644 --- a/src/gui/StringListWidget.hxx +++ b/src/gui/StringListWidget.hxx @@ -35,6 +35,9 @@ class StringListWidget : public ListWidget protected: void handleMouseEntered() override; void handleMouseLeft() override; + // display depends on _hasFocus so we have to redraw when focus changes + void receivedFocusWidget() override { setDirty(); } + void lostFocusWidget() override { setDirty(); } void drawWidget(bool hilite) override; Common::Rect getEditRect() const override; From f4b23967975d643e8f8ffd89b07a5125aaa2aab4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 15 Nov 2020 16:41:01 +0100 Subject: [PATCH 196/263] attempt to fix 'shifting' dialogs (OptionsDialog) --- src/emucore/EventHandler.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 7d241101e..5eced0d94 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -2288,6 +2288,7 @@ void EventHandler::enterMenuMode(EventHandlerState state) void EventHandler::leaveMenuMode() { #ifdef GUI_SUPPORT + myOverlay->removeDialog(); // remove the base dialog from dialog stack setState(EventHandlerState::EMULATION); myOSystem.sound().mute(false); #endif From c3530863b5b4e5639aaa52bc359cccf296773966 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 15 Nov 2020 15:16:06 -0330 Subject: [PATCH 197/263] Some simplifications to Point/Size/Rect classes. --- src/common/Rect.hxx | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/common/Rect.hxx b/src/common/Rect.hxx index faf6677b6..708de9d86 100644 --- a/src/common/Rect.hxx +++ b/src/common/Rect.hxx @@ -44,8 +44,8 @@ struct Point if(c != 'x') x = y = 0; } - bool operator==(const Point & p) const { return x == p.x && y == p.y; } - bool operator!=(const Point & p) const { return x != p.x || y != p.y; } + bool operator==(const Point& p) const { return x == p.x && y == p.y; } + bool operator!=(const Point& p) const { return !(*this == p); } friend ostream& operator<<(ostream& os, const Point& p) { os << p.x << "x" << p.y; @@ -75,11 +75,11 @@ struct Size } bool operator==(const Size& s) const { return w == s.w && h == s.h; } - bool operator!=(const Size& s) const { return w != s.w || h != s.h; } - bool operator<(const Size& s) const { return w < s.w && h < s.h; } - bool operator<=(const Size& s) const { return w <= s.w && h <= s.h; } - bool operator>(const Size& s) const { return w > s.w || h > s.h; } - bool operator>=(const Size& s) const { return w >= s.w || h >= s.h; } + bool operator< (const Size& s) const { return w < s.w && h < s.h; } + bool operator> (const Size& s) const { return w > s.w || h > s.h; } + bool operator!=(const Size& s) const { return !(*this == s); } + bool operator<=(const Size& s) const { return !(*this > s); } + bool operator>=(const Size& s) const { return !(*this < s); } friend ostream& operator<<(ostream& os, const Size& s) { os << s.w << "x" << s.h; @@ -175,6 +175,11 @@ struct Rect return r.left != x || r.top != y; } + bool operator==(const Rect& r) const { + return top == r.top && left == r.left && bottom == r.bottom && right == r.right; + } + bool operator!=(const Rect& r) const { return !(*this == r); } + friend ostream& operator<<(ostream& os, const Rect& r) { os << r.point() << "," << r.size(); return os; From 7144ff496493248b2306e43324d291cacd5f9d7b Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sun, 15 Nov 2020 19:55:35 +0100 Subject: [PATCH 198/263] Enable rtti in makefile. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 168ae178d..021e802dc 100644 --- a/Makefile +++ b/Makefile @@ -48,11 +48,11 @@ endif CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter ifdef HAVE_GCC - CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 + CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 -frtti endif ifdef HAVE_CLANG - CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 + CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 -frtti endif ifdef CLANG_WARNINGS From d9e23fd9ebdfe94d76a3196413b5304b4b1fb007 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sun, 15 Nov 2020 23:16:26 +0100 Subject: [PATCH 199/263] Remove overkill. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 021e802dc..90279a56a 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ ifdef HAVE_GCC endif ifdef HAVE_CLANG - CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 -frtti + CXXFLAGS+= -Wno-multichar -Wunused -frtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 endif ifdef CLANG_WARNINGS From 03311a4b76b6b733798cf74ed5b161086c44b653 Mon Sep 17 00:00:00 2001 From: cd-w Date: Sun, 15 Nov 2020 15:26:03 -0800 Subject: [PATCH 200/263] Increase sample size from 2K to 512K for CDFJ+ --- src/emucore/CartCDF.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 93e330c39..43c7290ac 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -277,7 +277,7 @@ uInt8 CartridgeCDF::peek(uInt16 address) if DIGITAL_AUDIO_ON { // retrieve packed sample (max size is 2K, or 4K of unpacked data) - uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> 21); + uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> 13); // get sample value from ROM or RAM if (sampleaddress < 0x00080000) @@ -288,7 +288,7 @@ uInt8 CartridgeCDF::peek(uInt16 address) peekvalue = 0; // make sure current volume value is in the lower nybble - if ((myMusicCounters[0] & (1<<20)) == 0) + if ((myMusicCounters[0] & (1<<12)) == 0) peekvalue >>= 4; peekvalue &= 0x0f; } From b4d0be6461eb3994ddbe88ff7d0412290bc30b91 Mon Sep 17 00:00:00 2001 From: cd-w Date: Sun, 15 Nov 2020 15:36:23 -0800 Subject: [PATCH 201/263] Fix audio changes to be compatible with CDF/CDFJ --- src/emucore/CartCDF.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 43c7290ac..ae06bdc05 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -277,7 +277,8 @@ uInt8 CartridgeCDF::peek(uInt16 address) if DIGITAL_AUDIO_ON { // retrieve packed sample (max size is 2K, or 4K of unpacked data) - uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> 13); + + uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> (isCDFJplus() ? 13 : 21)); // get sample value from ROM or RAM if (sampleaddress < 0x00080000) @@ -288,7 +289,7 @@ uInt8 CartridgeCDF::peek(uInt16 address) peekvalue = 0; // make sure current volume value is in the lower nybble - if ((myMusicCounters[0] & (1<<12)) == 0) + if ((myMusicCounters[0] & (1<<(isCDFJplus() ? 12 : 20))) == 0) peekvalue >>= 4; peekvalue &= 0x0f; } From 120c3062864f208ddbb2f385e50deeef3dbbcd1b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 16 Nov 2020 12:26:01 +0100 Subject: [PATCH 202/263] added initial tool tip functionality removed duplicate _editMode in DataGridWidget --- src/debugger/gui/DataGridWidget.cxx | 1 + src/debugger/gui/DataGridWidget.hxx | 1 - src/gui/Dialog.cxx | 8 +++ src/gui/Dialog.hxx | 4 +- src/gui/EditTextWidget.cxx | 1 + src/gui/LauncherDialog.cxx | 3 ++ src/gui/ToolTip.cxx | 79 ++++++++++++++++++++++++----- src/gui/ToolTip.hxx | 60 ++++++++++++++++++---- src/gui/Widget.cxx | 12 ++++- src/gui/Widget.hxx | 4 +- 10 files changed, 147 insertions(+), 26 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 32358dd05..877d96c6a 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -45,6 +45,7 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font, _base(base) { _flags = Widget::FLAG_ENABLED | Widget::FLAG_RETAIN_FOCUS | Widget::FLAG_WANTS_RAWDATA; + _editMode = false; // Make sure all lists contain some default values _hiliteList.clear(); diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index 114097b01..82eca7fbc 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -128,7 +128,6 @@ class DataGridWidget : public EditableWidget BoolArray _changedList; BoolArray _hiliteList; - bool _editMode{false}; int _selectedItem{0}; StellaKey _currentKeyDown{KBDK_UNKNOWN}; string _backupString; diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 18dd20cbf..f58d98536 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -27,6 +27,7 @@ #include "Dialog.hxx" #include "Widget.hxx" #include "TabWidget.hxx" +#include "ToolTip.hxx" #include "ContextMenu.hxx" #include "PopUpWidget.hxx" @@ -65,6 +66,8 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font attr.blending = true; attr.blendalpha = 25; // darken background dialogs by 25% _shadeSurface->applyAttributes(); + + _toolTip = make_unique(instance, *this, font); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -266,6 +269,8 @@ void Dialog::render() _shadeSurface->setDstRect(_surface->dstRect()); _shadeSurface->render(); } + + _toolTip->render(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -588,6 +593,9 @@ void Dialog::handleMouseMoved(int x, int y) { Widget* w; + // Update mouse coordinates for tooltips + _toolTip->update(x, y); + if(_focusedWidget && !_dragWidget) { w = _focusedWidget; diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 0d0c57bc3..b92b8e383 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -26,6 +26,7 @@ class OSystem; class DialogContainer; class TabWidget; class CommandSender; +class ToolTip; #include "Stack.hxx" #include "Widget.hxx" @@ -122,6 +123,7 @@ class Dialog : public GuiObject */ bool shouldResize(uInt32& w, uInt32& h) const; + ToolTip& tooltip() { return *_toolTip; }; //bool enableToolTip(); //void showToolTip(int x, int y); //void hideToolTip(); @@ -203,7 +205,7 @@ class Dialog : public GuiObject string _title; int _th{0}; int _layer{0}; - int _toolTipTimer{0}; + unique_ptr _toolTip; Common::FixedStack> mySurfaceStack; diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index c818f3cf0..d3e4587a5 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -18,6 +18,7 @@ #include "OSystem.hxx" #include "FBSurface.hxx" #include "Dialog.hxx" +#include "ToolTip.hxx" #include "Font.hxx" #include "EditTextWidget.hxx" diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 8018bcb44..abae25742 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -120,12 +120,14 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Show the filter input field xpos -= fwidth + LBL_GAP; myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwidth, lineHeight, ""); + myPattern->setToolTip("Enter a filter text to reduce file list."); // Show the "Filter" label xpos -= lwidth3 + LBL_GAP; new StaticTextWidget(this, font, xpos, ypos, lblFilter); // Show the checkbox for all files xpos -= lwidth2 + LBL_GAP * 3; myAllFiles = new CheckboxWidget(this, font, xpos, ypos, lblAllFiles, kAllfilesCmd); + myAllFiles->setToolTip("Uncheck to show ROM files only."); wid.push_back(myAllFiles); wid.push_back(myPattern); } @@ -178,6 +180,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, #ifndef BSPF_MACOS myStartButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 0) / 4, buttonHeight, "Select", kLoadROMCmd); + myStartButton->setToolTip("Start emulation of selected ROM."); wid.push_back(myStartButton); xpos += (buttonWidth + 0) / 4 + BUTTON_GAP; diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 53cbea0c3..72ecb47ad 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -16,25 +16,80 @@ //============================================================================ #include "OSystem.hxx" +#include "FrameBuffer.hxx" +#include "FBSurface.hxx" + #include "Font.hxx" #include "Dialog.hxx" -#include "DialogContainer.hxx" +#include "Widget.hxx" #include "ToolTip.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ToolTip::ToolTip(OSystem& instance, DialogContainer& parent, - const GUI::Font& font) - : Dialog(instance, parent, font) +ToolTip::ToolTip(OSystem& instance, Dialog& dialog, const GUI::Font& font) + : myDialog(dialog), + myFont(font) { - const int lineHeight = font.getLineHeight(), - fontWidth = font.getMaxCharWidth(), - fontHeight = font.getFontHeight(), - buttonWidth = font.getStringWidth("Previous") + fontWidth * 2.5, - buttonHeight = font.getLineHeight() * 1.25; - const int VBORDER = fontHeight / 2; - const int HBORDER = fontWidth * 1.25; - const int VGAP = fontHeight / 4; + const int fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(); + + myTextXOfs = fontHeight < 24 ? 5 : 8; //3 : 5; + myWidth = myTextXOfs * 2 + fontWidth * MAX_LEN; + myHeight = fontHeight + TEXT_Y_OFS * 2; + mySurface = instance.frameBuffer().allocateSurface(myWidth, myHeight); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::request(Widget* widget) +{ + if(myWidget != widget) + { + release(); + } + if(myTimer == DELAY_TIME) + { + string text = widget->getToolTip(); + int width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); + int yOffset = 20; // TODO: query cursor height + + myWidget = widget; + // TODO: limit to app or screen size + mySurface->setSrcSize(width, myHeight); + mySurface->setDstSize(width, myHeight); + mySurface->setDstPos(myPos.x, myPos.y + yOffset); + + mySurface->frameRect(0, 0, width, myHeight, kColor); + mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); + mySurface->drawString(myFont, text, myTextXOfs, TEXT_Y_OFS, + width - myTextXOfs * 2, myHeight - TEXT_Y_OFS * 2, kTextColor); + myDialog.setDirtyChain(); + } + myTimer++; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::release() +{ + if(myWidget != nullptr) + { + myTimer = 0; + myWidget = nullptr; + myDialog.setDirtyChain(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::render() +{ + if(myWidget != nullptr) + mySurface->render(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::update(int x, int y) +{ + if(myWidget != nullptr && x != myPos.x || y != myPos.y) + release(); + myPos.x = x; + myPos.y = y; +} diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index 2066bd3df..7ba4dc044 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -18,22 +18,62 @@ #ifndef TOOL_TIP_HXX #define TOOL_TIP_HXX -class OSystem; -class DialogContainer; - /** * Class for providing tooltip functionality * * @author Thomas Jentzsch */ -class ToolTip : public Dialog -{ - public: - public: - ToolTip(OSystem& instance, DialogContainer& parent, - const GUI::Font& font); - ~ToolTip() override = default; +class OSystem; +class FBSurface; +class Widget; + +#include "Rect.hxx" + +class ToolTip +{ +public: + // Maximum tooltip length + static constexpr int MAX_LEN = 60; + + ToolTip(OSystem& instance, Dialog& dialog, const GUI::Font& font); + ~ToolTip() = default; + + /** + Request a tooltip display + */ + void request(Widget* widget); + + + /** + Hide an existing tooltip (if displayed) + */ + void release(); + + /** + Update with current mouse position + */ + void update(int x, int y); + + /* + Render the tooltip + */ + void render(); + +private: + static constexpr uInt32 DELAY_TIME = 45; // display delay + static constexpr int TEXT_Y_OFS = 2; + + const GUI::Font& myFont; + Dialog& myDialog; + + Widget* myWidget{nullptr}; + uInt32 myTimer{0}; + Common::Point myPos; + int myWidth{0}; + int myHeight{0}; + int myTextXOfs{0}; + shared_ptr mySurface; }; #endif diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index f33d27146..f37f8840c 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -21,6 +21,7 @@ #include "bspf.hxx" #include "Command.hxx" #include "Dialog.hxx" +#include "ToolTip.hxx" #include "FBSurface.hxx" #include "GuiObject.hxx" #include "OSystem.hxx" @@ -74,7 +75,8 @@ void Widget::tick() { if(isEnabled()) { - //if(_hasFocus && hasToolTip()) + if(isHighlighted() && hasToolTip()) + dialog().tooltip().request(this); //{ // if(dialog().enableToolTip()) // dialog().showToolTip(10, 10); @@ -208,6 +210,14 @@ void Widget::setEnabled(bool e) else clearFlags(Widget::FLAG_ENABLED); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setToolTip(const string& text) +{ + assert(text.length() <= ToolTip::MAX_LEN); + + _toolTipText = text; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Widget* Widget::findWidgetInChain(Widget* w, int x, int y) { diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 5ee8ef0b1..98e36863f 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -87,6 +87,7 @@ class Widget : public GuiObject bool isEnabled() const { return _flags & FLAG_ENABLED; } bool isVisible() const override { return !(_flags & FLAG_INVISIBLE); } + bool isHighlighted() const { return _flags & FLAG_HILITED; } virtual bool wantsFocus() const { return _flags & FLAG_RETAIN_FOCUS; } bool wantsTab() const { return _flags & FLAG_WANTS_TAB; } bool wantsRaw() const { return _flags & FLAG_WANTS_RAWDATA; } @@ -102,7 +103,8 @@ class Widget : public GuiObject void setBGColorHi(ColorId color) { _bgcolorhi = color; setDirty(); } void setShadowColor(ColorId color) { _shadowcolor = color; setDirty(); } - void setToolTip(const string& text) { _toolTipText = text; } + void setToolTip(const string& text); + const string& getToolTip() const { return _toolTipText; } bool hasToolTip() const { return !_toolTipText.empty(); } virtual void loadConfig() { } From f55931f2e002b49002e42736de173427fca02366 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 16 Nov 2020 09:50:50 -0330 Subject: [PATCH 203/263] Fix warning, and add ToolTip to Linux build. --- src/gui/Dialog.hxx | 2 +- src/gui/module.mk | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index b92b8e383..b134d7d37 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -123,7 +123,7 @@ class Dialog : public GuiObject */ bool shouldResize(uInt32& w, uInt32& h) const; - ToolTip& tooltip() { return *_toolTip; }; + ToolTip& tooltip() { return *_toolTip; } //bool enableToolTip(); //void showToolTip(int x, int y); //void hideToolTip(); diff --git a/src/gui/module.mk b/src/gui/module.mk index a2f8489fd..4be9b66ad 100644 --- a/src/gui/module.mk +++ b/src/gui/module.mk @@ -49,6 +49,7 @@ MODULE_OBJS := \ src/gui/TimeLineWidget.o \ src/gui/TimeMachineDialog.o \ src/gui/TimeMachine.o \ + src/gui/ToolTip.o \ src/gui/UndoHandler.o \ src/gui/UIDialog.o \ src/gui/VideoAudioDialog.o \ From b68a6fa600826817bd27ab0d61014d78d6a653f7 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 16 Nov 2020 17:41:24 +0100 Subject: [PATCH 204/263] fixed tool tips for HiDPI added tool tip repositioning if exceeding surface --- src/gui/ToolTip.cxx | 34 +++++++++++++++++++++++++--------- src/gui/ToolTip.hxx | 14 ++++++++------ src/gui/VideoAudioDialog.cxx | 1 + 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 72ecb47ad..30100009a 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -16,11 +16,10 @@ //============================================================================ #include "OSystem.hxx" +#include "Dialog.hxx" +#include "Font.hxx" #include "FrameBuffer.hxx" #include "FBSurface.hxx" - -#include "Font.hxx" -#include "Dialog.hxx" #include "Widget.hxx" #include "ToolTip.hxx" @@ -36,7 +35,8 @@ ToolTip::ToolTip(OSystem& instance, Dialog& dialog, const GUI::Font& font) myTextXOfs = fontHeight < 24 ? 5 : 8; //3 : 5; myWidth = myTextXOfs * 2 + fontWidth * MAX_LEN; myHeight = fontHeight + TEXT_Y_OFS * 2; - mySurface = instance.frameBuffer().allocateSurface(myWidth, myHeight); + mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight); + myScale = myDialog.instance().frameBuffer().hidpiScaleFactor(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -48,15 +48,31 @@ void ToolTip::request(Widget* widget) } if(myTimer == DELAY_TIME) { + const uInt32 VGAP = 1; + const uInt32 hCursor = 19; // TODO: query cursor height string text = widget->getToolTip(); - int width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); - int yOffset = 20; // TODO: query cursor height + uInt32 width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); + // Note: These include HiDPI scaling: + const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect(); + const Common::Rect dialogRect = myDialog.surface().dstRect(); + // Limit to app or screen size and adjust position + const Int32 xAbs = myPos.x + dialogRect.x() / myScale; + const uInt32 yAbs = myPos.y + dialogRect.y() / myScale; + Int32 x = std::min(xAbs, Int32(imageRect.w() / myScale - width)); + const uInt32 y = (yAbs + myHeight + hCursor > imageRect.h() / myScale) + ? yAbs - myHeight - VGAP + : yAbs + hCursor / myScale + VGAP; + + if(x < 0) + { + x = 0; + width = imageRect.w() / myScale; + } myWidget = widget; - // TODO: limit to app or screen size mySurface->setSrcSize(width, myHeight); - mySurface->setDstSize(width, myHeight); - mySurface->setDstPos(myPos.x, myPos.y + yOffset); + mySurface->setDstSize(width * myScale, myHeight * myScale); + mySurface->setDstPos(x * myScale, y * myScale); mySurface->frameRect(0, 0, width, myHeight, kColor); mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index 7ba4dc044..d3164a09d 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -25,8 +25,9 @@ */ class OSystem; -class FBSurface; +class Dialog; class Widget; +class FBSurface; #include "Rect.hxx" @@ -34,7 +35,7 @@ class ToolTip { public: // Maximum tooltip length - static constexpr int MAX_LEN = 60; + static constexpr uInt32 MAX_LEN = 80; ToolTip(OSystem& instance, Dialog& dialog, const GUI::Font& font); ~ToolTip() = default; @@ -64,15 +65,16 @@ private: static constexpr uInt32 DELAY_TIME = 45; // display delay static constexpr int TEXT_Y_OFS = 2; - const GUI::Font& myFont; Dialog& myDialog; + const GUI::Font& myFont; Widget* myWidget{nullptr}; uInt32 myTimer{0}; Common::Point myPos; - int myWidth{0}; - int myHeight{0}; - int myTextXOfs{0}; + uInt32 myWidth{0}; + uInt32 myHeight{0}; + uInt32 myScale{1}; + uInt32 myTextXOfs{0}; shared_ptr mySurface; }; diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 86db273b9..8d2c3be6d 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -122,6 +122,7 @@ void VideoAudioDialog::addDisplayTab() myRenderer = new PopUpWidget(myTab, _font, xpos, ypos, pwidth, lineHeight, instance().frameBuffer().supportedRenderers(), "Renderer ", lwidth); + myRenderer->setToolTip("Select renderer used for displaying screen."); wid.push_back(myRenderer); const int swidth = myRenderer->getWidth() - lwidth; ypos += lineHeight + VGAP; From c6068104d937a573abd7269decc318c7268c438b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 16 Nov 2020 18:59:01 +0100 Subject: [PATCH 205/263] added a separate flag for mouse focus --- src/debugger/gui/DataGridWidget.cxx | 14 --------- src/debugger/gui/DataGridWidget.hxx | 2 -- src/debugger/gui/RomListWidget.cxx | 14 --------- src/debugger/gui/RomListWidget.hxx | 2 -- src/debugger/gui/TiaZoomWidget.cxx | 10 +----- src/debugger/gui/TiaZoomWidget.hxx | 3 -- src/debugger/gui/ToggleWidget.cxx | 14 --------- src/debugger/gui/ToggleWidget.hxx | 2 -- src/gui/CheckListWidget.cxx | 14 --------- src/gui/CheckListWidget.hxx | 4 --- src/gui/EditTextWidget.cxx | 14 --------- src/gui/EditTextWidget.hxx | 2 -- src/gui/GuiObject.hxx | 3 +- src/gui/PopUpWidget.cxx | 14 --------- src/gui/PopUpWidget.hxx | 2 -- src/gui/ScrollBarWidget.cxx | 10 +----- src/gui/ScrollBarWidget.hxx | 1 - src/gui/StringListWidget.cxx | 14 --------- src/gui/StringListWidget.hxx | 2 -- src/gui/TabWidget.cxx | 14 --------- src/gui/TabWidget.hxx | 4 +-- src/gui/Widget.cxx | 48 +++++++++-------------------- src/gui/Widget.hxx | 9 ++---- 23 files changed, 24 insertions(+), 192 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 877d96c6a..63c637ecd 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -240,20 +240,6 @@ void DataGridWidget::setRange(int lower, int upper) _upperBound = std::min(1 << _bits, upper); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void DataGridWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void DataGridWidget::handleMouseLeft() -{ - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DataGridWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) { diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index 82eca7fbc..9096879f3 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -101,8 +101,6 @@ class DataGridWidget : public EditableWidget void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; void handleMouseWheel(int x, int y, int direction) override; - void handleMouseEntered() override; - void handleMouseLeft() override; bool handleText(char text) override; bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyUp(StellaKey key, StellaMod mod) override; diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 473df388e..58d392ee9 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -284,20 +284,6 @@ void RomListWidget::handleMouseWheel(int x, int y, int direction) myScrollBar->handleMouseWheel(x, y, direction); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomListWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RomListWidget::handleMouseLeft() -{ - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool RomListWidget::handleText(char text) { diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx index ec557f606..37473d12f 100644 --- a/src/debugger/gui/RomListWidget.hxx +++ b/src/debugger/gui/RomListWidget.hxx @@ -60,8 +60,6 @@ class RomListWidget : public EditableWidget void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; void handleMouseWheel(int x, int y, int direction) override; - void handleMouseEntered() override; - void handleMouseLeft() override; bool handleText(char text) override; bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyUp(StellaKey key, StellaMod mod) override; diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx index 759e95516..0895c51a8 100644 --- a/src/debugger/gui/TiaZoomWidget.cxx +++ b/src/debugger/gui/TiaZoomWidget.cxx @@ -178,19 +178,11 @@ void TiaZoomWidget::handleMouseMoved(int x, int y) } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void TiaZoomWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaZoomWidget::handleMouseLeft() { - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); myMouseMoving = false; + Widget::handleMouseLeft(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/TiaZoomWidget.hxx b/src/debugger/gui/TiaZoomWidget.hxx index d4d3a9835..7169645bf 100644 --- a/src/debugger/gui/TiaZoomWidget.hxx +++ b/src/debugger/gui/TiaZoomWidget.hxx @@ -34,9 +34,6 @@ class TiaZoomWidget : public Widget, public CommandSender void loadConfig() override; void setPos(int x, int y); - protected: - void handleMouseEntered() override; - private: void zoom(int level); void recalc(); diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index ea3253d8a..4f9ddccfa 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -40,20 +40,6 @@ ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font, Widget::FLAG_WANTS_RAWDATA; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToggleWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToggleWidget::handleMouseLeft() -{ - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) { diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index 67777a13a..0d6759467 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -68,8 +68,6 @@ class ToggleWidget : public Widget, public CommandSender void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; - void handleMouseEntered() override; - void handleMouseLeft() override; bool handleKeyDown(StellaKey key, StellaMod mod) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/CheckListWidget.cxx b/src/gui/CheckListWidget.cxx index 079989376..6d80fcc07 100644 --- a/src/gui/CheckListWidget.cxx +++ b/src/gui/CheckListWidget.cxx @@ -46,20 +46,6 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font, } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CheckListWidget::handleMouseEntered() -{ - setFlags(Widget::FLAG_HILITED); - setDirty(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CheckListWidget::handleMouseLeft() -{ - clearFlags(Widget::FLAG_HILITED); - setDirty(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CheckListWidget::setList(const StringList& list, const BoolArray& state) { diff --git a/src/gui/CheckListWidget.hxx b/src/gui/CheckListWidget.hxx index 625875a9d..2ebec0d5d 100644 --- a/src/gui/CheckListWidget.hxx +++ b/src/gui/CheckListWidget.hxx @@ -42,10 +42,6 @@ class CheckListWidget : public ListWidget bool getState(int line); bool getSelectedState() { return getState(_selectedItem); } - protected: - void handleMouseEntered() override; - void handleMouseLeft() override; - private: bool handleEvent(Event::Type e) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index d3e4587a5..61785bd78 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -49,20 +49,6 @@ void EditTextWidget::setText(const string& str, bool changed) _changed = changed; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditTextWidget::handleMouseEntered() -{ - if(isEnabled() && isEditable()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditTextWidget::handleMouseLeft() -{ - if(isEnabled() && isEditable()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) { diff --git a/src/gui/EditTextWidget.hxx b/src/gui/EditTextWidget.hxx index fe063e042..e7c21beff 100644 --- a/src/gui/EditTextWidget.hxx +++ b/src/gui/EditTextWidget.hxx @@ -54,8 +54,6 @@ class EditTextWidget : public EditableWidget Common::Rect getEditRect() const override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; - void handleMouseEntered() override; - void handleMouseLeft() override; protected: string _backupString; diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index c276698f8..490df4344 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -52,7 +52,8 @@ class GuiObject : public CommandReceiver FLAG_RETAIN_FOCUS = 1 << 6, FLAG_WANTS_TAB = 1 << 7, FLAG_WANTS_RAWDATA = 1 << 8, - FLAG_NOBG = 1 << 9 + FLAG_NOBG = 1 << 9, + FLAG_MOUSE_FOCUS = 1 << 10 }; public: diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index ccf6af1aa..06c726779 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -158,20 +158,6 @@ void PopUpWidget::handleMouseWheel(int x, int y, int direction) } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PopUpWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PopUpWidget::handleMouseLeft() -{ - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool PopUpWidget::handleEvent(Event::Type e) { diff --git a/src/gui/PopUpWidget.hxx b/src/gui/PopUpWidget.hxx index deb0af30c..babe28686 100644 --- a/src/gui/PopUpWidget.hxx +++ b/src/gui/PopUpWidget.hxx @@ -70,8 +70,6 @@ class PopUpWidget : public EditableWidget protected: void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseWheel(int x, int y, int direction) override; - void handleMouseEntered() override; - void handleMouseLeft() override; bool handleEvent(Event::Type e) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/ScrollBarWidget.cxx b/src/gui/ScrollBarWidget.cxx index 04a99c732..73e89bc78 100644 --- a/src/gui/ScrollBarWidget.cxx +++ b/src/gui/ScrollBarWidget.cxx @@ -240,19 +240,11 @@ void ScrollBarWidget::checkBounds(int old_pos) } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ScrollBarWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ScrollBarWidget::handleMouseLeft() { _part = Part::None; - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); + Widget::handleMouseLeft(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ScrollBarWidget.hxx b/src/gui/ScrollBarWidget.hxx index 1d1b4c34a..0c29fde17 100644 --- a/src/gui/ScrollBarWidget.hxx +++ b/src/gui/ScrollBarWidget.hxx @@ -49,7 +49,6 @@ class ScrollBarWidget : public Widget, public CommandSender void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; void handleMouseMoved(int x, int y) override; bool handleMouseClicks(int x, int y, MouseButton b) override; - void handleMouseEntered() override; void handleMouseLeft() override; void setArrows(); diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 5032654e6..ad5f1e7ec 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -50,20 +50,6 @@ void StringListWidget::setList(const StringList& list) ListWidget::recalc(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void StringListWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void StringListWidget::handleMouseLeft() -{ - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StringListWidget::drawWidget(bool hilite) { diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx index ee3b56e97..ed5874b91 100644 --- a/src/gui/StringListWidget.hxx +++ b/src/gui/StringListWidget.hxx @@ -33,8 +33,6 @@ class StringListWidget : public ListWidget bool wantsFocus() const override { return true; } protected: - void handleMouseEntered() override; - void handleMouseLeft() override; // display depends on _hasFocus so we have to redraw when focus changes void receivedFocusWidget() override { setDirty(); } void lostFocusWidget() override { setDirty(); } diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx index 5e96338ab..28b383f6c 100644 --- a/src/gui/TabWidget.cxx +++ b/src/gui/TabWidget.cxx @@ -213,20 +213,6 @@ void TabWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void TabWidget::handleMouseEntered() -{ - //if(isEnabled()) - // setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void TabWidget::handleMouseLeft() -{ - //if(isEnabled()) - // clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TabWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { diff --git a/src/gui/TabWidget.hxx b/src/gui/TabWidget.hxx index 1f581df5c..141b29497 100644 --- a/src/gui/TabWidget.hxx +++ b/src/gui/TabWidget.hxx @@ -63,8 +63,8 @@ class TabWidget : public Widget, public CommandSender protected: void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; - void handleMouseEntered() override; - void handleMouseLeft() override; + void handleMouseEntered() override {} + void handleMouseLeft() override {} void handleCommand(CommandSender* sender, int cmd, int data, int id) override; bool handleEvent(Event::Type event) override; diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index f37f8840c..991207655 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -75,12 +75,8 @@ void Widget::tick() { if(isEnabled()) { - if(isHighlighted() && hasToolTip()) + if(hasMouseFocus() && hasToolTip()) dialog().tooltip().request(this); - //{ - // if(dialog().enableToolTip()) - // dialog().showToolTip(10, 10); - //} // Recursively tick widget and all child dialogs and widgets Widget* w = _firstWidget; @@ -181,6 +177,20 @@ void Widget::drawChain() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::handleMouseEntered() +{ + if(isEnabled()) + setFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::handleMouseLeft() +{ + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Widget::receivedFocus() { @@ -465,20 +475,6 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font, _bmh = bmh; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ButtonWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ButtonWidget::handleMouseLeft() -{ - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool ButtonWidget::handleEvent(Event::Type e) { @@ -576,20 +572,6 @@ CheckboxWidget::CheckboxWidget(GuiObject* boss, const GUI::Font& font, setFill(CheckboxWidget::FillType::Normal); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CheckboxWidget::handleMouseEntered() -{ - if(isEnabled()) - setFlags(Widget::FLAG_HILITED); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CheckboxWidget::handleMouseLeft() -{ - if(isEnabled()) - clearFlags(Widget::FLAG_HILITED); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CheckboxWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount) { diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 98e36863f..bf831a5eb 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -58,8 +58,8 @@ class Widget : public GuiObject virtual bool handleKeyUp(StellaKey key, StellaMod mod) { return false; } virtual void handleMouseDown(int x, int y, MouseButton b, int clickCount) { } virtual void handleMouseUp(int x, int y, MouseButton b, int clickCount) { } - virtual void handleMouseEntered() { } - virtual void handleMouseLeft() { } + virtual void handleMouseEntered(); + virtual void handleMouseLeft(); virtual void handleMouseMoved(int x, int y) { } virtual void handleMouseWheel(int x, int y, int direction) { } virtual bool handleMouseClicks(int x, int y, MouseButton b) { return false; } @@ -88,6 +88,7 @@ class Widget : public GuiObject bool isEnabled() const { return _flags & FLAG_ENABLED; } bool isVisible() const override { return !(_flags & FLAG_INVISIBLE); } bool isHighlighted() const { return _flags & FLAG_HILITED; } + bool hasMouseFocus() const { return _flags & FLAG_MOUSE_FOCUS; } virtual bool wantsFocus() const { return _flags & FLAG_RETAIN_FOCUS; } bool wantsTab() const { return _flags & FLAG_WANTS_TAB; } bool wantsRaw() const { return _flags & FLAG_WANTS_RAWDATA; } @@ -231,8 +232,6 @@ class ButtonWidget : public StaticTextWidget, public CommandSender bool handleMouseClicks(int x, int y, MouseButton b) override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; - void handleMouseEntered() override; - void handleMouseLeft() override; bool handleEvent(Event::Type event) override; void drawWidget(bool hilite) override; @@ -273,8 +272,6 @@ class CheckboxWidget : public ButtonWidget bool getState() const { return _state; } void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; - void handleMouseEntered() override; - void handleMouseLeft() override; static int boxSize(const GUI::Font& font) { From 004b34f51e5e61305cec92f90f335df73ce292b3 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 16 Nov 2020 20:00:51 +0100 Subject: [PATCH 206/263] fixed tool tip font for Launcher added a few more tool tips --- src/gui/LauncherDialog.cxx | 3 ++- src/gui/ToolTip.cxx | 5 +++-- src/gui/VideoAudioDialog.cxx | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index abae25742..93361b9f5 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -56,7 +56,8 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, int x, int y, int w, int h) - : Dialog(osystem, parent, x, y, w, h) + : Dialog(osystem, parent, osystem.frameBuffer().launcherFont(), "", + x, y, w, h) { myUseMinimalUI = instance().settings().getBool("minimal_ui"); diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 30100009a..82c0df10b 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -48,8 +48,10 @@ void ToolTip::request(Widget* widget) } if(myTimer == DELAY_TIME) { + myWidget = widget; + const uInt32 VGAP = 1; - const uInt32 hCursor = 19; // TODO: query cursor height + const uInt32 hCursor = 18; string text = widget->getToolTip(); uInt32 width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); // Note: These include HiDPI scaling: @@ -69,7 +71,6 @@ void ToolTip::request(Widget* widget) width = imageRect.w() / myScale; } - myWidget = widget; mySurface->setSrcSize(width, myHeight); mySurface->setDstSize(width * myScale, myHeight * myScale); mySurface->setDstPos(x * myScale, y * myScale); diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index 8d2c3be6d..d34f0a330 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -129,6 +129,7 @@ void VideoAudioDialog::addDisplayTab() // TIA interpolation myTIAInterpolate = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Interpolation "); + myTIAInterpolate->setToolTip("Blur the emulated display."); wid.push_back(myTIAInterpolate); ypos += lineHeight + VGAP * 4; @@ -146,12 +147,14 @@ void VideoAudioDialog::addDisplayTab() // FS stretch myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch"); + myUseStretch->setToolTip("Stretch the emulated display to fill the whole screen."); wid.push_back(myUseStretch); #ifdef ADAPTABLE_REFRESH_SUPPORT // Adapt refresh rate ypos += lineHeight + VGAP; myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate"); + myRefreshAdapt->setToolTip("Select the optimal display refresh rate for each ROM."); wid.push_back(myRefreshAdapt); #else myRefreshAdapt = nullptr; @@ -168,6 +171,7 @@ void VideoAudioDialog::addDisplayTab() // Aspect ratio correction ypos += lineHeight + VGAP * 4; myCorrectAspect = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Correct aspect ratio (*)"); + myCorrectAspect->setToolTip("Uncheck to disable real world aspect ratio correction."); wid.push_back(myCorrectAspect); // Vertical size @@ -177,6 +181,7 @@ void VideoAudioDialog::addDisplayTab() "V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true); myVSizeAdjust->setMinValue(-5); myVSizeAdjust->setMaxValue(5); myVSizeAdjust->setTickmarkIntervals(2); + myVSizeAdjust->setToolTip("Adapt vertical size to emulated TV display."); wid.push_back(myVSizeAdjust); From 99c0cd66bc94648b1a2ee741739a29cd127d3081 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 16 Nov 2020 23:50:10 +0100 Subject: [PATCH 207/263] added value tool tips to debugger (DataGridWiget, ToogleWidget) --- src/debugger/gui/CpuWidget.cxx | 4 ++-- src/debugger/gui/DataGridWidget.cxx | 17 +++++++++++++++++ src/debugger/gui/DataGridWidget.hxx | 3 +++ src/debugger/gui/ToggleWidget.cxx | 26 ++++++++++++++++++++++++++ src/debugger/gui/ToggleWidget.hxx | 3 +++ src/gui/Dialog.cxx | 2 +- src/gui/Dialog.hxx | 3 --- src/gui/ToolTip.cxx | 29 +++++++++++++++++++---------- src/gui/ToolTip.hxx | 11 ++++++----- src/gui/Widget.hxx | 8 ++++++-- 10 files changed, 83 insertions(+), 23 deletions(-) diff --git a/src/debugger/gui/CpuWidget.cxx b/src/debugger/gui/CpuWidget.cxx index 31f939f01..ea6fbb96f 100644 --- a/src/debugger/gui/CpuWidget.cxx +++ b/src/debugger/gui/CpuWidget.cxx @@ -109,10 +109,10 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n { new StaticTextWidget(boss, lfont, myCpuGridDecValue->getLeft() - fontWidth, ypos + row * lineHeight + 2, - lwidth - 2, fontHeight, "#"); + fontWidth, fontHeight, "#"); new StaticTextWidget(boss, lfont, myCpuGridBinValue->getLeft() - fontWidth, ypos + row * lineHeight + 2, - lwidth - 2, fontHeight, "%"); + fontWidth, fontHeight, "%"); } // Create a bitfield widget for changing the processor status diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 63c637ecd..f6898b6c8 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -570,6 +570,23 @@ void DataGridWidget::handleCommand(CommandSender* sender, int cmd, } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string DataGridWidget::getToolTip(int x, int y) const +{ + const int col = (x - getAbsX()) / _colWidth; + const int row = (y - getAbsY()) / _rowHeight; + const int pos = row * _cols + col; + const Int32 val = _valueList[pos]; + const string hex = Common::Base::toString(val, Common::Base::Fmt::_16); + const string dec = Common::Base::toString(val, Common::Base::Fmt::_10); + const string bin = Common::Base::toString(val, Common::Base::Fmt::_2); + ostringstream buf; + + // TODO: time leading spaces and zeroes + buf << "$" << hex << " = #" << dec << " = %" << bin; + return buf.str(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DataGridWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index 9096879f3..f50270f4f 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -84,6 +84,9 @@ class DataGridWidget : public EditableWidget void setCrossed(bool enable) { _crossGrid = enable; } + string getToolTip(int x = 0, int y = 0) const override; + bool hasToolTip() const override { return true; } + protected: void drawWidget(bool hilite) override; diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index 4f9ddccfa..346c51121 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -16,6 +16,7 @@ //============================================================================ #include "OSystem.hxx" +#include "Base.hxx" #include "StellaKeys.hxx" #include "Widget.hxx" #include "ToggleWidget.hxx" @@ -209,3 +210,28 @@ void ToggleWidget::handleCommand(CommandSender* sender, int cmd, } } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string ToggleWidget::getToolTip(int x, int y) const +{ + const int row = (y - getAbsY()) / _rowHeight; + const int pos = row * _cols;// +col; + Int32 val = 0; + + for(int col = 0; col < _cols; ++col) + { + val <<= 1; + val += _stateList[pos + col]; + } + + const string hex = Common::Base::toString(val, Common::Base::Fmt::_16); + const string dec = Common::Base::toString(val, Common::Base::Fmt::_10); + const string bin = Common::Base::toString(val, Common::Base::Fmt::_2); + ostringstream buf; + + // TODO: time leading spaces and zeroes + buf << "$" << hex << " = #" << dec << " = %" << bin; + return buf.str(); +} + + diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index 0d6759467..a671f53e9 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -46,6 +46,9 @@ class ToggleWidget : public Widget, public CommandSender void setEditable(bool editable) { _editable = editable; } bool isEditable() const { return _editable; } + string getToolTip(int x = 0, int y = 0) const override; + bool hasToolTip() const override { return true; } + protected: protected: diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index f58d98536..b9678182e 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -67,7 +67,7 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font attr.blendalpha = 25; // darken background dialogs by 25% _shadeSurface->applyAttributes(); - _toolTip = make_unique(instance, *this, font); + _toolTip = make_unique(*this, font); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index b134d7d37..f628ec792 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -124,9 +124,6 @@ class Dialog : public GuiObject bool shouldResize(uInt32& w, uInt32& h) const; ToolTip& tooltip() { return *_toolTip; } - //bool enableToolTip(); - //void showToolTip(int x, int y); - //void hideToolTip(); protected: void draw() override { } diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 82c0df10b..9531ee5ef 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -24,35 +24,44 @@ #include "ToolTip.hxx" +// TODO: +// - disable when in edit mode +// - option to disable tips +// - multi line tips +// - nicer formating of DataDridWidget tip +// - allow reversing ToogleWidget (TooglePixelWidget) + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ToolTip::ToolTip(OSystem& instance, Dialog& dialog, const GUI::Font& font) +ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) : myDialog(dialog), myFont(font) { const int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(); - myTextXOfs = fontHeight < 24 ? 5 : 8; //3 : 5; - myWidth = myTextXOfs * 2 + fontWidth * MAX_LEN; - myHeight = fontHeight + TEXT_Y_OFS * 2; + myTextXOfs = fontHeight < 24 ? 5 : 8; // 3 : 5; + myTextYOfs = fontHeight < 24 ? 2 : 3; + myWidth = fontWidth * MAX_LEN + myTextXOfs * 2; + myHeight = fontHeight + myTextYOfs * 2; + mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight); myScale = myDialog.instance().frameBuffer().hidpiScaleFactor(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToolTip::request(Widget* widget) +void ToolTip::request(const Widget* widget) { if(myWidget != widget) - { release(); - } + if(myTimer == DELAY_TIME) { myWidget = widget; const uInt32 VGAP = 1; const uInt32 hCursor = 18; - string text = widget->getToolTip(); + string text = widget->getToolTip(myPos.x, myPos.y); uInt32 width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); // Note: These include HiDPI scaling: const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect(); @@ -77,8 +86,8 @@ void ToolTip::request(Widget* widget) mySurface->frameRect(0, 0, width, myHeight, kColor); mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); - mySurface->drawString(myFont, text, myTextXOfs, TEXT_Y_OFS, - width - myTextXOfs * 2, myHeight - TEXT_Y_OFS * 2, kTextColor); + mySurface->drawString(myFont, text, myTextXOfs, myTextYOfs, + width - myTextXOfs * 2, myHeight - myTextYOfs * 2, kTextColor); myDialog.setDirtyChain(); } myTimer++; diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index d3164a09d..125343294 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -19,7 +19,7 @@ #define TOOL_TIP_HXX /** - * Class for providing tooltip functionality + * Class for providing tool tip functionality * * @author Thomas Jentzsch */ @@ -37,13 +37,13 @@ public: // Maximum tooltip length static constexpr uInt32 MAX_LEN = 80; - ToolTip(OSystem& instance, Dialog& dialog, const GUI::Font& font); + ToolTip(Dialog& dialog, const GUI::Font& font); ~ToolTip() = default; /** Request a tooltip display */ - void request(Widget* widget); + void request(const Widget* widget); /** @@ -63,18 +63,19 @@ public: private: static constexpr uInt32 DELAY_TIME = 45; // display delay - static constexpr int TEXT_Y_OFS = 2; + //static constexpr int TEXT_Y_OFS = 2; Dialog& myDialog; const GUI::Font& myFont; - Widget* myWidget{nullptr}; + const Widget* myWidget{nullptr}; uInt32 myTimer{0}; Common::Point myPos; uInt32 myWidth{0}; uInt32 myHeight{0}; uInt32 myScale{1}; uInt32 myTextXOfs{0}; + uInt32 myTextYOfs{0}; shared_ptr mySurface; }; diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index bf831a5eb..42612cc99 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -105,8 +105,8 @@ class Widget : public GuiObject void setShadowColor(ColorId color) { _shadowcolor = color; setDirty(); } void setToolTip(const string& text); - const string& getToolTip() const { return _toolTipText; } - bool hasToolTip() const { return !_toolTipText.empty(); } + virtual string getToolTip(int x = 0, int y = 0) const { return _toolTipText; } + virtual bool hasToolTip() const { return !_toolTipText.empty(); } virtual void loadConfig() { } @@ -181,6 +181,10 @@ class StaticTextWidget : public Widget const string& text = "", TextAlign align = TextAlign::Left, ColorId shadowColor = kNone); ~StaticTextWidget() override = default; + + void handleMouseEntered() override {} + void handleMouseLeft() override {} + void setValue(int value); void setLabel(const string& label); void setAlign(TextAlign align) { _align = align; setDirty(); } From f1f5938b79d76eef7df5cd769b15f28516c3006d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 17 Nov 2020 08:34:39 +0100 Subject: [PATCH 208/263] fixed bug which removed highlighting for most widgets --- src/debugger/gui/ToggleWidget.cxx | 2 +- src/gui/ToolTip.cxx | 3 ++- src/gui/ToolTip.hxx | 2 +- src/gui/Widget.cxx | 14 ++++++++++++++ src/gui/Widget.hxx | 2 ++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index 346c51121..a73bc25dc 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -212,7 +212,7 @@ void ToggleWidget::handleCommand(CommandSender* sender, int cmd, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ToggleWidget::getToolTip(int x, int y) const +string ToggleWidget::getToolTip(int, int y) const { const int row = (y - getAbsY()) / _rowHeight; const int pos = row * _cols;// +col; diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 9531ee5ef..ece2f1ccc 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -30,7 +30,8 @@ // - multi line tips // - nicer formating of DataDridWidget tip // - allow reversing ToogleWidget (TooglePixelWidget) - +// - shift checkbox bits +// - RomListWidget (hex codes, maybe disassembly operands) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index 125343294..efcf3bafe 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -19,7 +19,7 @@ #define TOOL_TIP_HXX /** - * Class for providing tool tip functionality + * Class for providing tooltip functionality * * @author Thomas Jentzsch */ diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 991207655..a7fb55561 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -475,6 +475,20 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font, _bmh = bmh; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ButtonWidget::handleMouseEntered() +{ + if(isEnabled()) + setFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ButtonWidget::handleMouseLeft() +{ + if(isEnabled()) + clearFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool ButtonWidget::handleEvent(Event::Type e) { diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 42612cc99..33c6a3e20 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -236,6 +236,8 @@ class ButtonWidget : public StaticTextWidget, public CommandSender bool handleMouseClicks(int x, int y, MouseButton b) override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; + void handleMouseEntered() override; + void handleMouseLeft() override; bool handleEvent(Event::Type event) override; void drawWidget(bool hilite) override; From d7fe5510bb50c9cff4304d72c6a1c04d58d93e0f Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 17 Nov 2020 12:33:47 +0100 Subject: [PATCH 209/263] keep tooltips visible while mouse moves in focus show tooltips faster when moving from one to another update tooltip when mouse moves over different widget items disable tooltip when editing --- src/debugger/gui/DataGridWidget.cxx | 22 ++++- src/debugger/gui/DataGridWidget.hxx | 8 +- src/debugger/gui/ToggleWidget.cxx | 22 ++++- src/debugger/gui/ToggleWidget.hxx | 7 +- src/gui/Dialog.cxx | 6 +- src/gui/EditableWidget.cxx | 8 ++ src/gui/EditableWidget.hxx | 1 + src/gui/LauncherDialog.cxx | 2 +- src/gui/PopUpWidget.cxx | 3 + src/gui/ToolTip.cxx | 139 +++++++++++++++++----------- src/gui/ToolTip.hxx | 79 +++++++++------- src/gui/VideoAudioDialog.cxx | 8 +- src/gui/Widget.cxx | 4 +- src/gui/Widget.hxx | 8 +- 14 files changed, 205 insertions(+), 112 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index f6898b6c8..d11375d29 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -571,12 +571,18 @@ void DataGridWidget::handleCommand(CommandSender* sender, int cmd, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string DataGridWidget::getToolTip(int x, int y) const +int DataGridWidget::getToolTipIndex(Common::Point pos) const { - const int col = (x - getAbsX()) / _colWidth; - const int row = (y - getAbsY()) / _rowHeight; - const int pos = row * _cols + col; - const Int32 val = _valueList[pos]; + const int col = (pos.x - getAbsX()) / _colWidth; + const int row = (pos.y - getAbsY()) / _rowHeight; + + return row * _cols + col; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string DataGridWidget::getToolTip(Common::Point pos) const +{ + const Int32 val = _valueList[getToolTipIndex(pos)]; const string hex = Common::Base::toString(val, Common::Base::Fmt::_16); const string dec = Common::Base::toString(val, Common::Base::Fmt::_10); const string bin = Common::Base::toString(val, Common::Base::Fmt::_2); @@ -587,6 +593,12 @@ string DataGridWidget::getToolTip(int x, int y) const return buf.str(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool DataGridWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +{ + return getToolTipIndex(oldPos) != getToolTipIndex(newPos); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DataGridWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index f50270f4f..1a402659d 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -84,8 +84,8 @@ class DataGridWidget : public EditableWidget void setCrossed(bool enable) { _crossGrid = enable; } - string getToolTip(int x = 0, int y = 0) const override; - bool hasToolTip() const override { return true; } + string getToolTip(Common::Point pos) const override; + bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; protected: void drawWidget(bool hilite) override; @@ -101,6 +101,8 @@ class DataGridWidget : public EditableWidget void receivedFocusWidget() override; void lostFocusWidget() override; + bool hasToolTip() const override { return true; } + void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; void handleMouseWheel(int x, int y, int direction) override; @@ -148,6 +150,8 @@ class DataGridWidget : public EditableWidget void enableEditMode(bool state) { _editMode = state; } + int getToolTipIndex(Common::Point pos) const; + private: // Following constructors and assignment operators not supported DataGridWidget() = delete; diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index a73bc25dc..3d2fca262 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -212,16 +212,23 @@ void ToggleWidget::handleCommand(CommandSender* sender, int cmd, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ToggleWidget::getToolTip(int, int y) const +int ToggleWidget::getToolTipIndex(Common::Point pos) const { - const int row = (y - getAbsY()) / _rowHeight; - const int pos = row * _cols;// +col; + const int row = (pos.y - getAbsY()) / _rowHeight; + + return row * _cols; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string ToggleWidget::getToolTip(Common::Point pos) const +{ + const int idx = getToolTipIndex(pos); Int32 val = 0; for(int col = 0; col < _cols; ++col) { val <<= 1; - val += _stateList[pos + col]; + val += _stateList[idx + col]; } const string hex = Common::Base::toString(val, Common::Base::Fmt::_16); @@ -234,4 +241,11 @@ string ToggleWidget::getToolTip(int, int y) const return buf.str(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool ToggleWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +{ + return getToolTipIndex(oldPos) != getToolTipIndex(newPos); +} + + diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index a671f53e9..060a52e13 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -46,10 +46,11 @@ class ToggleWidget : public Widget, public CommandSender void setEditable(bool editable) { _editable = editable; } bool isEditable() const { return _editable; } - string getToolTip(int x = 0, int y = 0) const override; - bool hasToolTip() const override { return true; } + string getToolTip(Common::Point pos) const override; + bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; protected: + bool hasToolTip() const override { return true; } protected: int _rows; @@ -74,6 +75,8 @@ class ToggleWidget : public Widget, public CommandSender bool handleKeyDown(StellaKey key, StellaMod mod) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + int getToolTipIndex(Common::Point pos) const; + // Following constructors and assignment operators not supported ToggleWidget() = delete; ToggleWidget(const ToggleWidget&) = delete; diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index b9678182e..a33b4ffa1 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -593,9 +593,6 @@ void Dialog::handleMouseMoved(int x, int y) { Widget* w; - // Update mouse coordinates for tooltips - _toolTip->update(x, y); - if(_focusedWidget && !_dragWidget) { w = _focusedWidget; @@ -639,6 +636,9 @@ void Dialog::handleMouseMoved(int x, int y) if (w && (w->getFlags() & Widget::FLAG_TRACK_MOUSE)) w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y)); + + // Update mouse coordinates for tooltips + _toolTip->update(_mouseWidget, Common::Point(x, y)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index d6c35fa55..39a4b519f 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -22,6 +22,7 @@ #include "OSystem.hxx" #include "EventHandler.hxx" #include "UndoHandler.hxx" +#include "ToolTip.hxx" #include "EditableWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -79,6 +80,12 @@ void EditableWidget::tick() Widget::tick(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EditableWidget::wantsToolTip() const +{ + return !(_hasFocus && isEditable() && _editMode) && Widget::wantsToolTip(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EditableWidget::setEditable(bool editable, bool hiliteBG) { @@ -100,6 +107,7 @@ void EditableWidget::receivedFocusWidget() { _caretTimer = 0; _caretEnabled = true; + dialog().tooltip().release(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 8ebf1791c..6e55cf541 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -68,6 +68,7 @@ class EditableWidget : public Widget, public CommandSender void receivedFocusWidget() override; void lostFocusWidget() override; void tick() override; + bool wantsToolTip() const override; virtual void startEditMode() { setFlags(Widget::FLAG_WANTS_RAWDATA); } virtual void endEditMode() { clearFlags(Widget::FLAG_WANTS_RAWDATA); } diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 93361b9f5..9c140e15c 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -121,7 +121,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Show the filter input field xpos -= fwidth + LBL_GAP; myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwidth, lineHeight, ""); - myPattern->setToolTip("Enter a filter text to reduce file list."); + myPattern->setToolTip("Enter filter text to reduce file list."); // Show the "Filter" label xpos -= lwidth3 + LBL_GAP; new StaticTextWidget(this, font, xpos, ypos, lblFilter); diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 06c726779..45f79e55b 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -20,6 +20,8 @@ #include "FBSurface.hxx" #include "Font.hxx" #include "ContextMenu.hxx" +#include "Dialog.hxx" +#include "ToolTip.hxx" #include "DialogContainer.hxx" #include "PopUpWidget.hxx" @@ -122,6 +124,7 @@ void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) { if(isEnabled() && !myMenu->isVisible()) { + dialog().tooltip().hide(); // Add menu just underneath parent widget myMenu->show(getAbsX() + _labelWidth, getAbsY() + getHeight(), dialog().surface().dstRect(), myMenu->getSelected()); diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index ece2f1ccc..36c8b1b20 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -24,8 +24,12 @@ #include "ToolTip.hxx" -// TODO: -// - disable when in edit mode +// TODOs: +// + keep enabled when mouse moves over same widget +// + static position and text for normal widgets +// + moving position and text over e.g. DataGridWidget +// + reenable tip faster +// + disable when in edit mode // - option to disable tips // - multi line tips // - nicer formating of DataDridWidget tip @@ -41,7 +45,7 @@ ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) const int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(); - myTextXOfs = fontHeight < 24 ? 5 : 8; // 3 : 5; + myTextXOfs = fontHeight < 24 ? 5 : 8; myTextYOfs = fontHeight < 24 ? 2 : 3; myWidth = fontWidth * MAX_LEN + myTextXOfs * 2; myHeight = fontHeight + myTextYOfs * 2; @@ -51,72 +55,103 @@ ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToolTip::request(const Widget* widget) +void ToolTip::update(const Widget* widget, Common::Point pos) { - if(myWidget != widget) - release(); - - if(myTimer == DELAY_TIME) + if(myTipWidget != widget) { - myWidget = widget; + myFocusWidget = widget; + release(); + } + if(myTipShown && myTipWidget->changedToolTip(myPos, pos)) + myPos = pos, show(); + else + myPos = pos; +} - const uInt32 VGAP = 1; - const uInt32 hCursor = 18; - string text = widget->getToolTip(myPos.x, myPos.y); - uInt32 width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); - // Note: These include HiDPI scaling: - const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect(); - const Common::Rect dialogRect = myDialog.surface().dstRect(); - // Limit to app or screen size and adjust position - const Int32 xAbs = myPos.x + dialogRect.x() / myScale; - const uInt32 yAbs = myPos.y + dialogRect.y() / myScale; - Int32 x = std::min(xAbs, Int32(imageRect.w() / myScale - width)); - const uInt32 y = (yAbs + myHeight + hCursor > imageRect.h() / myScale) - ? yAbs - myHeight - VGAP - : yAbs + hCursor / myScale + VGAP; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::hide() +{ + if(myTipShown) + { + myTimer = 0; + myTipWidget = myFocusWidget = nullptr; - if(x < 0) - { - x = 0; - width = imageRect.w() / myScale; - } - - mySurface->setSrcSize(width, myHeight); - mySurface->setDstSize(width * myScale, myHeight * myScale); - mySurface->setDstPos(x * myScale, y * myScale); - - mySurface->frameRect(0, 0, width, myHeight, kColor); - mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); - mySurface->drawString(myFont, text, myTextXOfs, myTextYOfs, - width - myTextXOfs * 2, myHeight - myTextYOfs * 2, kTextColor); + myTipShown = false; myDialog.setDirtyChain(); } - myTimer++; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToolTip::release() { - if(myWidget != nullptr) + if(myTipShown) { - myTimer = 0; - myWidget = nullptr; + myTimer = DELAY_TIME; + + myTipShown = false; myDialog.setDirtyChain(); } + + // After displaying a tip, slowly reset the timer to 0 + // until a new tip is requested + if(myTipWidget != myFocusWidget && myTimer) + myTimer--; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::request() +{ + myTipWidget = myFocusWidget; + + if(myTimer == DELAY_TIME) + show(); + + myTimer++; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::show() +{ + if(myTipWidget == nullptr) + return; + + const uInt32 V_GAP = 1; + const uInt32 H_CURSOR = 18; + string text = myTipWidget->getToolTip(myPos); + uInt32 width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); + // Note: The rects include HiDPI scaling + const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect(); + const Common::Rect dialogRect = myDialog.surface().dstRect(); + // Limit position to app size and adjust accordingly + const Int32 xAbs = myPos.x + dialogRect.x() / myScale; + const uInt32 yAbs = myPos.y + dialogRect.y() / myScale; + Int32 x = std::min(xAbs, Int32(imageRect.w() / myScale - width)); + const uInt32 y = (yAbs + myHeight + H_CURSOR > imageRect.h() / myScale) + ? yAbs - myHeight - V_GAP + : yAbs + H_CURSOR / myScale + V_GAP; + + if(x < 0) + { + x = 0; + width = imageRect.w() / myScale; + } + + mySurface->setSrcSize(width, myHeight); + mySurface->setDstSize(width * myScale, myHeight * myScale); + mySurface->setDstPos(x * myScale, y * myScale); + + mySurface->frameRect(0, 0, width, myHeight, kColor); + mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); + mySurface->drawString(myFont, text, myTextXOfs, myTextYOfs, + width - myTextXOfs * 2, myHeight - myTextYOfs * 2, kTextColor); + + myTipShown = true; + myDialog.setDirtyChain(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToolTip::render() { - if(myWidget != nullptr) - mySurface->render(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToolTip::update(int x, int y) -{ - if(myWidget != nullptr && x != myPos.x || y != myPos.y) - release(); - myPos.x = x; - myPos.y = y; + if(myTipShown) + mySurface->render(), cerr << " render tooltip" << endl; } diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index efcf3bafe..b3bbf547a 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -33,50 +33,59 @@ class FBSurface; class ToolTip { -public: - // Maximum tooltip length - static constexpr uInt32 MAX_LEN = 80; + public: + // Maximum tooltip length + static constexpr uInt32 MAX_LEN = 80; - ToolTip(Dialog& dialog, const GUI::Font& font); - ~ToolTip() = default; + ToolTip(Dialog& dialog, const GUI::Font& font); + ~ToolTip() = default; - /** - Request a tooltip display - */ - void request(const Widget* widget); + /** + Request a tooltip display. + */ + void request(); + /** + Hide a displayed tooltip and reset the timer. + */ + void hide(); - /** - Hide an existing tooltip (if displayed) - */ - void release(); + /** + Hide a displayed tooltip and reset the timer slowly. + This allows faster tip display of the next tip. + */ + void release(); - /** - Update with current mouse position - */ - void update(int x, int y); + /** + Update focussed widget and current mouse position. + */ + void update(const Widget* widget, Common::Point pos); - /* - Render the tooltip - */ - void render(); + /* + Render the tooltip + */ + void render(); -private: - static constexpr uInt32 DELAY_TIME = 45; // display delay - //static constexpr int TEXT_Y_OFS = 2; + private: + void show(); - Dialog& myDialog; - const GUI::Font& myFont; + private: + static constexpr uInt32 DELAY_TIME = 45; // display delay - const Widget* myWidget{nullptr}; - uInt32 myTimer{0}; - Common::Point myPos; - uInt32 myWidth{0}; - uInt32 myHeight{0}; - uInt32 myScale{1}; - uInt32 myTextXOfs{0}; - uInt32 myTextYOfs{0}; - shared_ptr mySurface; + Dialog& myDialog; + const GUI::Font& myFont; + const Widget* myTipWidget{nullptr}; + const Widget* myFocusWidget{nullptr}; + + uInt32 myTimer{0}; + Common::Point myPos; + uInt32 myWidth{0}; + uInt32 myHeight{0}; + uInt32 myTextXOfs{0}; + uInt32 myTextYOfs{0}; + bool myTipShown{false}; + uInt32 myScale{1}; + shared_ptr mySurface; }; #endif diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index d34f0a330..def965aa6 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -129,7 +129,7 @@ void VideoAudioDialog::addDisplayTab() // TIA interpolation myTIAInterpolate = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Interpolation "); - myTIAInterpolate->setToolTip("Blur the emulated display."); + myTIAInterpolate->setToolTip("Blur emulated display."); wid.push_back(myTIAInterpolate); ypos += lineHeight + VGAP * 4; @@ -147,14 +147,14 @@ void VideoAudioDialog::addDisplayTab() // FS stretch myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch"); - myUseStretch->setToolTip("Stretch the emulated display to fill the whole screen."); + myUseStretch->setToolTip("Stretch emulated display to fill whole screen."); wid.push_back(myUseStretch); #ifdef ADAPTABLE_REFRESH_SUPPORT // Adapt refresh rate ypos += lineHeight + VGAP; myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate"); - myRefreshAdapt->setToolTip("Select the optimal display refresh rate for each ROM."); + myRefreshAdapt->setToolTip("Select optimal display refresh rate for each ROM."); wid.push_back(myRefreshAdapt); #else myRefreshAdapt = nullptr; @@ -181,7 +181,7 @@ void VideoAudioDialog::addDisplayTab() "V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true); myVSizeAdjust->setMinValue(-5); myVSizeAdjust->setMaxValue(5); myVSizeAdjust->setTickmarkIntervals(2); - myVSizeAdjust->setToolTip("Adapt vertical size to emulated TV display."); + myVSizeAdjust->setToolTip("Adjust vertical size to match emulated TV display."); wid.push_back(myVSizeAdjust); diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index a7fb55561..cfb933965 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -75,8 +75,8 @@ void Widget::tick() { if(isEnabled()) { - if(hasMouseFocus() && hasToolTip()) - dialog().tooltip().request(this); + if(wantsToolTip()) + dialog().tooltip().request(); // Recursively tick widget and all child dialogs and widgets Widget* w = _firstWidget; diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 33c6a3e20..45c676fe2 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -26,6 +26,7 @@ class Dialog; #include #include "bspf.hxx" +#include "Rect.hxx" #include "Event.hxx" #include "EventHandlerConstants.hxx" #include "FrameBufferConstants.hxx" @@ -105,8 +106,8 @@ class Widget : public GuiObject void setShadowColor(ColorId color) { _shadowcolor = color; setDirty(); } void setToolTip(const string& text); - virtual string getToolTip(int x = 0, int y = 0) const { return _toolTipText; } - virtual bool hasToolTip() const { return !_toolTipText.empty(); } + virtual string getToolTip(Common::Point pos) const { return _toolTipText; } + virtual bool changedToolTip(Common::Point oldPos, Common::Point newPos) const { return false; } virtual void loadConfig() { } @@ -120,6 +121,9 @@ class Widget : public GuiObject void releaseFocus() override { assert(_boss); _boss->releaseFocus(); } + virtual bool wantsToolTip() const { return hasMouseFocus() && hasToolTip(); } + virtual bool hasToolTip() const { return !_toolTipText.empty(); } + // By default, delegate unhandled commands to the boss void handleCommand(CommandSender* sender, int cmd, int data, int id) override { assert(_boss); _boss->handleCommand(sender, cmd, data, id); } From 35971d3353a78292a31126d61fb7d587abc83ffe Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 17 Nov 2020 13:06:11 +0100 Subject: [PATCH 210/263] added considering bit order in PF pixel tooltip display removed unused click count from ToggleWidget --- src/debugger/gui/TiaWidget.cxx | 2 +- src/debugger/gui/ToggleBitWidget.cxx | 2 +- src/debugger/gui/TogglePixelWidget.cxx | 5 +++-- src/debugger/gui/TogglePixelWidget.hxx | 4 ++-- src/debugger/gui/ToggleWidget.cxx | 25 ++++++++++++++++--------- src/debugger/gui/ToggleWidget.hxx | 7 ++++--- 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/debugger/gui/TiaWidget.cxx b/src/debugger/gui/TiaWidget.cxx index 5f6ba56ab..20aba0763 100644 --- a/src/debugger/gui/TiaWidget.cxx +++ b/src/debugger/gui/TiaWidget.cxx @@ -563,7 +563,7 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont, new StaticTextWidget(boss, lfont, xpos, ypos+2, 2*fontWidth, fontHeight, "PF", TextAlign::Left); xpos += 2*fontWidth + 5; - myPF[0] = new TogglePixelWidget(boss, nfont, xpos, ypos+1, 4, 1); + myPF[0] = new TogglePixelWidget(boss, nfont, xpos, ypos+1, 4, 1, 4); myPF[0]->setTarget(this); myPF[0]->setID(kPF0ID); addFocusWidget(myPF[0]); diff --git a/src/debugger/gui/ToggleBitWidget.cxx b/src/debugger/gui/ToggleBitWidget.cxx index 479f31225..39ca7dcce 100644 --- a/src/debugger/gui/ToggleBitWidget.cxx +++ b/src/debugger/gui/ToggleBitWidget.cxx @@ -26,7 +26,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int cols, int rows, int colchars) - : ToggleWidget(boss, font, x, y, cols, rows, 1) + : ToggleWidget(boss, font, x, y, cols, rows) { _rowHeight = font.getLineHeight(); _colWidth = colchars * font.getMaxCharWidth() + 8; diff --git a/src/debugger/gui/TogglePixelWidget.cxx b/src/debugger/gui/TogglePixelWidget.cxx index fdc1609bc..b7dd5dbdf 100644 --- a/src/debugger/gui/TogglePixelWidget.cxx +++ b/src/debugger/gui/TogglePixelWidget.cxx @@ -24,8 +24,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TogglePixelWidget::TogglePixelWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, int cols, int rows) - : ToggleWidget(boss, font, x, y, cols, rows, 1) + int x, int y, int cols, int rows, + int shiftBits) + : ToggleWidget(boss, font, x, y, cols, rows, shiftBits) { _rowHeight = _colWidth = font.getLineHeight(); diff --git a/src/debugger/gui/TogglePixelWidget.hxx b/src/debugger/gui/TogglePixelWidget.hxx index 6177cac45..c748210f2 100644 --- a/src/debugger/gui/TogglePixelWidget.hxx +++ b/src/debugger/gui/TogglePixelWidget.hxx @@ -25,7 +25,8 @@ class TogglePixelWidget : public ToggleWidget { public: TogglePixelWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, int cols, int rows); + int x, int y, int cols = 1, int rows = 1, + int shiftBits = 0); ~TogglePixelWidget() override = default; void setColor(ColorId color) { _pixelColor = color; } @@ -42,7 +43,6 @@ class TogglePixelWidget : public ToggleWidget private: ColorId _pixelColor{kNone}, _backgroundColor{kDlgColor}; - bool _swapBits{false}; bool _crossBits{false}; private: diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index 3d2fca262..60f4ee154 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -23,8 +23,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, int cols, int rows, - int clicksToChange) + int x, int y, int cols, int rows, int shiftBits) : Widget(boss, font, x, y, 16, 16), CommandSender(boss), _rows(rows), @@ -34,7 +33,7 @@ ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font, _rowHeight(0), _colWidth(0), _selectedItem(0), - _clicksToChange(clicksToChange), + _shiftBits(shiftBits), _editable(true) { _flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS | @@ -70,7 +69,7 @@ void ToggleWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount) // If this was a double click and the mouse is still over the selected item, // send the double click command - if (clickCount == _clicksToChange && (_selectedItem == findItem(x, y))) + if (clickCount == 1 && (_selectedItem == findItem(x, y))) { _stateList[_selectedItem] = !_stateList[_selectedItem]; _changedList[_selectedItem] = !_changedList[_selectedItem]; @@ -225,11 +224,19 @@ string ToggleWidget::getToolTip(Common::Point pos) const const int idx = getToolTipIndex(pos); Int32 val = 0; - for(int col = 0; col < _cols; ++col) - { - val <<= 1; - val += _stateList[idx + col]; - } + if(_swapBits) + for(int col = _cols - 1; col >= 0; --col) + { + val <<= 1; + val += _stateList[idx + col]; + } + else + for(int col = 0; col < _cols; ++col) + { + val <<= 1; + val += _stateList[idx + col]; + } + val <<= _shiftBits; const string hex = Common::Base::toString(val, Common::Base::Fmt::_16); const string dec = Common::Base::toString(val, Common::Base::Fmt::_10); diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index 060a52e13..5f4ec13a7 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -33,8 +33,8 @@ class ToggleWidget : public Widget, public CommandSender public: ToggleWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, int cols, int rows, - int clicksToChange = 2); + int x, int y, int cols = 1, int rows = 1, + int shiftBits = 0); ~ToggleWidget() override = default; const BoolArray& getState() { return _stateList; } @@ -60,8 +60,9 @@ class ToggleWidget : public Widget, public CommandSender int _rowHeight; // explicitly set in child classes int _colWidth; // explicitly set in child classes int _selectedItem; - int _clicksToChange; // number of clicks to register a change bool _editable; + bool _swapBits{false}; + int _shiftBits{0}; // shift bits for tooltip display BoolArray _stateList; BoolArray _changedList; From 92b77f32c474700e1583816aa4543ea2f5ab17ea Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 17 Nov 2020 13:36:12 +0100 Subject: [PATCH 211/263] enhanced GPRx bits display in debugger, now considers reflection --- src/debugger/gui/TiaWidget.cxx | 12 ++++++++---- src/debugger/gui/TogglePixelWidget.hxx | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/debugger/gui/TiaWidget.cxx b/src/debugger/gui/TiaWidget.cxx index 20aba0763..c330bf386 100644 --- a/src/debugger/gui/TiaWidget.cxx +++ b/src/debugger/gui/TiaWidget.cxx @@ -919,10 +919,14 @@ void TiaWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) case kRefP0ID: tia.refP0(myRefP0->getState() ? 1 : 0); + myGRP0->setIntState(myGRP0->getIntState(), !myRefP0->getState()); + myGRP0Old->setIntState(myGRP0Old->getIntState(), !myRefP0->getState()); break; case kRefP1ID: tia.refP1(myRefP1->getState() ? 1 : 0); + myGRP1->setIntState(myGRP1->getIntState(), !myRefP1->getState()); + myGRP1Old->setIntState(myGRP1Old->getIntState(), !myRefP1->getState()); break; case kDelP0ID: @@ -1043,8 +1047,8 @@ void TiaWidget::loadConfig() myGRP0Old->setColor(kBGColorLo); myGRP0Old->setCrossed(true); } - myGRP0->setIntState(state.gr[TiaState::P0], false); - myGRP0Old->setIntState(state.gr[TiaState::P0+2], false); + myGRP0->setIntState(state.gr[TiaState::P0], state.ref[TiaState::P0]); + myGRP0Old->setIntState(state.gr[TiaState::P0+2], state.ref[TiaState::P0]); // posP0 myPosP0->setList(0, state.pos[TiaState::P0], @@ -1079,8 +1083,8 @@ void TiaWidget::loadConfig() myGRP1Old->setColor(kBGColorLo); myGRP1Old->setCrossed(true); } - myGRP1->setIntState(state.gr[TiaState::P1], false); - myGRP1Old->setIntState(state.gr[TiaState::P1+2], false); + myGRP1->setIntState(state.gr[TiaState::P1], state.ref[TiaState::P1]); + myGRP1Old->setIntState(state.gr[TiaState::P1+2], state.ref[TiaState::P1]); // posP1 myPosP1->setList(0, state.pos[TiaState::P1], diff --git a/src/debugger/gui/TogglePixelWidget.hxx b/src/debugger/gui/TogglePixelWidget.hxx index c748210f2..fe63cd964 100644 --- a/src/debugger/gui/TogglePixelWidget.hxx +++ b/src/debugger/gui/TogglePixelWidget.hxx @@ -36,7 +36,7 @@ class TogglePixelWidget : public ToggleWidget void setState(const BoolArray& state); - void setIntState(int value, bool swap); + void setIntState(int value, bool swap = false); int getIntState(); void setCrossed(bool enable) { _crossBits = enable; } From 9bb6959dd857fc2025a97b730c0e019e7a7621af Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 17 Nov 2020 18:10:54 +0100 Subject: [PATCH 212/263] aligned tooltip font to dialog font improved debugger tooltip display added tooltips for RomListWidget bytes --- src/debugger/gui/DataGridWidget.cxx | 11 ++--- src/debugger/gui/DebuggerDialog.cxx | 2 + src/debugger/gui/RomListWidget.cxx | 63 +++++++++++++++++++++++++++++ src/debugger/gui/RomListWidget.hxx | 7 ++++ src/debugger/gui/ToggleWidget.cxx | 12 +++--- src/gui/LauncherDialog.cxx | 6 ++- src/gui/ToolTip.cxx | 34 +++++++++++----- src/gui/ToolTip.hxx | 4 +- 8 files changed, 116 insertions(+), 23 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index d11375d29..9e75a955f 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -583,13 +583,14 @@ int DataGridWidget::getToolTipIndex(Common::Point pos) const string DataGridWidget::getToolTip(Common::Point pos) const { const Int32 val = _valueList[getToolTipIndex(pos)]; - const string hex = Common::Base::toString(val, Common::Base::Fmt::_16); - const string dec = Common::Base::toString(val, Common::Base::Fmt::_10); - const string bin = Common::Base::toString(val, Common::Base::Fmt::_2); ostringstream buf; - // TODO: time leading spaces and zeroes - buf << "$" << hex << " = #" << dec << " = %" << bin; + buf << _toolTipText + << "$" << Common::Base::toString(val, Common::Base::Fmt::_16) + << " = #" << val; + if(val < 0x100) + buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2); + return buf.str(); } diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index b8c0662ee..07e530ac6 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -18,6 +18,7 @@ #include "Cart.hxx" #include "Widget.hxx" #include "Dialog.hxx" +#include "ToolTip.hxx" #include "Settings.hxx" #include "StellaKeys.hxx" #include "EventHandler.hxx" @@ -406,6 +407,7 @@ void DebuggerDialog::createFont() break; } } + tooltip().setFont(*myNFont); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 58d392ee9..e595fc6aa 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -442,6 +442,69 @@ void RomListWidget::lostFocusWidget() abortEditMode(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Common::Point RomListWidget::getToolTipIndex(Common::Point pos) const +{ + const Common::Rect& r = getEditRect(); + const int col = (pos.x - r.x() - getAbsX()) / _font.getMaxCharWidth(); + const int row = (pos.y - getAbsY()) / _lineHeight; + + if(col < 0) + return Common::Point(-1, -1); + else + return Common::Point(col, row + _currentPos); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string RomListWidget::getToolTip(Common::Point pos) const +{ + const Common::Point idx = getToolTipIndex(pos); + + if(idx.y == -1) + return EmptyString; + + const string bytes = myDisasm->list[idx.y].bytes; + + if(bytes.length() < idx.x + 1) + return EmptyString; + + Int32 val; + if(bytes.length() == 8 && bytes[2] != ' ') + { + // Binary value + val = stol(bytes, 0, 2); + } + else + { + // hex 1..3 values + if(idx.x % 3 == 2) + // Skip gaps between hex values + return EmptyString; + + // Get one hex byte + const string valStr = bytes.substr((idx.x / 3) * 3, 2); + + val = stol(valStr, 0, 16); + + } + ostringstream buf; + + buf << _toolTipText + << "$" << Common::Base::toString(val, Common::Base::Fmt::_16) + << " = #" << val; + if(val < 0x100) + buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2); + + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool RomListWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +{ + return getToolTipIndex(oldPos) != getToolTipIndex(newPos); +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomListWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx index 37473d12f..3f26d217f 100644 --- a/src/debugger/gui/RomListWidget.hxx +++ b/src/debugger/gui/RomListWidget.hxx @@ -56,6 +56,9 @@ class RomListWidget : public EditableWidget void setSelected(int item); void setHighlighted(int item); + string getToolTip(Common::Point pos) const override; + bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; + protected: void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; @@ -77,11 +80,15 @@ class RomListWidget : public EditableWidget void endEditMode() override; void abortEditMode() override; void lostFocusWidget() override; + + bool hasToolTip() const override { return true; } + void scrollToSelected() { scrollToCurrent(_selectedItem); } void scrollToHighlighted() { scrollToCurrent(_highlightedItem); } private: void scrollToCurrent(int item); + Common::Point getToolTipIndex(Common::Point pos) const; private: unique_ptr myMenu; diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index 60f4ee154..e20544783 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -223,6 +223,7 @@ string ToggleWidget::getToolTip(Common::Point pos) const { const int idx = getToolTipIndex(pos); Int32 val = 0; + ostringstream buf; if(_swapBits) for(int col = _cols - 1; col >= 0; --col) @@ -238,13 +239,12 @@ string ToggleWidget::getToolTip(Common::Point pos) const } val <<= _shiftBits; - const string hex = Common::Base::toString(val, Common::Base::Fmt::_16); - const string dec = Common::Base::toString(val, Common::Base::Fmt::_10); - const string bin = Common::Base::toString(val, Common::Base::Fmt::_2); - ostringstream buf; + buf << _toolTipText + << "$" << Common::Base::toString(val, Common::Base::Fmt::_16) + << " = #" << val; + if(val < 0x100) + buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2); - // TODO: time leading spaces and zeroes - buf << "$" << hex << " = #" << dec << " = %" << bin; return buf.str(); } diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 9c140e15c..5092299ec 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -30,6 +30,7 @@ #include "StellaSettingsDialog.hxx" #include "WhatsNewDialog.hxx" #include "MessageBox.hxx" +#include "ToolTip.hxx" #include "OSystem.hxx" #include "FrameBuffer.hxx" #include "FBSurface.hxx" @@ -56,8 +57,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, int x, int y, int w, int h) - : Dialog(osystem, parent, osystem.frameBuffer().launcherFont(), "", - x, y, w, h) + : Dialog(osystem, parent, x, y, w, h) { myUseMinimalUI = instance().settings().getBool("minimal_ui"); @@ -80,6 +80,8 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, const string& lblAllFiles = "Show all files"; const string& lblFound = "XXXX items found"; + tooltip().setFont(font); + lwidth = font.getStringWidth(lblRom); lwidth2 = font.getStringWidth(lblAllFiles) + CheckboxWidget::boxSize(font); int lwidth3 = font.getStringWidth(lblFilter); diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 36c8b1b20..85f5bedf4 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -32,16 +32,24 @@ // + disable when in edit mode // - option to disable tips // - multi line tips -// - nicer formating of DataDridWidget tip -// - allow reversing ToogleWidget (TooglePixelWidget) -// - shift checkbox bits +// + nicer formating of DataDridWidget tip +// + allow reversing ToogleWidget (TooglePixelWidget) +// + shift checkbox bits // - RomListWidget (hex codes, maybe disassembly operands) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) - : myDialog(dialog), - myFont(font) + : myDialog(dialog) { + myScale = myDialog.instance().frameBuffer().hidpiScaleFactor(); + + setFont(font); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::setFont(const GUI::Font& font) +{ + myFont = &font; const int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(); @@ -51,7 +59,6 @@ ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) myHeight = fontHeight + myTextYOfs * 2; mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight); - myScale = myDialog.instance().frameBuffer().hidpiScaleFactor(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -86,7 +93,7 @@ void ToolTip::release() { if(myTipShown) { - myTimer = DELAY_TIME; + myTimer = DELAY_TIME - 1; myTipShown = false; myDialog.setDirtyChain(); @@ -118,7 +125,16 @@ void ToolTip::show() const uInt32 V_GAP = 1; const uInt32 H_CURSOR = 18; string text = myTipWidget->getToolTip(myPos); - uInt32 width = std::min(myWidth, myFont.getStringWidth(text) + myTextXOfs * 2); + + myTipShown = true; + if(text.empty()) + { + release(); + return; + } + + uInt32 width = std::min(myWidth, myFont->getStringWidth(text) + myTextXOfs * 2); + //uInt32 height = std::min(myHeight, font.getFontHeight() + myTextYOfs * 2); // Note: The rects include HiDPI scaling const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect(); const Common::Rect dialogRect = myDialog.surface().dstRect(); @@ -142,7 +158,7 @@ void ToolTip::show() mySurface->frameRect(0, 0, width, myHeight, kColor); mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); - mySurface->drawString(myFont, text, myTextXOfs, myTextYOfs, + mySurface->drawString(*myFont, text, myTextXOfs, myTextYOfs, width - myTextXOfs * 2, myHeight - myTextYOfs * 2, kTextColor); myTipShown = true; diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index b3bbf547a..879200c06 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -40,6 +40,8 @@ class ToolTip ToolTip(Dialog& dialog, const GUI::Font& font); ~ToolTip() = default; + void setFont(const GUI::Font& font); + /** Request a tooltip display. */ @@ -73,7 +75,7 @@ class ToolTip static constexpr uInt32 DELAY_TIME = 45; // display delay Dialog& myDialog; - const GUI::Font& myFont; + const GUI::Font* myFont{nullptr}; const Widget* myTipWidget{nullptr}; const Widget* myFocusWidget{nullptr}; From 94ed04469761e2b7b35eeb1611b5eb36dcd2e12b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 17 Nov 2020 19:41:23 +0100 Subject: [PATCH 213/263] added tooltips to TiaInfoWidget and CpuWidget --- src/debugger/gui/CpuWidget.cxx | 6 +++--- src/debugger/gui/RomListWidget.cxx | 2 +- src/debugger/gui/TiaInfoWidget.cxx | 11 +++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/debugger/gui/CpuWidget.cxx b/src/debugger/gui/CpuWidget.cxx index ea6fbb96f..a8719f448 100644 --- a/src/debugger/gui/CpuWidget.cxx +++ b/src/debugger/gui/CpuWidget.cxx @@ -85,18 +85,19 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n _w = lwidth + myPCGrid->getWidth() + myPCLabel->getWidth() + 20; // Create labels showing the source of data for SP/A/X/Y registers + const std::array labels = { "SP", "A", "X", "Y" }; xpos += myCpuGridBinValue->getWidth() + 20; int src_y = ypos, src_w = (max_w - xpos + x) - 10; for(int i = 0; i < 4; ++i) { myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w, fontHeight + 1); + myCpuDataSrc[i]->setToolTip("Source label of last load into " + labels[i] + "."); myCpuDataSrc[i]->setEditable(false, true); src_y += fontHeight + 2; } // Add labels for other CPU registers xpos = x; - const std::array labels = { "SP ", "A ", "X ", "Y " }; for(int row = 0; row < 4; ++row) { new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 2, @@ -139,10 +140,9 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n xpos = myCpuDataSrc[0]->getLeft(); new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, ypos + 2, "Dest"); myCpuDataDest = new EditTextWidget(boss, nfont, xpos, ypos, src_w, fontHeight + 1); + myCpuDataDest->setToolTip("Destination label of last store."); myCpuDataDest->setEditable(false, true); - - _h = ypos + myPSRegister->getHeight() - y; } diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index e595fc6aa..72f3a0b03 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -476,7 +476,7 @@ string RomListWidget::getToolTip(Common::Point pos) const } else { - // hex 1..3 values + // 1..3 hex values if(idx.x % 3 == 2) // Skip gaps between hex values return EmptyString; diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index a02b2365d..2690f8b4f 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -60,30 +60,35 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, xpos = x; new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycls" : "F. Cycls"); myFrameCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myFrameCycles->setToolTip("CPU cycles executed this frame."); myFrameCycles->setEditable(false, true); // Left: WSync Cycles ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycls" : "WSync C."); myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myWSyncCylces->setToolTip("CPU cycles used for WSYNC this frame."); myWSyncCylces->setEditable(false, true); // Left: Timer Cycles ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycls" : "Timer C."); myTimerCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myTimerCylces->setToolTip("CPU cycles roughly used for INTIM reads this frame."); myTimerCylces->setEditable(false, true); // Left: Total Cycles ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total"); myTotalCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight); + myTotalCycles->setToolTip("Total CPU cycles executed for this session (E notation)."); myTotalCycles->setEditable(false, true); // Left: Delta Cycles ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta"); myDeltaCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight); + myDeltaCycles->setToolTip("CPU cycles executed since last debug break."); myDeltaCycles->setEditable(false, true); // Right column @@ -93,6 +98,7 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, // Right: Frame Count new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cnt." : "Frame"); myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidthR, ypos - 1, fwidth, lineHeight); + myFrameCount->setToolTip("Total number of frames executed this session."); myFrameCount->setEditable(false, true); lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ") + LGAP; @@ -102,28 +108,33 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scanline" : "Scn Ln"); myScanlineCountLast = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myScanlineCountLast->setToolTip("Number of scanlines of last frame."); myScanlineCountLast->setEditable(false, true); myScanlineCount = new EditTextWidget(boss, nfont, xpos + lwidth - myScanlineCountLast->getWidth() - 2, ypos - 1, fwidth, lineHeight); + myScanlineCount->setToolTip("Current scanline of this frame."); myScanlineCount->setEditable(false, true); // Right: Scan Cycle ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle" : "Scn Cycle"); myScanlineCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myScanlineCycles->setToolTip("CPU cycles in current scanline."); myScanlineCycles->setEditable(false, true); // Right: Pixel Pos ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Pixel Pos"); myPixelPosition = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myPixelPosition->setToolTip("Pixel position in current scanline."); myPixelPosition->setEditable(false, true); // Right: Color Clock ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Color Clock" : "Color Clk"); myColorClocks = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight); + myColorClocks->setToolTip("Color clocks in current scanline."); myColorClocks->setEditable(false, true); // Calculate actual dimensions From a660861008adf479525c7283ab3fb86c6af7251f Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 17 Nov 2020 18:37:10 -0330 Subject: [PATCH 214/263] Fixed minor clang warnings, and implemented clang-tidy suggestions. --- src/debugger/gui/RomListWidget.cxx | 6 +++--- src/debugger/gui/ToggleWidget.cxx | 8 +------- src/debugger/gui/ToggleWidget.hxx | 16 ++++++++-------- src/gui/ToolTip.cxx | 7 +++++-- src/gui/ToolTip.hxx | 4 ++-- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 72f3a0b03..504f7443d 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -465,14 +465,14 @@ string RomListWidget::getToolTip(Common::Point pos) const const string bytes = myDisasm->list[idx.y].bytes; - if(bytes.length() < idx.x + 1) + if(bytes.length() < size_t(idx.x + 1)) return EmptyString; Int32 val; if(bytes.length() == 8 && bytes[2] != ' ') { // Binary value - val = stol(bytes, 0, 2); + val = static_cast(stol(bytes, 0, 2)); } else { @@ -484,7 +484,7 @@ string RomListWidget::getToolTip(Common::Point pos) const // Get one hex byte const string valStr = bytes.substr((idx.x / 3) * 3, 2); - val = stol(valStr, 0, 16); + val = static_cast(stol(valStr, 0, 16)); } ostringstream buf; diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index e20544783..2a4187c6d 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -28,13 +28,7 @@ ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font, CommandSender(boss), _rows(rows), _cols(cols), - _currentRow(0), - _currentCol(0), - _rowHeight(0), - _colWidth(0), - _selectedItem(0), - _shiftBits(shiftBits), - _editable(true) + _shiftBits(shiftBits) { _flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS | Widget::FLAG_WANTS_RAWDATA; diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index 5f4ec13a7..3f74237b0 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -53,14 +53,14 @@ class ToggleWidget : public Widget, public CommandSender bool hasToolTip() const override { return true; } protected: - int _rows; - int _cols; - int _currentRow; - int _currentCol; - int _rowHeight; // explicitly set in child classes - int _colWidth; // explicitly set in child classes - int _selectedItem; - bool _editable; + int _rows{0}; + int _cols{0}; + int _currentRow{0}; + int _currentCol{0}; + int _rowHeight{0}; // explicitly set in child classes + int _colWidth{0}; // explicitly set in child classes + int _selectedItem{0}; + bool _editable{true}; bool _swapBits{false}; int _shiftBits{0}; // shift bits for tooltip display diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 85f5bedf4..77b5d5e20 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -62,7 +62,7 @@ void ToolTip::setFont(const GUI::Font& font) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToolTip::update(const Widget* widget, Common::Point pos) +void ToolTip::update(const Widget* widget, const Common::Point& pos) { if(myTipWidget != widget) { @@ -70,7 +70,10 @@ void ToolTip::update(const Widget* widget, Common::Point pos) release(); } if(myTipShown && myTipWidget->changedToolTip(myPos, pos)) - myPos = pos, show(); + { + myPos = pos; + show(); + } else myPos = pos; } diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index 879200c06..17ff2e7ec 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -59,9 +59,9 @@ class ToolTip void release(); /** - Update focussed widget and current mouse position. + Update focused widget and current mouse position. */ - void update(const Widget* widget, Common::Point pos); + void update(const Widget* widget, const Common::Point& pos); /* Render the tooltip From d7d813b901e4ecb22dcdca291a62921f0d840d48 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 17 Nov 2020 18:54:35 -0330 Subject: [PATCH 215/263] Fixed another minor clang warning. --- src/debugger/gui/RomListWidget.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 504f7443d..0d0d6c3fa 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -472,7 +472,7 @@ string RomListWidget::getToolTip(Common::Point pos) const if(bytes.length() == 8 && bytes[2] != ' ') { // Binary value - val = static_cast(stol(bytes, 0, 2)); + val = static_cast(stol(bytes, nullptr, 2)); } else { @@ -484,7 +484,7 @@ string RomListWidget::getToolTip(Common::Point pos) const // Get one hex byte const string valStr = bytes.substr((idx.x / 3) * 3, 2); - val = static_cast(stol(valStr, 0, 16)); + val = static_cast(stol(valStr, nullptr, 16)); } ostringstream buf; From 9aaca0bd4e01c17f4aba012d3120d9d0799cf719 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 18 Nov 2020 17:48:19 +0100 Subject: [PATCH 216/263] improved tooltip handling (better delays, rerender instead of redraw) added tooltip to StringListWidget for shortened texts (e.g. ROM names in launcher) added code for StaticTextWidget tooltip (without setting widget dirty) --- src/debugger/gui/RomListWidget.cxx | 2 +- src/gui/Dialog.cxx | 4 +- src/gui/EditableWidget.cxx | 8 +-- src/gui/EditableWidget.hxx | 1 + src/gui/GuiObject.hxx | 8 +-- src/gui/StringListWidget.cxx | 30 +++++++++ src/gui/StringListWidget.hxx | 9 +++ src/gui/ToolTip.cxx | 104 ++++++++++++++--------------- src/gui/ToolTip.hxx | 12 ++-- src/gui/Widget.cxx | 21 +++++- src/gui/Widget.hxx | 4 +- 11 files changed, 130 insertions(+), 73 deletions(-) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 0d0d6c3fa..861a4112d 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -40,6 +40,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, _textcolorhi = kTextColor; _editMode = false; + _dyCaret = 1; _cols = w / _fontWidth; _rows = h / _lineHeight; @@ -485,7 +486,6 @@ string RomListWidget::getToolTip(Common::Point pos) const const string valStr = bytes.substr((idx.x / 3) * 3, 2); val = static_cast(stol(valStr, nullptr, 16)); - } ostringstream buf; diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index a33b4ffa1..1b58d7729 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -432,9 +432,9 @@ void Dialog::drawDialog() FBSurface& s = surface(); - cerr << endl << "d"; if(isDirty()) { + cerr << endl << "d"; //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl; if(clearsBackground()) @@ -464,6 +464,8 @@ void Dialog::drawDialog() clearDirty(); } + else + cerr << endl; // Draw all children drawChain(); diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 39a4b519f..8ff411f83 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -107,7 +107,7 @@ void EditableWidget::receivedFocusWidget() { _caretTimer = 0; _caretEnabled = true; - dialog().tooltip().release(); + dialog().tooltip().hide(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -379,7 +379,7 @@ void EditableWidget::drawCaretSelection() x += _x; y += _y; - s.fillRect(x - 1, y + 1, w + 1, h - 3, kTextColorHi); + s.fillRect(x - 1, y + 1 + _dyCaret, w + 1, h - 3, kTextColorHi); s.drawString(_font, text, x, y + 1, w, h, kTextColorInv, TextAlign::Left, 0, false); } @@ -397,8 +397,8 @@ void EditableWidget::drawCaretSelection() x += _x; y += _y; - s.vLine(x, y + 1, y + editRect.h() - 3, color); - s.vLine(x - 1, y + 1, y + editRect.h() - 3, color); + s.vLine(x, y + 1 + _dyCaret, y + editRect.h() - 3, color); + s.vLine(x - 1, y + 1 + _dyCaret, y + editRect.h() - 3, color); clearDirty(); } } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 6e55cf541..497c2a4e8 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -125,6 +125,7 @@ class EditableWidget : public Widget, public CommandSender protected: int _editScrollOffset{0}; bool _editMode{true}; + int _dyCaret{0}; private: TextFilter _filter; diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx index 490df4344..85424a670 100644 --- a/src/gui/GuiObject.hxx +++ b/src/gui/GuiObject.hxx @@ -106,20 +106,20 @@ class GuiObject : public CommandReceiver virtual void tick() = 0; - void setFlags(uInt32 flags) + void setFlags(uInt32 flags, bool updateDirty = true) { uInt32 oldFlags = _flags; _flags |= flags; - if(oldFlags != _flags) + if(updateDirty && oldFlags != _flags) setDirty(); } - void clearFlags(uInt32 flags) + void clearFlags(uInt32 flags, bool updateDirty = true) { uInt32 oldFlags = _flags; _flags &= ~flags; - if(oldFlags != _flags) + if(updateDirty && oldFlags != _flags) setDirty(); } uInt32 getFlags() const { return _flags; } diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index ad5f1e7ec..74cf23e40 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -50,6 +50,36 @@ void StringListWidget::setList(const StringList& list) ListWidget::recalc(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int StringListWidget::getToolTipIndex(Common::Point pos) const +{ + return (pos.y - getAbsY()) / _lineHeight + _currentPos; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string StringListWidget::getToolTip(Common::Point pos) const +{ + Common::Rect rect = getEditRect(); + const string value = _list[getToolTipIndex(pos)]; + + if(uInt32(_font.getStringWidth(value)) > rect.w()) + return _toolTipText + value; + else + return _toolTipText; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool StringListWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +{ + bool ch = getToolTipIndex(oldPos) != getToolTipIndex(newPos) + && getToolTip(oldPos) != getToolTip(newPos); + + if(ch) + cerr << "changed" << endl; + + return ch; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StringListWidget::drawWidget(bool hilite) { diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx index ed5874b91..fb96a9e22 100644 --- a/src/gui/StringListWidget.hxx +++ b/src/gui/StringListWidget.hxx @@ -32,10 +32,16 @@ class StringListWidget : public ListWidget void setList(const StringList& list); bool wantsFocus() const override { return true; } + string getToolTip(Common::Point pos) const override; + bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; + protected: // display depends on _hasFocus so we have to redraw when focus changes void receivedFocusWidget() override { setDirty(); } void lostFocusWidget() override { setDirty(); } + + bool hasToolTip() const override { return true; } + void drawWidget(bool hilite) override; Common::Rect getEditRect() const override; @@ -43,6 +49,9 @@ class StringListWidget : public ListWidget bool _hilite{false}; int _textOfs{0}; + private: + int getToolTipIndex(Common::Point pos) const; + private: // Following constructors and assignment operators not supported StringListWidget() = delete; diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 77b5d5e20..5d37478db 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -17,6 +17,7 @@ #include "OSystem.hxx" #include "Dialog.hxx" +#include "DialogContainer.hxx" #include "Font.hxx" #include "FrameBuffer.hxx" #include "FBSurface.hxx" @@ -25,17 +26,8 @@ #include "ToolTip.hxx" // TODOs: -// + keep enabled when mouse moves over same widget -// + static position and text for normal widgets -// + moving position and text over e.g. DataGridWidget -// + reenable tip faster -// + disable when in edit mode // - option to disable tips // - multi line tips -// + nicer formating of DataDridWidget tip -// + allow reversing ToogleWidget (TooglePixelWidget) -// + shift checkbox bits -// - RomListWidget (hex codes, maybe disassembly operands) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) @@ -61,21 +53,48 @@ void ToolTip::setFont(const GUI::Font& font) mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ToolTip::request() +{ + // Called each frame when a tooltip is wanted + if(myFocusWidget && myTimer < DELAY_TIME * RELEASE_SPEED) + { + const string tip = myFocusWidget->getToolTip(myMousePos); + + if(!tip.empty()) + { + myTipWidget = myFocusWidget; + myTimer += RELEASE_SPEED; + if(myTimer >= DELAY_TIME * RELEASE_SPEED) + show(tip); + } + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToolTip::update(const Widget* widget, const Common::Point& pos) { + // Called each mouse move + myMousePos = pos; + myFocusWidget = widget; + if(myTipWidget != widget) - { - myFocusWidget = widget; - release(); - } - if(myTipShown && myTipWidget->changedToolTip(myPos, pos)) - { - myPos = pos; - show(); - } + release(false); + + if(!myTipShown) + release(true); else - myPos = pos; + { + if(myTipWidget->changedToolTip(myTipPos, myMousePos)) + { + const string tip = myTipWidget->getToolTip(myMousePos); + + if(!tip.empty()) + show(tip); + else + release(true); + } + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -85,65 +104,40 @@ void ToolTip::hide() { myTimer = 0; myTipWidget = myFocusWidget = nullptr; - myTipShown = false; - myDialog.setDirtyChain(); + myDialog.instance().frameBuffer().setPendingRender(); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToolTip::release() +void ToolTip::release(bool emptyTip) { if(myTipShown) { - myTimer = DELAY_TIME - 1; - myTipShown = false; - myDialog.setDirtyChain(); + myDialog.instance().frameBuffer().setPendingRender(); } // After displaying a tip, slowly reset the timer to 0 // until a new tip is requested - if(myTipWidget != myFocusWidget && myTimer) + if((emptyTip || myTipWidget != myFocusWidget) && myTimer) myTimer--; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToolTip::request() +void ToolTip::show(const string& tip) { - myTipWidget = myFocusWidget; - - if(myTimer == DELAY_TIME) - show(); - - myTimer++; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ToolTip::show() -{ - if(myTipWidget == nullptr) - return; + myTipPos = myMousePos; const uInt32 V_GAP = 1; const uInt32 H_CURSOR = 18; - string text = myTipWidget->getToolTip(myPos); - - myTipShown = true; - if(text.empty()) - { - release(); - return; - } - - uInt32 width = std::min(myWidth, myFont->getStringWidth(text) + myTextXOfs * 2); - //uInt32 height = std::min(myHeight, font.getFontHeight() + myTextYOfs * 2); + uInt32 width = std::min(myWidth, myFont->getStringWidth(tip) + myTextXOfs * 2); // Note: The rects include HiDPI scaling const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect(); const Common::Rect dialogRect = myDialog.surface().dstRect(); // Limit position to app size and adjust accordingly - const Int32 xAbs = myPos.x + dialogRect.x() / myScale; - const uInt32 yAbs = myPos.y + dialogRect.y() / myScale; + const Int32 xAbs = myTipPos.x + dialogRect.x() / myScale; + const uInt32 yAbs = myTipPos.y + dialogRect.y() / myScale; Int32 x = std::min(xAbs, Int32(imageRect.w() / myScale - width)); const uInt32 y = (yAbs + myHeight + H_CURSOR > imageRect.h() / myScale) ? yAbs - myHeight - V_GAP @@ -161,11 +155,11 @@ void ToolTip::show() mySurface->frameRect(0, 0, width, myHeight, kColor); mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); - mySurface->drawString(*myFont, text, myTextXOfs, myTextYOfs, + mySurface->drawString(*myFont, tip, myTextXOfs, myTextYOfs, width - myTextXOfs * 2, myHeight - myTextYOfs * 2, kTextColor); myTipShown = true; - myDialog.setDirtyChain(); + myDialog.instance().frameBuffer().setPendingRender(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index 17ff2e7ec..2c9f95037 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -56,7 +56,7 @@ class ToolTip Hide a displayed tooltip and reset the timer slowly. This allows faster tip display of the next tip. */ - void release(); + void release(bool emptyTip); /** Update focused widget and current mouse position. @@ -69,10 +69,13 @@ class ToolTip void render(); private: - void show(); + void show(const string& tip); private: - static constexpr uInt32 DELAY_TIME = 45; // display delay + static constexpr uInt32 DELAY_TIME = 45; // display delay [frames] + // Tips are slower released than requested, so that repeated tips are shown + // faster. This constant defines how much faster. + static constexpr uInt32 RELEASE_SPEED = 2; Dialog& myDialog; const GUI::Font* myFont{nullptr}; @@ -80,7 +83,8 @@ class ToolTip const Widget* myFocusWidget{nullptr}; uInt32 myTimer{0}; - Common::Point myPos; + Common::Point myMousePos; + Common::Point myTipPos; uInt32 myWidth{0}; uInt32 myHeight{0}; uInt32 myTextXOfs{0}; diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index cfb933965..23c72760d 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -97,8 +97,8 @@ void Widget::draw() if(isDirty()) { - //cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; - cerr << "w"; + cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; + //cerr << "w"; FBSurface& s = _boss->dialog().surface(); @@ -418,6 +418,23 @@ void StaticTextWidget::setLabel(const string& label) setDirty(); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void StaticTextWidget::handleMouseEntered() +{ + if(isEnabled()) + // Mouse focus for tooltips must not change dirty status + setFlags(Widget::FLAG_MOUSE_FOCUS, false); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void StaticTextWidget::handleMouseLeft() +{ + if(isEnabled()) + // Mouse focus for tooltips must not change dirty status + clearFlags(Widget::FLAG_MOUSE_FOCUS, false); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StaticTextWidget::drawWidget(bool hilite) { diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 45c676fe2..c5eb233b3 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -186,8 +186,8 @@ class StaticTextWidget : public Widget ColorId shadowColor = kNone); ~StaticTextWidget() override = default; - void handleMouseEntered() override {} - void handleMouseLeft() override {} + void handleMouseEntered() override; + void handleMouseLeft() override; void setValue(int value); void setLabel(const string& label); From c19cde6f118ef3e4456fe51c0d0e19a4dc222626 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 18 Nov 2020 20:07:25 +0100 Subject: [PATCH 217/263] added multi-line tooltip support --- src/debugger/gui/RomListWidget.cxx | 6 ++-- src/emucore/FBSurface.cxx | 52 +++++++++++++++++------------- src/emucore/FBSurface.hxx | 15 +++++++-- src/gui/EditableWidget.cxx | 8 ++--- src/gui/EditableWidget.hxx | 2 +- src/gui/ToolTip.cxx | 44 +++++++++++++++++-------- src/gui/ToolTip.hxx | 6 +++- 7 files changed, 84 insertions(+), 49 deletions(-) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 861a4112d..5f4487786 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -40,7 +40,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont, _textcolorhi = kTextColor; _editMode = false; - _dyCaret = 1; + _dyText = -1; // fixes the vertical position of selected text _cols = w / _fontWidth; _rows = h / _lineHeight; @@ -631,8 +631,8 @@ Common::Rect RomListWidget::getEditRect() const { const int yoffset = std::max(0, (_selectedItem - _currentPos) * _lineHeight); - return Common::Rect(2 + _w - _bytesWidth, 1 + yoffset, - _w, _lineHeight + yoffset); + return Common::Rect(2 + _w - _bytesWidth, 1 + yoffset + 1, + _w, _lineHeight + yoffset + 1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index c489fc703..cfcf58ff3 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -296,21 +296,39 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FBSurface::wrapString(const string& inStr, int pos, string& leftStr, string& rightStr) const +void FBSurface::splitString(const GUI::Font& font, const string& s, int w, + string& left, string& right) const { - for(int i = pos; i > 0; --i) + uInt32 pos; + int w2 = 0; + bool split = false; + + // SLOW algorithm to find the acceptable length. But it is good enough for now. + for(pos = 0; pos < s.size(); ++pos) { - if(isWhiteSpace(inStr[i])) + int charWidth = font.getCharWidth(s[pos]); + if(w2 + charWidth > w) { - leftStr = inStr.substr(0, i); - if(inStr[i] == ' ') // skip leading space after line break - i++; - rightStr = inStr.substr(i); - return; + split = true; + break; } + w2 += charWidth; } - leftStr = inStr.substr(0, pos); - rightStr = inStr.substr(pos); + + if(split) + for(int i = pos; i > 0; --i) + { + if(isWhiteSpace(s[i])) + { + left = s.substr(0, i); + if(s[i] == ' ') // skip leading space after line break + i++; + right = s.substr(i); + return; + } + } + left = s.substr(0, pos); + right = s.substr(pos); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -340,21 +358,9 @@ int FBSurface::drawString(const GUI::Font& font, const string& s, while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2) { // String is too wide. - uInt32 i; string leftStr, rightStr; - int w2 = 0; - // SLOW algorithm to find the acceptable length. But it is good enough for now. - for(i = 0; i < inStr.size(); ++i) - { - int charWidth = font.getCharWidth(inStr[i]); - if(w2 + charWidth > w) - break; - - w2 += charWidth; - //str += inStr[i]; - } - wrapString(inStr, i, leftStr, rightStr); + splitString(font, inStr, w, leftStr, rightStr); drawString(font, leftStr, x, y, w, color, align, deltax, false, shadowColor); h -= font.getFontHeight(); y += font.getFontHeight(); diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx index 71bddc289..de19fca28 100644 --- a/src/emucore/FBSurface.hxx +++ b/src/emucore/FBSurface.hxx @@ -247,6 +247,18 @@ class FBSurface ColorId color, TextAlign align = TextAlign::Left, int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone); + /** + Splits a given string to a given width considering whitespaces. + + @param font The font to draw the string with + @param s The string to split + @param w The width of the string area + @param left The left part of the split string + @param right The right part of the split string + */ + void splitString(const GUI::Font& font, const string& s, int w, + string& left, string& right) const; + /** The rendering attributes that can be modified for this texture. These probably can only be implemented in child FBSurfaces where @@ -383,9 +395,6 @@ class FBSurface */ bool checkBounds(const uInt32 x, const uInt32 y) const; - void wrapString(const string& inStr, int pos, - string& leftStr, string& rightStr) const; - /** Check if the given character is a whitespace. @param s Character to check diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index 8ff411f83..e015dd899 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -379,8 +379,8 @@ void EditableWidget::drawCaretSelection() x += _x; y += _y; - s.fillRect(x - 1, y + 1 + _dyCaret, w + 1, h - 3, kTextColorHi); - s.drawString(_font, text, x, y + 1, w, h, + s.fillRect(x - 1, y + 1, w + 1, h - 3, kTextColorHi); + s.drawString(_font, text, x, y + 1 + _dyText, w, h, kTextColorInv, TextAlign::Left, 0, false); } @@ -397,8 +397,8 @@ void EditableWidget::drawCaretSelection() x += _x; y += _y; - s.vLine(x, y + 1 + _dyCaret, y + editRect.h() - 3, color); - s.vLine(x - 1, y + 1 + _dyCaret, y + editRect.h() - 3, color); + s.vLine(x, y + 1, y + editRect.h() - 3, color); + s.vLine(x - 1, y + 1, y + editRect.h() - 3, color); clearDirty(); } } diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx index 497c2a4e8..3ffe09a65 100644 --- a/src/gui/EditableWidget.hxx +++ b/src/gui/EditableWidget.hxx @@ -125,7 +125,7 @@ class EditableWidget : public Widget, public CommandSender protected: int _editScrollOffset{0}; bool _editMode{true}; - int _dyCaret{0}; + int _dyText{0}; private: TextFilter _filter; diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 5d37478db..5cfed635c 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -27,7 +27,6 @@ // TODOs: // - option to disable tips -// - multi line tips // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) @@ -47,8 +46,8 @@ void ToolTip::setFont(const GUI::Font& font) myTextXOfs = fontHeight < 24 ? 5 : 8; myTextYOfs = fontHeight < 24 ? 2 : 3; - myWidth = fontWidth * MAX_LEN + myTextXOfs * 2; - myHeight = fontHeight + myTextYOfs * 2; + myWidth = fontWidth * MAX_COLUMNS + myTextXOfs * 2; + myHeight = fontHeight * MAX_ROWS + myTextYOfs * 2; mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight); } @@ -129,9 +128,30 @@ void ToolTip::show(const string& tip) { myTipPos = myMousePos; + uInt32 maxWidth = std::min(myWidth - myTextXOfs * 2, uInt32(myFont->getStringWidth(tip))); + + mySurface->fillRect(1, 1, maxWidth + myTextXOfs * 2 - 2, myHeight - 2, kWidColor); + int lines = std::min(MAX_ROWS, + uInt32(mySurface->drawString(*myFont, tip, myTextXOfs, myTextYOfs, + maxWidth, myHeight - myTextYOfs * 2, + kTextColor))); + // Calculate maximum width of drawn string lines + uInt32 width = 0; + string inStr = tip; + for(int i = 0; i < lines; ++i) + { + string leftStr, rightStr; + + mySurface->splitString(*myFont, inStr, maxWidth, leftStr, rightStr); + width = std::max(width, uInt32(myFont->getStringWidth(leftStr))); + inStr = rightStr; + } + width += myTextXOfs * 2; + + // Calculate and set surface size and position + const uInt32 height = std::min(myHeight, myFont->getFontHeight() * lines + myTextYOfs * 2); const uInt32 V_GAP = 1; const uInt32 H_CURSOR = 18; - uInt32 width = std::min(myWidth, myFont->getStringWidth(tip) + myTextXOfs * 2); // Note: The rects include HiDPI scaling const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect(); const Common::Rect dialogRect = myDialog.surface().dstRect(); @@ -139,24 +159,20 @@ void ToolTip::show(const string& tip) const Int32 xAbs = myTipPos.x + dialogRect.x() / myScale; const uInt32 yAbs = myTipPos.y + dialogRect.y() / myScale; Int32 x = std::min(xAbs, Int32(imageRect.w() / myScale - width)); - const uInt32 y = (yAbs + myHeight + H_CURSOR > imageRect.h() / myScale) - ? yAbs - myHeight - V_GAP + const uInt32 y = (yAbs + height + H_CURSOR > imageRect.h() / myScale) + ? yAbs - height - V_GAP : yAbs + H_CURSOR / myScale + V_GAP; if(x < 0) { x = 0; - width = imageRect.w() / myScale; + width = std::min(width, imageRect.w() / myScale); } - mySurface->setSrcSize(width, myHeight); - mySurface->setDstSize(width * myScale, myHeight * myScale); + mySurface->setSrcSize(width, height); + mySurface->setDstSize(width * myScale, height * myScale); mySurface->setDstPos(x * myScale, y * myScale); - - mySurface->frameRect(0, 0, width, myHeight, kColor); - mySurface->fillRect(1, 1, width - 2, myHeight - 2, kWidColor); - mySurface->drawString(*myFont, tip, myTextXOfs, myTextYOfs, - width - myTextXOfs * 2, myHeight - myTextYOfs * 2, kTextColor); + mySurface->frameRect(0, 0, width, height, kColor); myTipShown = true; myDialog.instance().frameBuffer().setPendingRender(); diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx index 2c9f95037..71da6dc13 100644 --- a/src/gui/ToolTip.hxx +++ b/src/gui/ToolTip.hxx @@ -33,9 +33,13 @@ class FBSurface; class ToolTip { + private: + static constexpr uInt32 MAX_COLUMNS = 60; + static constexpr uInt32 MAX_ROWS = 5; + public: // Maximum tooltip length - static constexpr uInt32 MAX_LEN = 80; + static constexpr uInt32 MAX_LEN = MAX_COLUMNS * MAX_ROWS; ToolTip(Dialog& dialog, const GUI::Font& font); ~ToolTip() = default; From 59f157187fb3fceb62e61d1318247263bcd3de95 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 18 Nov 2020 21:02:42 +0100 Subject: [PATCH 218/263] improved string wrapping (incl. '\n') fixed potential exception in StringListWidget --- src/emucore/FBSurface.cxx | 17 +++++++++++------ src/gui/StringListWidget.cxx | 14 ++++++++++++-- src/gui/ToolTip.cxx | 3 --- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index cfcf58ff3..6421dd171 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -307,7 +307,7 @@ void FBSurface::splitString(const GUI::Font& font, const string& s, int w, for(pos = 0; pos < s.size(); ++pos) { int charWidth = font.getCharWidth(s[pos]); - if(w2 + charWidth > w) + if(w2 + charWidth > w || s[pos] == '\n') { split = true; break; @@ -321,7 +321,7 @@ void FBSurface::splitString(const GUI::Font& font, const string& s, int w, if(isWhiteSpace(s[i])) { left = s.substr(0, i); - if(s[i] == ' ') // skip leading space after line break + if(s[i] == ' ' || s[pos] == '\n') // skip leading space after line break i++; right = s.substr(i); return; @@ -334,7 +334,7 @@ void FBSurface::splitString(const GUI::Font& font, const string& s, int w, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FBSurface::isWhiteSpace(const char s) const { - const string WHITESPACES = " ,.;:+-"; + const string WHITESPACES = " ,.;:+-*/'([\n"; for(size_t i = 0; i < WHITESPACES.length(); ++i) if(s == WHITESPACES[i]) @@ -349,13 +349,14 @@ int FBSurface::drawString(const GUI::Font& font, const string& s, ColorId color, TextAlign align, int deltax, bool useEllipsis, ColorId shadowColor) { - int lines = 1; + int lines = 0; #ifdef GUI_SUPPORT string inStr = s; // draw multiline string - while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2) + //while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2) + while(inStr.length() && h >= font.getFontHeight() * 2) { // String is too wide. string leftStr, rightStr; @@ -367,7 +368,11 @@ int FBSurface::drawString(const GUI::Font& font, const string& s, inStr = rightStr; lines++; } - drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor); + if(inStr.length()) + { + drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor); + lines++; + } #endif return lines; } diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 74cf23e40..04820090c 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -53,14 +53,24 @@ void StringListWidget::setList(const StringList& list) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int StringListWidget::getToolTipIndex(Common::Point pos) const { - return (pos.y - getAbsY()) / _lineHeight + _currentPos; + int idx = (pos.y - getAbsY()) / _lineHeight + _currentPos; + + if(idx >= int(_list.size())) + return -1; + else + return idx; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string StringListWidget::getToolTip(Common::Point pos) const { Common::Rect rect = getEditRect(); - const string value = _list[getToolTipIndex(pos)]; + int idx = getToolTipIndex(pos); + + if(idx < 0) + return EmptyString; + + const string value = _list[idx]; if(uInt32(_font.getStringWidth(value)) > rect.w()) return _toolTipText + value; diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 5cfed635c..6e6ef9fc9 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -25,9 +25,6 @@ #include "ToolTip.hxx" -// TODOs: -// - option to disable tips - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font) : myDialog(dialog) From 355dc9597d597048b637e9483424491dd24b0e9a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 18 Nov 2020 17:56:57 -0330 Subject: [PATCH 219/263] Use const references where appropriate. Probably not a huge performance gain, but added to match the rest of the code. --- src/debugger/gui/DataGridWidget.cxx | 7 ++++--- src/debugger/gui/DataGridWidget.hxx | 6 +++--- src/debugger/gui/RomListWidget.cxx | 9 +++++---- src/debugger/gui/RomListWidget.hxx | 6 +++--- src/debugger/gui/ToggleWidget.cxx | 10 ++++------ src/debugger/gui/ToggleWidget.hxx | 6 +++--- src/gui/StringListWidget.cxx | 7 ++++--- src/gui/StringListWidget.hxx | 6 +++--- src/gui/Widget.hxx | 5 +++-- 9 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 9e75a955f..fb078ba18 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -571,7 +571,7 @@ void DataGridWidget::handleCommand(CommandSender* sender, int cmd, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int DataGridWidget::getToolTipIndex(Common::Point pos) const +int DataGridWidget::getToolTipIndex(const Common::Point& pos) const { const int col = (pos.x - getAbsX()) / _colWidth; const int row = (pos.y - getAbsY()) / _rowHeight; @@ -580,7 +580,7 @@ int DataGridWidget::getToolTipIndex(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string DataGridWidget::getToolTip(Common::Point pos) const +string DataGridWidget::getToolTip(const Common::Point& pos) const { const Int32 val = _valueList[getToolTipIndex(pos)]; ostringstream buf; @@ -595,7 +595,8 @@ string DataGridWidget::getToolTip(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool DataGridWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +bool DataGridWidget::changedToolTip(const Common::Point& oldPos, + const Common::Point& newPos) const { return getToolTipIndex(oldPos) != getToolTipIndex(newPos); } diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index 1a402659d..37434db3c 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -84,8 +84,8 @@ class DataGridWidget : public EditableWidget void setCrossed(bool enable) { _crossGrid = enable; } - string getToolTip(Common::Point pos) const override; - bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; + string getToolTip(const Common::Point& pos) const override; + bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; protected: void drawWidget(bool hilite) override; @@ -150,7 +150,7 @@ class DataGridWidget : public EditableWidget void enableEditMode(bool state) { _editMode = state; } - int getToolTipIndex(Common::Point pos) const; + int getToolTipIndex(const Common::Point& pos) const; private: // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 5f4487786..236f99a31 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -444,7 +444,7 @@ void RomListWidget::lostFocusWidget() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Common::Point RomListWidget::getToolTipIndex(Common::Point pos) const +Common::Point RomListWidget::getToolTipIndex(const Common::Point& pos) const { const Common::Rect& r = getEditRect(); const int col = (pos.x - r.x() - getAbsX()) / _font.getMaxCharWidth(); @@ -457,9 +457,9 @@ Common::Point RomListWidget::getToolTipIndex(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string RomListWidget::getToolTip(Common::Point pos) const +string RomListWidget::getToolTip(const Common::Point& pos) const { - const Common::Point idx = getToolTipIndex(pos); + const Common::Point& idx = getToolTipIndex(pos); if(idx.y == -1) return EmptyString; @@ -499,7 +499,8 @@ string RomListWidget::getToolTip(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool RomListWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +bool RomListWidget::changedToolTip(const Common::Point& oldPos, + const Common::Point& newPos) const { return getToolTipIndex(oldPos) != getToolTipIndex(newPos); } diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx index 3f26d217f..9baa9350a 100644 --- a/src/debugger/gui/RomListWidget.hxx +++ b/src/debugger/gui/RomListWidget.hxx @@ -56,8 +56,8 @@ class RomListWidget : public EditableWidget void setSelected(int item); void setHighlighted(int item); - string getToolTip(Common::Point pos) const override; - bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; + string getToolTip(const Common::Point& pos) const override; + bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; protected: void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; @@ -88,7 +88,7 @@ class RomListWidget : public EditableWidget private: void scrollToCurrent(int item); - Common::Point getToolTipIndex(Common::Point pos) const; + Common::Point getToolTipIndex(const Common::Point& pos) const; private: unique_ptr myMenu; diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index 2a4187c6d..4fced1146 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -205,7 +205,7 @@ void ToggleWidget::handleCommand(CommandSender* sender, int cmd, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int ToggleWidget::getToolTipIndex(Common::Point pos) const +int ToggleWidget::getToolTipIndex(const Common::Point& pos) const { const int row = (pos.y - getAbsY()) / _rowHeight; @@ -213,7 +213,7 @@ int ToggleWidget::getToolTipIndex(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ToggleWidget::getToolTip(Common::Point pos) const +string ToggleWidget::getToolTip(const Common::Point& pos) const { const int idx = getToolTipIndex(pos); Int32 val = 0; @@ -243,10 +243,8 @@ string ToggleWidget::getToolTip(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ToggleWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +bool ToggleWidget::changedToolTip(const Common::Point& oldPos, + const Common::Point& newPos) const { return getToolTipIndex(oldPos) != getToolTipIndex(newPos); } - - - diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index 3f74237b0..347359677 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -46,8 +46,8 @@ class ToggleWidget : public Widget, public CommandSender void setEditable(bool editable) { _editable = editable; } bool isEditable() const { return _editable; } - string getToolTip(Common::Point pos) const override; - bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; + string getToolTip(const Common::Point& pos) const override; + bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; protected: bool hasToolTip() const override { return true; } @@ -76,7 +76,7 @@ class ToggleWidget : public Widget, public CommandSender bool handleKeyDown(StellaKey key, StellaMod mod) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - int getToolTipIndex(Common::Point pos) const; + int getToolTipIndex(const Common::Point& pos) const; // Following constructors and assignment operators not supported ToggleWidget() = delete; diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 04820090c..a512425b5 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -51,7 +51,7 @@ void StringListWidget::setList(const StringList& list) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int StringListWidget::getToolTipIndex(Common::Point pos) const +int StringListWidget::getToolTipIndex(const Common::Point& pos) const { int idx = (pos.y - getAbsY()) / _lineHeight + _currentPos; @@ -62,7 +62,7 @@ int StringListWidget::getToolTipIndex(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string StringListWidget::getToolTip(Common::Point pos) const +string StringListWidget::getToolTip(const Common::Point& pos) const { Common::Rect rect = getEditRect(); int idx = getToolTipIndex(pos); @@ -79,7 +79,8 @@ string StringListWidget::getToolTip(Common::Point pos) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool StringListWidget::changedToolTip(Common::Point oldPos, Common::Point newPos) const +bool StringListWidget::changedToolTip(const Common::Point& oldPos, + const Common::Point& newPos) const { bool ch = getToolTipIndex(oldPos) != getToolTipIndex(newPos) && getToolTip(oldPos) != getToolTip(newPos); diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx index fb96a9e22..f0bf8544b 100644 --- a/src/gui/StringListWidget.hxx +++ b/src/gui/StringListWidget.hxx @@ -32,8 +32,8 @@ class StringListWidget : public ListWidget void setList(const StringList& list); bool wantsFocus() const override { return true; } - string getToolTip(Common::Point pos) const override; - bool changedToolTip(Common::Point oldPos, Common::Point newPos) const override; + string getToolTip(const Common::Point& pos) const override; + bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; protected: // display depends on _hasFocus so we have to redraw when focus changes @@ -50,7 +50,7 @@ class StringListWidget : public ListWidget int _textOfs{0}; private: - int getToolTipIndex(Common::Point pos) const; + int getToolTipIndex(const Common::Point& pos) const; private: // Following constructors and assignment operators not supported diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index c5eb233b3..64685813a 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -106,8 +106,9 @@ class Widget : public GuiObject void setShadowColor(ColorId color) { _shadowcolor = color; setDirty(); } void setToolTip(const string& text); - virtual string getToolTip(Common::Point pos) const { return _toolTipText; } - virtual bool changedToolTip(Common::Point oldPos, Common::Point newPos) const { return false; } + virtual string getToolTip(const Common::Point& pos) const { return _toolTipText; } + virtual bool changedToolTip(const Common::Point& oldPos, + const Common::Point& newPos) const { return false; } virtual void loadConfig() { } From d0e818a693c32f926b17a123070f3702b782dd54 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 18 Nov 2020 23:52:19 +0100 Subject: [PATCH 220/263] added a few more tooltips to VideoAudioDialog --- src/gui/VideoAudioDialog.cxx | 8 ++++++++ src/gui/VideoAudioDialog.hxx | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx index def965aa6..ac2ad19bf 100644 --- a/src/gui/VideoAudioDialog.cxx +++ b/src/gui/VideoAudioDialog.cxx @@ -237,6 +237,7 @@ void VideoAudioDialog::addPaletteTab() myPhaseShiftNtsc->setMinValue((PaletteHandler::DEF_NTSC_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10); myPhaseShiftNtsc->setMaxValue((PaletteHandler::DEF_NTSC_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10); myPhaseShiftNtsc->setTickmarkIntervals(4); + myPhaseShiftNtsc->setToolTip("Adjust NTSC phase shift of 'Custom' palette."); wid.push_back(myPhaseShiftNtsc); ypos += lineHeight + VGAP; @@ -246,6 +247,7 @@ void VideoAudioDialog::addPaletteTab() myPhaseShiftPal->setMinValue((PaletteHandler::DEF_PAL_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10); myPhaseShiftPal->setMaxValue((PaletteHandler::DEF_PAL_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10); myPhaseShiftPal->setTickmarkIntervals(4); + myPhaseShiftPal->setToolTip("Adjust PAL phase shift of 'Custom' palette."); wid.push_back(myPhaseShiftPal); ypos += lineHeight + VGAP; @@ -258,6 +260,7 @@ void VideoAudioDialog::addPaletteTab() myTVRedScale->setMinValue(0); myTVRedScale->setMaxValue(100); myTVRedScale->setTickmarkIntervals(2); + myTVRedScale->setToolTip("Adjust red saturation of 'Custom' palette."); wid.push_back(myTVRedScale); const int xposr = myTIAPalette->getRight() - rgbsWidth; @@ -267,6 +270,7 @@ void VideoAudioDialog::addPaletteTab() myTVRedShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10); myTVRedShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10); myTVRedShift->setTickmarkIntervals(2); + myTVRedShift->setToolTip("Adjust red shift of 'Custom' palette."); wid.push_back(myTVRedShift); ypos += lineHeight + VGAP; @@ -276,6 +280,7 @@ void VideoAudioDialog::addPaletteTab() myTVGreenScale->setMinValue(0); myTVGreenScale->setMaxValue(100); myTVGreenScale->setTickmarkIntervals(2); + myTVGreenScale->setToolTip("Adjust green saturation of 'Custom' palette."); wid.push_back(myTVGreenScale); myTVGreenShift = @@ -284,6 +289,7 @@ void VideoAudioDialog::addPaletteTab() myTVGreenShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10); myTVGreenShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10); myTVGreenShift->setTickmarkIntervals(2); + myTVGreenShift->setToolTip("Adjust green shift of 'Custom' palette."); wid.push_back(myTVGreenShift); ypos += lineHeight + VGAP; @@ -293,6 +299,7 @@ void VideoAudioDialog::addPaletteTab() myTVBlueScale->setMinValue(0); myTVBlueScale->setMaxValue(100); myTVBlueScale->setTickmarkIntervals(2); + myTVBlueScale->setToolTip("Adjust blue saturation of 'Custom' palette."); wid.push_back(myTVBlueScale); myTVBlueShift = @@ -301,6 +308,7 @@ void VideoAudioDialog::addPaletteTab() myTVBlueShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10); myTVBlueShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10); myTVBlueShift->setTickmarkIntervals(2); + myTVBlueShift->setToolTip("Adjust blue shift of 'Custom' palette."); wid.push_back(myTVBlueShift); ypos += lineHeight + VGAP; xpos -= INDENT; diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index 1d0e8a637..0c8c44bf7 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -16,7 +16,7 @@ //============================================================================ #ifndef VIDEOAUDIO_DIALOG_HXX -#define VIDEOAUDIO_DIALOG_HXX +#define D class CommandSender; class CheckboxWidget; From 9ab2a5c41745db578f4cd5fe4a89da37b93bc12a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 18 Nov 2020 23:54:43 +0100 Subject: [PATCH 221/263] disable tooltip when displayed value changes/is edited --- src/debugger/gui/DataGridWidget.cxx | 6 +++++- src/debugger/gui/RomListWidget.cxx | 3 +++ src/debugger/gui/ToggleWidget.cxx | 4 ++++ src/gui/StringListWidget.cxx | 4 ++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index fb078ba18..4304ecb0e 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -17,6 +17,7 @@ #include "Widget.hxx" #include "Dialog.hxx" +#include "ToolTip.hxx" #include "Font.hxx" #include "OSystem.hxx" #include "Debugger.hxx" @@ -294,6 +295,7 @@ void DataGridWidget::handleMouseWheel(int x, int y, int direction) else if(direction < 0) incrementCell(); } + dialog().tooltip().hide(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -491,6 +493,7 @@ bool DataGridWidget::handleKeyDown(StellaKey key, StellaMod mod) sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id); setDirty(); + dialog().tooltip().hide(); } _currentKeyDown = key; @@ -582,7 +585,8 @@ int DataGridWidget::getToolTipIndex(const Common::Point& pos) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string DataGridWidget::getToolTip(const Common::Point& pos) const { - const Int32 val = _valueList[getToolTipIndex(pos)]; + const int idx = getToolTipIndex(pos); + const Int32 val = _valueList[idx]; ostringstream buf; buf << _toolTipText diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 236f99a31..c06675e32 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -20,6 +20,8 @@ #include "Debugger.hxx" #include "DiStella.hxx" #include "Widget.hxx" +#include "Dialog.hxx" +#include "ToolTip.hxx" #include "StellaKeys.hxx" #include "FBSurface.hxx" #include "Font.hxx" @@ -646,6 +648,7 @@ void RomListWidget::startEditMode() return; _editMode = true; + dialog().tooltip().hide(); switch(myDisasm->list[_selectedItem].type) { case Device::GFX: diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index 4fced1146..ac321f4bf 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -19,6 +19,8 @@ #include "Base.hxx" #include "StellaKeys.hxx" #include "Widget.hxx" +#include "Dialog.hxx" +#include "ToolTip.hxx" #include "ToggleWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -51,6 +53,7 @@ void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) _selectedItem = newSelectedItem; _currentRow = _selectedItem / _cols; _currentCol = _selectedItem - (_currentRow * _cols); + dialog().tooltip().hide(); setDirty(); } } @@ -182,6 +185,7 @@ bool ToggleWidget::handleKeyDown(StellaKey key, StellaMod mod) _stateList[_selectedItem] = !_stateList[_selectedItem]; _changedList[_selectedItem] = !_changedList[_selectedItem]; sendCommand(ToggleWidget::kItemDataChangedCmd, _selectedItem, _id); + dialog().tooltip().hide(); } setDirty(); diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index a512425b5..536240b8a 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -56,9 +56,9 @@ int StringListWidget::getToolTipIndex(const Common::Point& pos) const int idx = (pos.y - getAbsY()) / _lineHeight + _currentPos; if(idx >= int(_list.size())) - return -1; + return -1; else - return idx; + return idx; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From db8e6d3ea8e1f0b6b9fae226fe5d6f25505c1142 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 18 Nov 2020 22:18:07 -0330 Subject: [PATCH 222/263] Fix some clang warnings and minor typo. --- src/debugger/gui/Cart3EWidget.cxx | 2 +- src/debugger/gui/RomListWidget.cxx | 2 +- src/gui/VideoAudioDialog.hxx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/debugger/gui/Cart3EWidget.cxx b/src/debugger/gui/Cart3EWidget.cxx index 910f03368..9e0822b51 100644 --- a/src/debugger/gui/Cart3EWidget.cxx +++ b/src/debugger/gui/Cart3EWidget.cxx @@ -117,7 +117,7 @@ void Cartridge3EWidget::loadConfig() myBankWidgets[1]->setSelectedIndex(bank - myCart.romBankCount(), oldBank != bank); } - CartDebugWidget::loadConfig(); + CartDebugWidget::loadConfig(); // Intentionally calling grand-parent method } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index c06675e32..868b72cdf 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -468,7 +468,7 @@ string RomListWidget::getToolTip(const Common::Point& pos) const const string bytes = myDisasm->list[idx.y].bytes; - if(bytes.length() < size_t(idx.x + 1)) + if(static_cast(bytes.length()) < idx.x + 1) return EmptyString; Int32 val; diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx index 0c8c44bf7..550617d2d 100644 --- a/src/gui/VideoAudioDialog.hxx +++ b/src/gui/VideoAudioDialog.hxx @@ -16,7 +16,7 @@ //============================================================================ #ifndef VIDEOAUDIO_DIALOG_HXX -#define D +#define VIDEOAUDIO_DIALOG_HXX class CommandSender; class CheckboxWidget; @@ -38,7 +38,7 @@ class VideoAudioDialog : public Dialog { public: VideoAudioDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, - int max_w, int max_h); + int max_w, int max_h); ~VideoAudioDialog() override = default; private: From 2bdd09fec99e0743d85549973af33ebfed1b7889 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 19 Nov 2020 12:25:07 +0100 Subject: [PATCH 223/263] added tooltip display of RAM labels in DataGridWidgets added tooltip display of labels of some ToggleBitsWidget bits merged tooltip display of 2nd and 3rd RomListWidget byte added tooltip display of signed values --- src/debugger/gui/CartRamWidget.hxx | 2 +- src/debugger/gui/DataGridWidget.cxx | 13 ++++++++++- src/debugger/gui/DataGridWidget.hxx | 2 +- src/debugger/gui/RamWidget.cxx | 6 ++--- src/debugger/gui/RamWidget.hxx | 6 +++-- src/debugger/gui/RiotRamWidget.hxx | 3 ++- src/debugger/gui/RiotWidget.cxx | 26 +++++++++++++++++++-- src/debugger/gui/RomListWidget.cxx | 23 ++++++++++++++----- src/debugger/gui/ToggleBitWidget.cxx | 34 ++++++++++++++++++++++++++-- src/debugger/gui/ToggleBitWidget.hxx | 6 +++++ src/debugger/gui/ToggleWidget.cxx | 14 +++++++++--- src/debugger/gui/ToggleWidget.hxx | 3 +-- src/debugger/gui/module.mk | 1 + src/windows/Stella.vcxproj | 6 +++++ src/windows/Stella.vcxproj.filters | 6 +++++ 15 files changed, 127 insertions(+), 24 deletions(-) diff --git a/src/debugger/gui/CartRamWidget.hxx b/src/debugger/gui/CartRamWidget.hxx index bc0f4f810..d24a5d134 100644 --- a/src/debugger/gui/CartRamWidget.hxx +++ b/src/debugger/gui/CartRamWidget.hxx @@ -67,11 +67,11 @@ class CartRamWidget : public Widget, public CommandSender int x, int y, int w, int h, CartDebugWidget& cartDebug); ~InternalRamWidget() override = default; + string getLabel(int addr) const override; private: uInt8 getValue(int addr) const override; void setValue(int addr, uInt8 value) override; - string getLabel(int addr) const override; void fillList(uInt32 start, uInt32 size, IntArray& alist, IntArray& vlist, BoolArray& changed) const override; diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 4304ecb0e..5d0dc0623 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -579,13 +579,20 @@ int DataGridWidget::getToolTipIndex(const Common::Point& pos) const const int col = (pos.x - getAbsX()) / _colWidth; const int row = (pos.y - getAbsY()) / _rowHeight; - return row * _cols + col; + if(row >= 0 && row < _rows && col >= 0 && col < _cols) + return row * _cols + col; + else + return -1; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string DataGridWidget::getToolTip(const Common::Point& pos) const { const int idx = getToolTipIndex(pos); + + if(idx < 0) + return EmptyString; + const Int32 val = _valueList[idx]; ostringstream buf; @@ -593,7 +600,11 @@ string DataGridWidget::getToolTip(const Common::Point& pos) const << "$" << Common::Base::toString(val, Common::Base::Fmt::_16) << " = #" << val; if(val < 0x100) + { + if(val >= 0x80) + buf << '/' << -(0x100 - val); buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2); + } return buf.str(); } diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index 37434db3c..848993311 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -102,6 +102,7 @@ class DataGridWidget : public EditableWidget void lostFocusWidget() override; bool hasToolTip() const override { return true; } + int getToolTipIndex(const Common::Point& pos) const; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseUp(int x, int y, MouseButton b, int clickCount) override; @@ -150,7 +151,6 @@ class DataGridWidget : public EditableWidget void enableEditMode(bool state) { _editMode = state; } - int getToolTipIndex(const Common::Point& pos) const; private: // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/RamWidget.cxx b/src/debugger/gui/RamWidget.cxx index 77456f810..7f651910a 100644 --- a/src/debugger/gui/RamWidget.cxx +++ b/src/debugger/gui/RamWidget.cxx @@ -15,7 +15,7 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "DataGridWidget.hxx" +#include "DataGridRamWidget.hxx" #include "EditTextWidget.hxx" #include "GuiObject.hxx" #include "InputTextDialog.hxx" @@ -54,8 +54,8 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n // Add RAM grid (with scrollbar) int xpos = x + _font.getStringWidth("xxxx"); bool useScrollbar = ramsize / numrows > 16; - myRamGrid = new DataGridWidget(_boss, _nfont, xpos, ypos, - 16, myNumRows, 2, 8, Common::Base::Fmt::_16, useScrollbar); + myRamGrid = new DataGridRamWidget(_boss, *this, _nfont, xpos, ypos, + 16, myNumRows, 2, 8, Common::Base::Fmt::_16, useScrollbar); myRamGrid->setTarget(this); myRamGrid->setID(kRamGridID); addFocusWidget(myRamGrid); diff --git a/src/debugger/gui/RamWidget.hxx b/src/debugger/gui/RamWidget.hxx index fbc7747e6..069086fef 100644 --- a/src/debugger/gui/RamWidget.hxx +++ b/src/debugger/gui/RamWidget.hxx @@ -22,6 +22,7 @@ class GuiObject; class ButtonWidget; class DataGridWidget; class DataGridOpsWidget; +class DataGridRamWidget; class EditTextWidget; class StaticTextWidget; class InputTextDialog; @@ -41,11 +42,12 @@ class RamWidget : public Widget, public CommandSender void setOpsWidget(DataGridOpsWidget* w); void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + virtual string getLabel(int addr) const = 0; + private: // To be implemented by derived classes virtual uInt8 getValue(int addr) const = 0; virtual void setValue(int addr, uInt8 value) = 0; - virtual string getLabel(int addr) const = 0; virtual void fillList(uInt32 start, uInt32 size, IntArray& alist, IntArray& vlist, @@ -97,7 +99,7 @@ class RamWidget : public Widget, public CommandSender StaticTextWidget* myRamStart{nullptr}; std::array myRamLabels{nullptr}; - DataGridWidget* myRamGrid{nullptr}; + DataGridRamWidget* myRamGrid{nullptr}; DataGridWidget* myHexValue{nullptr}; DataGridWidget* myDecValue{nullptr}; DataGridWidget* myBinValue{nullptr}; diff --git a/src/debugger/gui/RiotRamWidget.hxx b/src/debugger/gui/RiotRamWidget.hxx index 53d006bb0..3e30fc3e0 100644 --- a/src/debugger/gui/RiotRamWidget.hxx +++ b/src/debugger/gui/RiotRamWidget.hxx @@ -36,10 +36,11 @@ class RiotRamWidget : public RamWidget int x, int y, int w); ~RiotRamWidget() override = default; + string getLabel(int addr) const override; + private: uInt8 getValue(int addr) const override; void setValue(int addr, uInt8 value) override; - string getLabel(int addr) const override; void fillList(uInt32 start, uInt32 size, IntArray& alist, IntArray& vlist, BoolArray& changed) const override; diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index 73a70391f..053ff1325 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -66,11 +66,13 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, on.push_back("1"); } + StringList labels; + #define CREATE_IO_REGS(desc, bits, bitsID, editable) \ t = new StaticTextWidget(boss, lfont, xpos, ypos+2, lwidth, fontHeight,\ - desc, TextAlign::Left); \ + desc); \ xpos += t->getWidth() + 5; \ - bits = new ToggleBitWidget(boss, nfont, xpos, ypos, 8, 1); \ + bits = new ToggleBitWidget(boss, nfont, xpos, ypos, 8, 1, 1, labels); \ bits->setTarget(this); \ bits->setID(bitsID); \ if(editable) addFocusWidget(bits); else bits->setEditable(false); \ @@ -78,6 +80,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, bits->setList(off, on); // SWCHA bits in 'poke' mode + labels.clear(); CREATE_IO_REGS("SWCHA(W)", mySWCHAWriteBits, kSWCHABitsID, true) col = xpos + 20; // remember this for adding widgets to the second column @@ -87,10 +90,20 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, // SWCHA bits in 'peek' mode xpos = 10; ypos += lineHeight + 5; + labels.clear(); + labels.push_back("P0 right"); + labels.push_back("P0 left"); + labels.push_back("P0 down"); + labels.push_back("P0 up"); + labels.push_back("P1 right"); + labels.push_back("P1 left"); + labels.push_back("P1 down"); + labels.push_back("P1 up"); CREATE_IO_REGS("SWCHA(R)", mySWCHAReadBits, kSWCHARBitsID, true) // SWCHB bits in 'poke' mode xpos = 10; ypos += 2 * lineHeight; + labels.clear(); CREATE_IO_REGS("SWCHB(W)", mySWCHBWriteBits, kSWCHBBitsID, true) // SWBCNT bits @@ -99,6 +112,15 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont, // SWCHB bits in 'peek' mode xpos = 10; ypos += lineHeight + 5; + labels.clear(); + labels.push_back("P1 difficulty"); + labels.push_back("P0 difficulty"); + labels.push_back(""); + labels.push_back(""); + labels.push_back("Color/B+W"); + labels.push_back(""); + labels.push_back("Select"); + labels.push_back("Reset"); CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, kSWCHBRBitsID, true) // Timer registers (R/W) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index 868b72cdf..aab298fad 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -452,7 +452,8 @@ Common::Point RomListWidget::getToolTipIndex(const Common::Point& pos) const const int col = (pos.x - r.x() - getAbsX()) / _font.getMaxCharWidth(); const int row = (pos.y - getAbsY()) / _lineHeight; - if(col < 0) + if(col < 0 || col >= 8 + || row < 0 || row + _currentPos >= int(myDisasm->list.size())) return Common::Point(-1, -1); else return Common::Point(col, row + _currentPos); @@ -463,7 +464,7 @@ string RomListWidget::getToolTip(const Common::Point& pos) const { const Common::Point& idx = getToolTipIndex(pos); - if(idx.y == -1) + if(idx.y < 0) return EmptyString; const string bytes = myDisasm->list[idx.y].bytes; @@ -480,12 +481,18 @@ string RomListWidget::getToolTip(const Common::Point& pos) const else { // 1..3 hex values - if(idx.x % 3 == 2) - // Skip gaps between hex values + if(idx.x == 2) + // Skip gap after first byte return EmptyString; - // Get one hex byte - const string valStr = bytes.substr((idx.x / 3) * 3, 2); + string valStr; + + if(idx.x < 2 || bytes.length() < 8) + // 1 or 2 hex bytes, get one hex byte + valStr = bytes.substr((idx.x / 3) * 3, 2); + else + // 3 hex bytes, get two rightmost hex bytes + valStr = bytes.substr(6, 2) + bytes.substr(3, 2); val = static_cast(stol(valStr, nullptr, 16)); } @@ -495,7 +502,11 @@ string RomListWidget::getToolTip(const Common::Point& pos) const << "$" << Common::Base::toString(val, Common::Base::Fmt::_16) << " = #" << val; if(val < 0x100) + { + if(val >= 0x80) + buf << '/' << -(0x100 - val); buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2); + } return buf.str(); } diff --git a/src/debugger/gui/ToggleBitWidget.cxx b/src/debugger/gui/ToggleBitWidget.cxx index 39ca7dcce..212ae60ed 100644 --- a/src/debugger/gui/ToggleBitWidget.cxx +++ b/src/debugger/gui/ToggleBitWidget.cxx @@ -25,8 +25,10 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font, - int x, int y, int cols, int rows, int colchars) - : ToggleWidget(boss, font, x, y, cols, rows) + int x, int y, int cols, int rows, int colchars, + const StringList& labels) + : ToggleWidget(boss, font, x, y, cols, rows), + _labelList(labels) { _rowHeight = font.getLineHeight(); _colWidth = colchars * font.getMaxCharWidth() + 8; @@ -47,6 +49,13 @@ ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font, _h = _rowHeight * rows + 1; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font, + int x, int y, int cols, int rows, int colchars) + : ToggleBitWidget(boss, font, x, y, cols, rows, colchars, StringList()) +{ +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToggleBitWidget::setList(const StringList& off, const StringList& on) { @@ -69,6 +78,27 @@ void ToggleBitWidget::setState(const BoolArray& state, const BoolArray& changed) setDirty(); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string ToggleBitWidget::getToolTip(const Common::Point& pos) const +{ + Common::Point idx = getToolTipIndex(pos); + + if(idx.y < 0) + return EmptyString; + + const string tip = ToggleWidget::getToolTip(pos); + + if(idx.x < _labelList.size()) + { + const string label = _labelList[idx.x]; + + if(!label.empty()) + return tip + "\n" + label; + } + return tip; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToggleBitWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/ToggleBitWidget.hxx b/src/debugger/gui/ToggleBitWidget.hxx index 6d5505030..707aea1cc 100644 --- a/src/debugger/gui/ToggleBitWidget.hxx +++ b/src/debugger/gui/ToggleBitWidget.hxx @@ -26,17 +26,23 @@ class ToggleBitWidget : public ToggleWidget public: ToggleBitWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int cols, int rows, int colchars = 1); + ToggleBitWidget(GuiObject* boss, const GUI::Font& font, + int x, int y, int cols, int rows, int colchars, + const StringList& labels); ~ToggleBitWidget() override = default; void setList(const StringList& off, const StringList& on); void setState(const BoolArray& state, const BoolArray& changed); + string getToolTip(const Common::Point& pos) const override; + protected: void drawWidget(bool hilite) override; protected: StringList _offList; StringList _onList; + StringList _labelList; private: // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx index ac321f4bf..adb33e118 100644 --- a/src/debugger/gui/ToggleWidget.cxx +++ b/src/debugger/gui/ToggleWidget.cxx @@ -209,17 +209,25 @@ void ToggleWidget::handleCommand(CommandSender* sender, int cmd, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int ToggleWidget::getToolTipIndex(const Common::Point& pos) const +Common::Point ToggleWidget::getToolTipIndex(const Common::Point& pos) const { + const int col = (pos.x - getAbsX()) / _colWidth; const int row = (pos.y - getAbsY()) / _rowHeight; - return row * _cols; + if(row >= 0 && row < _rows && col >= 0 && col < _cols) + return Common::Point(col, row); + else + return Common::Point(-1, -1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string ToggleWidget::getToolTip(const Common::Point& pos) const { - const int idx = getToolTipIndex(pos); + const int idx = getToolTipIndex(pos).y * _cols; + + if(idx < 0) + return EmptyString; + Int32 val = 0; ostringstream buf; diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx index 347359677..ee70f6233 100644 --- a/src/debugger/gui/ToggleWidget.hxx +++ b/src/debugger/gui/ToggleWidget.hxx @@ -51,6 +51,7 @@ class ToggleWidget : public Widget, public CommandSender protected: bool hasToolTip() const override { return true; } + Common::Point getToolTipIndex(const Common::Point& pos) const; protected: int _rows{0}; @@ -76,8 +77,6 @@ class ToggleWidget : public Widget, public CommandSender bool handleKeyDown(StellaKey key, StellaMod mod) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - int getToolTipIndex(const Common::Point& pos) const; - // Following constructors and assignment operators not supported ToggleWidget() = delete; ToggleWidget(const ToggleWidget&) = delete; diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index cda7666e9..0a985e71b 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -55,6 +55,7 @@ MODULE_OBJS := \ src/debugger/gui/CartDebugWidget.o \ src/debugger/gui/CpuWidget.o \ src/debugger/gui/DataGridOpsWidget.o \ + src/debugger/gui/DataGridRamWidget.o \ src/debugger/gui/DataGridWidget.o \ src/debugger/gui/DebuggerDialog.o \ src/debugger/gui/DelayQueueWidget.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index f9b5d3499..76e311ce3 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -525,6 +525,9 @@ true + + true + true @@ -1550,6 +1553,9 @@ true + + true + true diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 550419e9a..6db5675f0 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1035,6 +1035,9 @@ Source Files\gui + + Source Files\debugger + @@ -2129,6 +2132,9 @@ Header Files\gui + + Header Files\debugger + From b77afae17840dae057ad14d70e9e58181b81e57c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 19 Nov 2020 12:26:03 +0100 Subject: [PATCH 224/263] oops, added missing files --- src/debugger/DataGridRamWidget.cxx | 54 ++++++++++++++++++++++++++++++ src/debugger/DataGridRamWidget.hxx | 51 ++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/debugger/DataGridRamWidget.cxx create mode 100644 src/debugger/DataGridRamWidget.hxx diff --git a/src/debugger/DataGridRamWidget.cxx b/src/debugger/DataGridRamWidget.cxx new file mode 100644 index 000000000..9be4c4f14 --- /dev/null +++ b/src/debugger/DataGridRamWidget.cxx @@ -0,0 +1,54 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "RamWidget.hxx" +#include "DataGridRamWidget.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +DataGridRamWidget::DataGridRamWidget(GuiObject* boss, const RamWidget& ram, + const GUI::Font& font, + int x, int y, int cols, int rows, + int colchars, int bits, + Common::Base::Fmt base, + bool useScrollbar) + : DataGridWidget(boss, font, x, y, cols, rows, colchars, + bits, base, useScrollbar), + _ram(ram) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string DataGridRamWidget::getToolTip(const Common::Point& pos) const +{ + const int idx = getToolTipIndex(pos); + + if(idx < 0) + return EmptyString; + + const Int32 addr = _addrList[idx]; + const string label = _ram.getLabel(addr); + const string tip = DataGridWidget::getToolTip(pos); + + if(label.empty()) + return tip; + + ostringstream buf; + + buf << _ram.getLabel(addr) << '\n' << tip; + + return buf.str(); +} diff --git a/src/debugger/DataGridRamWidget.hxx b/src/debugger/DataGridRamWidget.hxx new file mode 100644 index 000000000..451c23403 --- /dev/null +++ b/src/debugger/DataGridRamWidget.hxx @@ -0,0 +1,51 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef DATA_GRID_RAM_WIDGET_HXX +#define DATA_GRID_RAM_WIDGET_HXX + +class RamWidget; + +#include "DataGridWidget.hxx" +#include "Base.hxx" + +class DataGridRamWidget : public DataGridWidget +{ + public: + DataGridRamWidget(GuiObject* boss, const RamWidget& ram, + const GUI::Font& font, + int x, int y, int cols, int rows, + int colchars, int bits, + Common::Base::Fmt format = Common::Base::Fmt::_DEFAULT, + bool useScrollbar = false); + ~DataGridRamWidget() override = default; + + string getToolTip(const Common::Point& pos) const override; + + private: + const RamWidget& _ram; + + private: + // Following constructors and assignment operators not supported + DataGridRamWidget() = delete; + DataGridRamWidget(const DataGridRamWidget&) = delete; + DataGridRamWidget(DataGridRamWidget&&) = delete; + DataGridRamWidget& operator=(const DataGridRamWidget&) = delete; + DataGridRamWidget& operator=(DataGridRamWidget&&) = delete; +}; + +#endif From 4f43334b6ce663d2a4bb3f1ce196c655ac7a1464 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 19 Nov 2020 09:36:02 -0330 Subject: [PATCH 225/263] Fix wrong location of debugger files. --- src/debugger/{ => gui}/DataGridRamWidget.cxx | 0 src/debugger/{ => gui}/DataGridRamWidget.hxx | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/debugger/{ => gui}/DataGridRamWidget.cxx (100%) rename src/debugger/{ => gui}/DataGridRamWidget.hxx (100%) diff --git a/src/debugger/DataGridRamWidget.cxx b/src/debugger/gui/DataGridRamWidget.cxx similarity index 100% rename from src/debugger/DataGridRamWidget.cxx rename to src/debugger/gui/DataGridRamWidget.cxx diff --git a/src/debugger/DataGridRamWidget.hxx b/src/debugger/gui/DataGridRamWidget.hxx similarity index 100% rename from src/debugger/DataGridRamWidget.hxx rename to src/debugger/gui/DataGridRamWidget.hxx From 2abfd14d46e3271edf2aa775e90e9b42f0d5217f Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 19 Nov 2020 09:49:38 -0330 Subject: [PATCH 226/263] Fix location of files in VS project. --- src/windows/Stella.vcxproj | 8 ++------ src/windows/Stella.vcxproj.filters | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 76e311ce3..d1cf96c6b 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -525,9 +525,6 @@ true - - true - true @@ -684,6 +681,7 @@ true + true @@ -1553,9 +1551,6 @@ true - - true - true @@ -1712,6 +1707,7 @@ true + true diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 6db5675f0..a8cac63d6 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1035,7 +1035,7 @@ Source Files\gui - + Source Files\debugger @@ -2132,7 +2132,7 @@ Header Files\gui - + Header Files\debugger From 7112dc553370982120ae1f376fe0975d83d5558b Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 19 Nov 2020 10:29:41 -0330 Subject: [PATCH 227/263] Add debugger files to Xcode project, and fix minor warnings. --- src/debugger/gui/ToggleBitWidget.cxx | 4 ++-- src/macos/stella.xcodeproj/project.pbxproj | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/debugger/gui/ToggleBitWidget.cxx b/src/debugger/gui/ToggleBitWidget.cxx index 212ae60ed..1ebe1c5e4 100644 --- a/src/debugger/gui/ToggleBitWidget.cxx +++ b/src/debugger/gui/ToggleBitWidget.cxx @@ -82,14 +82,14 @@ void ToggleBitWidget::setState(const BoolArray& state, const BoolArray& changed) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string ToggleBitWidget::getToolTip(const Common::Point& pos) const { - Common::Point idx = getToolTipIndex(pos); + const Common::Point& idx = getToolTipIndex(pos); if(idx.y < 0) return EmptyString; const string tip = ToggleWidget::getToolTip(pos); - if(idx.x < _labelList.size()) + if(idx.x < static_cast(_labelList.size())) { const string label = _labelList[idx.x]; diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index a23a0b173..09a728c1b 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -533,6 +533,8 @@ DCBDDE9F1D6A5F2F009DF1E9 /* Cart3EPlus.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */; }; DCC2FDF5255EB82500FA5E81 /* ToolTip.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */; }; DCC2FDF6255EB82500FA5E81 /* ToolTip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */; }; + DCC2FDF92566AD8800FA5E81 /* DataGridRamWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */; }; + DCC2FDFA2566AD8800FA5E81 /* DataGridRamWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */; }; DCC527D110B9DA19005E1287 /* Device.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527C910B9DA19005E1287 /* Device.hxx */; }; DCC527D210B9DA19005E1287 /* M6502.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC527CA10B9DA19005E1287 /* M6502.cxx */; }; DCC527D310B9DA19005E1287 /* M6502.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527CB10B9DA19005E1287 /* M6502.hxx */; }; @@ -1302,6 +1304,8 @@ DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EPlus.hxx; sourceTree = ""; }; DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ToolTip.hxx; sourceTree = ""; }; DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToolTip.cxx; sourceTree = ""; }; + DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataGridRamWidget.cxx; sourceTree = ""; }; + DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DataGridRamWidget.hxx; sourceTree = ""; }; DCC527C910B9DA19005E1287 /* Device.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Device.hxx; sourceTree = ""; }; DCC527CA10B9DA19005E1287 /* M6502.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = M6502.cxx; sourceTree = ""; }; DCC527CB10B9DA19005E1287 /* M6502.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = M6502.hxx; sourceTree = ""; }; @@ -1706,6 +1710,8 @@ 2D20F9E708C603EC00A73076 /* CpuWidget.hxx */, 2D20F9E808C603EC00A73076 /* DataGridOpsWidget.cxx */, 2D20F9E908C603EC00A73076 /* DataGridOpsWidget.hxx */, + DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */, + DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */, 2D20F9EA08C603EC00A73076 /* DataGridWidget.cxx */, 2D20F9EB08C603EC00A73076 /* DataGridWidget.hxx */, 2D20F9EC08C603EC00A73076 /* DebuggerDialog.cxx */, @@ -2578,6 +2584,7 @@ E08FCD5823A037EB0051F59B /* QisBlitter.hxx in Headers */, DCA078351F8C1B04008EFEE5 /* SDL_lib.hxx in Headers */, DCDA03B11A2009BB00711920 /* CartWD.hxx in Headers */, + DCC2FDFA2566AD8800FA5E81 /* DataGridRamWidget.hxx in Headers */, 2D91745909BA90380026E9FF /* PromptWidget.hxx in Headers */, DC3C9BC62469C8F700CF2D47 /* PaletteHandler.hxx in Headers */, 2D91745A09BA90380026E9FF /* RamWidget.hxx in Headers */, @@ -3198,6 +3205,7 @@ DC676A591729A0B000E4E73D /* CartSBWidget.cxx in Sources */, DC3C9BCC2469C93D00CF2D47 /* EmulationDialog.cxx in Sources */, DC676A5B1729A0B000E4E73D /* CartX07Widget.cxx in Sources */, + DCC2FDF92566AD8800FA5E81 /* DataGridRamWidget.cxx in Sources */, DC7A24DF173B1DBC00B20FE9 /* FileListWidget.cxx in Sources */, DC13B53F176FF2F500B8B4BB /* RomListSettings.cxx in Sources */, DC3EE8581E2C0E6D00905161 /* crc32.c in Sources */, From 319c521b77fedc204d9e90f0065714b1195d79d5 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 19 Nov 2020 11:35:02 -0330 Subject: [PATCH 228/263] Enable RTTI by default for Linux/UNIX builds; disable it for release builds only. --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 90279a56a..87a2c9847 100644 --- a/Makefile +++ b/Makefile @@ -48,11 +48,11 @@ endif CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter ifdef HAVE_GCC - CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 -frtti + CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 endif ifdef HAVE_CLANG - CXXFLAGS+= -Wno-multichar -Wunused -frtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 + CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 endif ifdef CLANG_WARNINGS @@ -81,8 +81,8 @@ else endif ifdef RELEASE - CXXFLAGS += -flto - LDFLAGS += -flto + CXXFLAGS += -flto -fno-rtti + LDFLAGS += -flto -fno-rtti endif ####################################################################### From 3c50de30a6d32724f8a02aa858006595e4a9ec77 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 19 Nov 2020 16:40:16 +0100 Subject: [PATCH 229/263] added tooltip hiding when context menus are opened added tooltips to TiaOutputWidget and TiaZoomWidget --- src/debugger/gui/RomListWidget.cxx | 2 +- src/debugger/gui/TiaOutputWidget.cxx | 49 ++++++++++++++++++++++++++++ src/debugger/gui/TiaOutputWidget.hxx | 7 ++++ src/debugger/gui/TiaZoomWidget.cxx | 46 ++++++++++++++++++++++++++ src/debugger/gui/TiaZoomWidget.hxx | 7 ++++ src/gui/LauncherDialog.cxx | 1 + 6 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index aab298fad..d732cd328 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -247,6 +247,7 @@ void RomListWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) // Set selected and add menu at current x,y mouse location _selectedItem = findItem(x, y); scrollToSelected(); + dialog().tooltip().hide(); myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect(), _selectedItem); } @@ -518,7 +519,6 @@ bool RomListWidget::changedToolTip(const Common::Point& oldPos, return getToolTipIndex(oldPos) != getToolTipIndex(newPos); } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RomListWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/TiaOutputWidget.cxx b/src/debugger/gui/TiaOutputWidget.cxx index 2062bd436..94963f870 100644 --- a/src/debugger/gui/TiaOutputWidget.cxx +++ b/src/debugger/gui/TiaOutputWidget.cxx @@ -22,6 +22,8 @@ #include "FBSurface.hxx" #include "Widget.hxx" #include "GuiObject.hxx" +#include "Dialog.hxx" +#include "ToolTip.hxx" #include "ContextMenu.hxx" #include "TiaZoomWidget.hxx" #include "Debugger.hxx" @@ -55,6 +57,7 @@ TiaOutputWidget::TiaOutputWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaOutputWidget::loadConfig() { + setEnabled(true); setDirty(); } @@ -110,6 +113,7 @@ void TiaOutputWidget::handleMouseDown(int x, int y, MouseButton b, int clickCoun myClickX = x; myClickY = y; + dialog().tooltip().hide(); // Add menu at current x,y mouse location myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect()); } @@ -158,6 +162,51 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Common::Point TiaOutputWidget::getToolTipIndex(const Common::Point& pos) const +{ + const Int32 width = instance().console().tia().width(); + const Int32 height = instance().console().tia().height(); + const int col = (pos.x - 1 - getAbsX()) >> 1; + const int row = pos.y - 1 - getAbsY(); + + if(col < 0 || col >= width || row < 0 || row >= height) + return Common::Point(-1, -1); + else + return Common::Point(col, row); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string TiaOutputWidget::getToolTip(const Common::Point& pos) const +{ + Common::Point idx = getToolTipIndex(pos); + + if(idx.x < 0) + return EmptyString; + + uInt32 height = instance().console().tia().height(); + // limit to 274 lines (PAL default without scaling) + uInt32 yStart = height <= FrameManager::Metrics::baseHeightPAL + ? 0 : (height - FrameManager::Metrics::baseHeightPAL) >> 1; + const Int32 i = idx.x + (yStart + idx.y) * instance().console().tia().width(); + uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer(); + ostringstream buf; + + buf << _toolTipText + << "X: #" << idx.x + << "\nY: #" << idx.y + << "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16); + + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool TiaOutputWidget::changedToolTip(const Common::Point& oldPos, + const Common::Point& newPos) const +{ + return getToolTipIndex(oldPos) != getToolTipIndex(newPos); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaOutputWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/TiaOutputWidget.hxx b/src/debugger/gui/TiaOutputWidget.hxx index c7bfd26f6..cc465266a 100644 --- a/src/debugger/gui/TiaOutputWidget.hxx +++ b/src/debugger/gui/TiaOutputWidget.hxx @@ -47,6 +47,13 @@ class TiaOutputWidget : public Widget, public CommandSender bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyUp(StellaKey key, StellaMod mod) override; */ + string getToolTip(const Common::Point& pos) const override; + bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; + + protected: + bool hasToolTip() const override { return true; } + Common::Point getToolTipIndex(const Common::Point& pos) const; + private: unique_ptr myMenu; TiaZoomWidget* myZoom{nullptr}; diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx index 0895c51a8..eec9723ff 100644 --- a/src/debugger/gui/TiaZoomWidget.cxx +++ b/src/debugger/gui/TiaZoomWidget.cxx @@ -26,6 +26,8 @@ #include "FBSurface.hxx" #include "Widget.hxx" #include "GuiObject.hxx" +#include "Dialog.hxx" +#include "ToolTip.hxx" #include "ContextMenu.hxx" #include "FrameManager.hxx" #include "TiaZoomWidget.hxx" @@ -127,6 +129,7 @@ void TiaZoomWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) } else if(b == MouseButton::RIGHT) { + dialog().tooltip().hide(); // Add menu at current x,y mouse location myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect()); } @@ -141,6 +144,8 @@ void TiaZoomWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaZoomWidget::handleMouseWheel(int x, int y, int direction) { + dialog().tooltip().hide(); + // zoom towards mouse position myClickX = x; myClickY = y; @@ -274,6 +279,47 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Common::Point TiaZoomWidget::getToolTipIndex(const Common::Point& pos) const +{ + const Int32 width = instance().console().tia().width() * 2; + const Int32 height = instance().console().tia().height(); + const int col = (pos.x - 1 - getAbsX()) / (myZoomLevel << 1) + (myOffX >> 1); + const int row = (pos.y - 1 - getAbsY()) / myZoomLevel + myOffY; + + if(col < 0 || col >= width || row < 0 || row >= height) + return Common::Point(-1, -1); + else + return Common::Point(col, row); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string TiaZoomWidget::getToolTip(const Common::Point& pos) const +{ + Common::Point idx = getToolTipIndex(pos); + + if(idx.x < 0) + return EmptyString; + + const Int32 i = idx.x + idx.y * instance().console().tia().width(); + uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer(); + ostringstream buf; + + buf << _toolTipText + << "X: #" << idx.x + << "\nY: #" << idx.y + << "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16); + + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool TiaZoomWidget::changedToolTip(const Common::Point& oldPos, + const Common::Point& newPos) const +{ + return getToolTipIndex(oldPos) != getToolTipIndex(newPos); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaZoomWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/TiaZoomWidget.hxx b/src/debugger/gui/TiaZoomWidget.hxx index 7169645bf..d46787f23 100644 --- a/src/debugger/gui/TiaZoomWidget.hxx +++ b/src/debugger/gui/TiaZoomWidget.hxx @@ -34,6 +34,13 @@ class TiaZoomWidget : public Widget, public CommandSender void loadConfig() override; void setPos(int x, int y); + string getToolTip(const Common::Point& pos) const override; + bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; + + protected: + bool hasToolTip() const override { return true; } + Common::Point getToolTipIndex(const Common::Point& pos) const; + private: void zoom(int level); void recalc(); diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 5092299ec..405be5745 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -568,6 +568,7 @@ void LauncherDialog::handleMouseDown(int x, int y, MouseButton b, int clickCount // Grab right mouse button for context menu, send left to base class if(b == MouseButton::RIGHT) { + dialog().tooltip().hide(); // Dynamically create context menu for ROM list options VariantList items; From 779375abec6c4d8a2df48dc03225b49c7c379ad8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 19 Nov 2020 16:44:03 +0100 Subject: [PATCH 230/263] fixed potential Clang warnings --- src/debugger/gui/TiaOutputWidget.cxx | 6 +++--- src/debugger/gui/TiaZoomWidget.cxx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/debugger/gui/TiaOutputWidget.cxx b/src/debugger/gui/TiaOutputWidget.cxx index 94963f870..6d2a1b9cb 100644 --- a/src/debugger/gui/TiaOutputWidget.cxx +++ b/src/debugger/gui/TiaOutputWidget.cxx @@ -179,14 +179,14 @@ Common::Point TiaOutputWidget::getToolTipIndex(const Common::Point& pos) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string TiaOutputWidget::getToolTip(const Common::Point& pos) const { - Common::Point idx = getToolTipIndex(pos); + const Common::Point& idx = getToolTipIndex(pos); if(idx.x < 0) return EmptyString; - uInt32 height = instance().console().tia().height(); + const uInt32 height = instance().console().tia().height(); // limit to 274 lines (PAL default without scaling) - uInt32 yStart = height <= FrameManager::Metrics::baseHeightPAL + const uInt32 yStart = height <= FrameManager::Metrics::baseHeightPAL ? 0 : (height - FrameManager::Metrics::baseHeightPAL) >> 1; const Int32 i = idx.x + (yStart + idx.y) * instance().console().tia().width(); uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer(); diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx index eec9723ff..3cbbad8e2 100644 --- a/src/debugger/gui/TiaZoomWidget.cxx +++ b/src/debugger/gui/TiaZoomWidget.cxx @@ -296,7 +296,7 @@ Common::Point TiaZoomWidget::getToolTipIndex(const Common::Point& pos) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string TiaZoomWidget::getToolTip(const Common::Point& pos) const { - Common::Point idx = getToolTipIndex(pos); + const Common::Point& idx = getToolTipIndex(pos); if(idx.x < 0) return EmptyString; From 4d19473bb4c204dbc7bab454321a2f6c9606a5ab Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 19 Nov 2020 13:39:32 -0330 Subject: [PATCH 231/263] Enable RTTI for Xcode. --- src/macos/stella.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj index 09a728c1b..d0892bdce 100644 --- a/src/macos/stella.xcodeproj/project.pbxproj +++ b/src/macos/stella.xcodeproj/project.pbxproj @@ -3405,7 +3405,7 @@ ., "$(HOME)/Library/Frameworks", ); - GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_CPP_RTTI = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = ""; @@ -3480,7 +3480,7 @@ ., "$(HOME)/Library/Frameworks", ); - GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_CPP_RTTI = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_VERSION = ""; From 80efc3d63107b09cc9a0b865feb515cf3ac53862 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 19 Nov 2020 19:19:49 +0100 Subject: [PATCH 232/263] removed "on top" logic for drawing widgets --- src/debugger/gui/DataGridWidget.cxx | 10 +++---- src/debugger/gui/DelayQueueWidget.cxx | 5 ++-- src/debugger/gui/PromptWidget.cxx | 8 ++--- src/debugger/gui/RomListWidget.cxx | 5 ++-- src/debugger/gui/ToggleBitWidget.cxx | 13 ++++---- src/debugger/gui/TogglePixelWidget.cxx | 3 +- src/gui/CheckListWidget.cxx | 8 ++--- src/gui/ColorWidget.cxx | 5 ++-- src/gui/Dialog.hxx | 1 - src/gui/EditTextWidget.cxx | 9 +++--- src/gui/PopUpWidget.cxx | 11 ++++--- src/gui/RomInfoWidget.cxx | 8 ++--- src/gui/ScrollBarWidget.cxx | 14 ++++----- src/gui/StringListWidget.cxx | 9 +++--- src/gui/TabWidget.cxx | 16 +++++----- src/gui/Widget.cxx | 41 ++++++++------------------ 16 files changed, 64 insertions(+), 102 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 5d0dc0623..81840147a 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -620,10 +620,9 @@ bool DataGridWidget::changedToolTip(const Common::Point& oldPos, void DataGridWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int row, col; - s.fillRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? _bgcolorhi : onTop ? _bgcolor : kBGColorHi); + s.fillRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? _bgcolorhi : _bgcolor); // Draw the internal grid and labels int linewidth = _cols * _colWidth; s.frameRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor); @@ -642,7 +641,7 @@ void DataGridWidget::drawWidget(bool hilite) int x = _x + 4 + (col * _colWidth); int y = _y + 2 + (row * _rowHeight); int pos = row*_cols + col; - ColorId textColor = onTop ? kTextColor : kColor; + ColorId textColor = kTextColor; // Draw the selected item inverted, on a highlighted background. if (_currentRow == row && _currentCol == col && @@ -662,13 +661,12 @@ void DataGridWidget::drawWidget(bool hilite) { if(_changedList[pos]) { - s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, - onTop ? kDbgChangedColor : _bgcolorlo); + s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kDbgChangedColor); if(_hiliteList[pos]) textColor = kDbgColorHi; else - textColor = onTop ? kDbgChangedTextColor : textColor; + textColor = kDbgChangedTextColor; } else if(_hiliteList[pos]) textColor = kDbgColorHi; diff --git a/src/debugger/gui/DelayQueueWidget.cxx b/src/debugger/gui/DelayQueueWidget.cxx index 6dbd613be..cca5644c6 100644 --- a/src/debugger/gui/DelayQueueWidget.cxx +++ b/src/debugger/gui/DelayQueueWidget.cxx @@ -90,7 +90,6 @@ void DelayQueueWidget::loadConfig() { void DelayQueueWidget::drawWidget(bool hilite) { FBSurface& surface = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int y = _y, x = _x, @@ -102,14 +101,14 @@ void DelayQueueWidget::drawWidget(bool hilite) y += 1; x += 1; w -= 1; - surface.fillRect(x, y, w - 1, _h - 2, onTop ? kDlgColor : _bgcolorlo); + surface.fillRect(x, y, w - 1, _h - 2, kDlgColor); y += 2; x += 2; w -= 3; for (const auto& line : myLines) { - surface.drawString(_font, line, x, y, w, onTop ? _textcolor : kColor); + surface.drawString(_font, line, x, y, w, _textcolor); y += lineHeight; } } diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 490f7b8a6..116080bf7 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -81,9 +81,7 @@ void PromptWidget::drawWidget(bool hilite) { //cerr << "PromptWidget::drawWidget\n"; ColorId fgcolor, bgcolor; - FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); // Draw text int start = _scrollLine - _linesPerPage + 1; @@ -104,7 +102,7 @@ void PromptWidget::drawWidget(bool hilite) else fgcolor = ColorId(c >> 8); - s.drawChar(_font, c & 0x7f, x, y, onTop ? fgcolor : kColor); + s.drawChar(_font, c & 0x7f, x, y, fgcolor); x += _kConsoleCharWidth; } y += _kConsoleLineHeight; @@ -938,8 +936,6 @@ void PromptWidget::drawCaret() { //cerr << "PromptWidget::drawCaret()\n"; FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); - int line = _currentPos / _lineWidth; // Don't draw the cursor if it's not in the current view @@ -951,7 +947,7 @@ void PromptWidget::drawCaret() int y = _y + displayLine * _kConsoleLineHeight; char c = buffer(_currentPos); //FIXME: int to char?? - s.fillRect(x, y, _kConsoleCharWidth, _kConsoleLineHeight, onTop ? kTextColor : kColor); + s.fillRect(x, y, _kConsoleCharWidth, _kConsoleLineHeight, kTextColor); s.drawChar(_font, c, x, y + 2, kBGColor); } diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index d732cd328..c226398a6 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -523,10 +523,9 @@ bool RomListWidget::changedToolTip(const Common::Point& oldPos, void RomListWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); const CartDebug::DisassemblyList& dlist = myDisasm->list; int i, pos, xpos, ypos, len = int(dlist.size()); - ColorId textColor = onTop ? kTextColor : kColor; + ColorId textColor = kTextColor; const Common::Rect& r = getEditRect(); const Common::Rect& l = getLineRect(); @@ -559,7 +558,7 @@ void RomListWidget::drawWidget(bool hilite) // Draw highlighted item in a frame if(_highlightedItem == pos) - s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _lineHeight, onTop ? kWidColorHi : kBGColorLo); + s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _lineHeight, kWidColorHi); // Draw the selected item inverted, on a highlighted background. if(_selectedItem == pos && _hasFocus) diff --git a/src/debugger/gui/ToggleBitWidget.cxx b/src/debugger/gui/ToggleBitWidget.cxx index 1ebe1c5e4..994d73aa9 100644 --- a/src/debugger/gui/ToggleBitWidget.cxx +++ b/src/debugger/gui/ToggleBitWidget.cxx @@ -104,7 +104,6 @@ void ToggleBitWidget::drawWidget(bool hilite) { //cerr << "ToggleBitWidget::drawWidget\n"; FBSurface& s = dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int row, col; string buffer; @@ -146,18 +145,16 @@ void ToggleBitWidget::drawWidget(bool hilite) // Highlight changes if(_changedList[pos]) { - s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, - onTop ? kDbgChangedColor : _bgcolorlo); - s.drawString(_font, buffer, x, y, _colWidth, onTop ? kDbgChangedTextColor : kColor); + s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kDbgChangedColor); + s.drawString(_font, buffer, x, y, _colWidth, kDbgChangedTextColor); } else - s.drawString(_font, buffer, x, y, _colWidth, - onTop ? textColor : kColor); + s.drawString(_font, buffer, x, y, _colWidth, textColor); } else { - s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, onTop ? kBGColorHi : kDlgColor); - s.drawString(_font, buffer, x, y, _colWidth, onTop ? kTextColor : kColor); + s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kBGColorHi); + s.drawString(_font, buffer, x, y, _colWidth, kTextColor); } } } diff --git a/src/debugger/gui/TogglePixelWidget.cxx b/src/debugger/gui/TogglePixelWidget.cxx index b7dd5dbdf..1cdb80bae 100644 --- a/src/debugger/gui/TogglePixelWidget.cxx +++ b/src/debugger/gui/TogglePixelWidget.cxx @@ -118,7 +118,6 @@ void TogglePixelWidget::drawWidget(bool hilite) { //cerr << "TogglePixelWidget::drawWidget\n"; FBSurface& s = dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int row, col; s.frameRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor); @@ -146,7 +145,7 @@ void TogglePixelWidget::drawWidget(bool hilite) // Either draw the pixel in given color, or erase (show background) s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, - _stateList[pos] ? onTop ? _pixelColor : kColor : onTop ? _backgroundColor : kBGColorLo); + _stateList[pos] ? _pixelColor : _backgroundColor); if (_changedList[pos]) s.frameRect(x - 3, y - 1, _colWidth - 1, _rowHeight - 1, kDbgChangedColor); } diff --git a/src/gui/CheckListWidget.cxx b/src/gui/CheckListWidget.cxx index 6d80fcc07..13afb335a 100644 --- a/src/gui/CheckListWidget.cxx +++ b/src/gui/CheckListWidget.cxx @@ -81,7 +81,6 @@ void CheckListWidget::drawWidget(bool hilite) { //cerr << "CheckListWidget::drawWidget\n"; FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int i, pos, len = int(_list.size()); // Draw a thin frame around the list and to separate columns @@ -112,18 +111,17 @@ void CheckListWidget::drawWidget(bool hilite) } else s.frameRect(_x + r.x() - 3, _y + 1 + _lineHeight * i, - _w - r.x(), _lineHeight, onTop ? kTextColorHi : kColor); + _w - r.x(), _lineHeight, kTextColorHi); } if (_selectedItem == pos && _editMode) { adjustOffset(); - s.drawString(_font, editString(), _x + r.x(), y, r.w(), onTop ? kTextColor : kColor, + s.drawString(_font, editString(), _x + r.x(), y, r.w(), kTextColor, TextAlign::Left, -_editScrollOffset, false); } else - s.drawString(_font, _list[pos], _x + r.x(), y, r.w(), - onTop ? textColor : kColor); + s.drawString(_font, _list[pos], _x + r.x(), y, r.w(), textColor); } // Only draw the caret while editing, and if it's in the current viewport diff --git a/src/gui/ColorWidget.cxx b/src/gui/ColorWidget.cxx index 27f4bc3cf..5f31df35d 100644 --- a/src/gui/ColorWidget.cxx +++ b/src/gui/ColorWidget.cxx @@ -45,7 +45,6 @@ void ColorWidget::setColor(ColorId color) void ColorWidget::drawWidget(bool hilite) { FBSurface& s = dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); if(_framed) { @@ -53,11 +52,11 @@ void ColorWidget::drawWidget(bool hilite) s.frameRect(_x, _y, _w, _h + 1, kColor); // Show the currently selected color - s.fillRect(_x + 1, _y + 1, _w - 2, _h - 1, onTop ? isEnabled() ? _color : kWidColor : kBGColorLo); + s.fillRect(_x + 1, _y + 1, _w - 2, _h - 1, isEnabled() ? _color : kWidColor); } else { - s.fillRect(_x, _y, _w, _h, onTop ? isEnabled() ? _color : kWidColor : kBGColorLo); + s.fillRect(_x, _y, _w, _h, isEnabled() ? _color : kWidColor); } // Cross out the grid? diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index f628ec792..7935f1c95 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -55,7 +55,6 @@ class Dialog : public GuiObject void close(); bool isVisible() const override { return _visible; } - bool isOnTop() const { return true; } // TODO: remove virtual void setPosition(); virtual void drawDialog(); diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index 61785bd78..6a0f32877 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -76,13 +76,12 @@ void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount void EditTextWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); // Highlight changes - if(_changed && onTop) + if(_changed) s.fillRect(_x, _y, _w, _h, kDbgChangedColor); else if(!isEditable() || !isEnabled()) - s.fillRect(_x, _y, _w, _h, onTop ? kDlgColor : kBGColorLo); + s.fillRect(_x, _y, _w, _h, kDlgColor); // Draw a thin frame around us. s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor); @@ -90,9 +89,9 @@ void EditTextWidget::drawWidget(bool hilite) // Draw the text adjustOffset(); s.drawString(_font, editString(), _x + _textOfs, _y + 2, getEditRect().w(), getEditRect().h(), - _changed && onTop && isEnabled() + _changed && isEnabled() ? kDbgChangedTextColor - : onTop && isEnabled() ? _textcolor : kColor, + : isEnabled() ? _textcolor : kColor, TextAlign::Left, scrollOffset(), !isEditable()); // Draw the caret and selection diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 45f79e55b..82f4e2596 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -249,7 +249,6 @@ void PopUpWidget::drawWidget(bool hilite) { //cerr << "PopUpWidget::drawWidget\n"; FBSurface& s = dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int x = _x + _labelWidth; int w = _w - _labelWidth; @@ -257,7 +256,7 @@ void PopUpWidget::drawWidget(bool hilite) // Draw the label, if any if(_labelWidth > 0) s.drawString(_font, _label, _x, _y + myTextY, _labelWidth, - isEnabled() && onTop ? _textcolor : kColor, TextAlign::Left); + isEnabled() ? _textcolor : kColor, TextAlign::Left); // Draw a thin frame around us. s.frameRect(x, _y, w, _h, isEnabled() && hilite ? kWidColorHi : kColor); @@ -267,12 +266,12 @@ void PopUpWidget::drawWidget(bool hilite) // Fill the background ColorId bgCol = isEditable() ? kWidColor : kDlgColor; s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 1), _h - 2, - onTop ? _changed ? kDbgChangedColor : bgCol : kDlgColor); + _changed ? kDbgChangedColor : bgCol); s.fillRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2, - onTop ? isEnabled() && hilite ? kBtnColorHi : bgCol : kBGColorLo); + isEnabled() && hilite ? kBtnColorHi : bgCol); // Draw an arrow pointing down at the right end to signal this is a dropdown/popup s.drawBitmap(_arrowImg, x + w - (_arrowWidth * 1.5 - 1), _y + myArrowsY + 1, - !(isEnabled() && onTop) ? kColor : kTextColor, _arrowWidth, _arrowHeight); + !isEnabled() ? kColor : kTextColor, _arrowWidth, _arrowHeight); // Draw the selected entry, if any const string& name = editString(); @@ -283,7 +282,7 @@ void PopUpWidget::drawWidget(bool hilite) TextAlign::Right : TextAlign::Left; adjustOffset(); s.drawString(_font, name, x + _textOfs, _y + myTextY, w, - !(isEnabled() && onTop) ? kColor : _changed ? kDbgChangedTextColor : kTextColor, + !isEnabled() ? kColor : _changed ? kDbgChangedTextColor : kTextColor, align, editable ? -_editScrollOffset : 0, !editable); if(editable) diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx index c2068a4d1..325cadfda 100644 --- a/src/gui/RomInfoWidget.cxx +++ b/src/gui/RomInfoWidget.cxx @@ -180,11 +180,9 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node) void RomInfoWidget::drawWidget(bool hilite) { FBSurface& s = dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); - const int yoff = myAvail.h + 10; - s.fillRect(_x+2, _y+2, _w-4, _h-4, onTop ? _bgcolor : _bgcolorlo); + s.fillRect(_x+2, _y+2, _w-4, _h-4, _bgcolor); s.frameRect(_x, _y, _w, _h, kColor); s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor); @@ -206,7 +204,7 @@ void RomInfoWidget::drawWidget(bool hilite) { uInt32 x = _x + ((_w - _font.getStringWidth(mySurfaceErrorMsg)) >> 1); uInt32 y = _y + ((yoff - _font.getLineHeight()) >> 1); - s.drawString(_font, mySurfaceErrorMsg, x, y, _w - 10, onTop ? _textcolor : _shadowcolor); + s.drawString(_font, mySurfaceErrorMsg, x, y, _w - 10, _textcolor); } int xpos = _x + 8, ypos = _y + yoff + 5; @@ -226,7 +224,7 @@ void RomInfoWidget::drawWidget(bool hilite) break; } int lines = s.drawString(_font, info, xpos, ypos, _w - 16, _font.getFontHeight() * 3, - onTop ? _textcolor : _shadowcolor); + _textcolor); ypos += _font.getLineHeight() + (lines - 1) * _font.getFontHeight(); } clearDirty(); diff --git a/src/gui/ScrollBarWidget.cxx b/src/gui/ScrollBarWidget.cxx index 73e89bc78..4bacbeece 100644 --- a/src/gui/ScrollBarWidget.cxx +++ b/src/gui/ScrollBarWidget.cxx @@ -274,9 +274,7 @@ void ScrollBarWidget::recalc() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ScrollBarWidget::drawWidget(bool hilite) { -//cerr << "ScrollBarWidget::drawWidget\n"; FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int bottomY = _y + _h; bool isSinglePage = (_numEntries <= _entriesPerPage); @@ -290,22 +288,24 @@ void ScrollBarWidget::drawWidget(bool hilite) s.fillRect(_x + 1, _y + 1, _w - 2, _upDownBoxHeight - 2, kScrollColor); s.drawBitmap(_upImg, _x + (_scrollBarWidth - _upDownWidth) / 2, _y + (_upDownBoxHeight - _upDownHeight) / 2, - onTop ? isSinglePage ? kColor : (hilite && _part == Part::UpArrow) ? kWidColor - : kTextColor : kColor, _upDownWidth, _upDownHeight); + isSinglePage ? kColor + : (hilite && _part == Part::UpArrow) ? kWidColor : kTextColor, + _upDownWidth, _upDownHeight); // Down arrow if(hilite && _part == Part::DownArrow) s.fillRect(_x + 1, bottomY - _upDownBoxHeight + 1, _w - 2, _upDownBoxHeight - 2, kScrollColor); s.drawBitmap(_downImg, _x + (_scrollBarWidth - _upDownWidth) / 2, bottomY - _upDownBoxHeight + (_upDownBoxHeight - _upDownHeight) / 2, - onTop ? isSinglePage ? kColor : (hilite && _part == Part::DownArrow) ? - kWidColor : kTextColor : kColor, _upDownWidth, _upDownHeight); + isSinglePage ? kColor + : (hilite && _part == Part::DownArrow) ? kWidColor : kTextColor, + _upDownWidth, _upDownHeight); // Slider if(!isSinglePage) { s.fillRect(_x + 1, _y + _sliderPos - 1, _w - 2, _sliderHeight + 2, - onTop ? (hilite && _part == Part::Slider) ? kScrollColorHi : kScrollColor : kColor); + (hilite && _part == Part::Slider) ? kScrollColorHi : kScrollColor); } clearDirty(); } diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 536240b8a..9173d6276 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -95,23 +95,22 @@ bool StringListWidget::changedToolTip(const Common::Point& oldPos, void StringListWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); int i, pos, len = int(_list.size()); // Draw a thin frame around the list. - s.frameRect(_x, _y, _w + 1, _h, onTop && hilite && _hilite ? kWidColorHi : kColor); + s.frameRect(_x, _y, _w + 1, _h, hilite && _hilite ? kWidColorHi : kColor); if (!isEnabled()) - s.fillRect(_x + 1, _y + 1, _w - 1, _h - 2, onTop ? kDlgColor : kBGColorLo); + s.fillRect(_x + 1, _y + 1, _w - 1, _h - 2, kDlgColor); // Draw the list items for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++) { const int y = _y + 2 + _lineHeight * i; - ColorId textColor = onTop ? kTextColor : kShadowColor; + ColorId textColor = kTextColor; // Draw the selected item inverted, on a highlighted background. - if (onTop && _selectedItem == pos && _hilite) + if (_selectedItem == pos && _hilite) { if(_hasFocus && !_editMode) { diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx index 28b383f6c..3c7d48258 100644 --- a/src/gui/TabWidget.cxx +++ b/src/gui/TabWidget.cxx @@ -265,36 +265,34 @@ void TabWidget::drawWidget(bool hilite) if(isDirty()) { FBSurface& s = dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); // Iterate over all tabs and draw them int i, x = _x + kTabLeftOffset; for(i = 0; i < int(_tabs.size()); ++i) { int tabWidth = _tabs[i].tabWidth ? _tabs[i].tabWidth : _tabWidth; - ColorId fontcolor = _tabs[i].enabled && onTop ? kTextColor : kColor; + ColorId fontcolor = _tabs[i].enabled ? kTextColor : kColor; int yOffset = (i == _activeTab) ? 0 : 1; s.fillRect(x, _y + 1, tabWidth, _tabHeight - 1, (i == _activeTab) - ? onTop ? kDlgColor : kBGColorLo - : onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor + ? kDlgColor : kBGColorHi); // ? kWidColor : kDlgColor s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset, _y + yOffset + (_tabHeight - _lineHeight - 1), tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center); if(i == _activeTab) { - s.hLine(x, _y, x + tabWidth - 1, onTop ? kWidColor : kDlgColor); - s.vLine(x + tabWidth, _y + 1, _y + _tabHeight - 1, onTop ? kBGColorLo : kColor); + s.hLine(x, _y, x + tabWidth - 1, kWidColor); + s.vLine(x + tabWidth, _y + 1, _y + _tabHeight - 1, kBGColorLo); } else - s.hLine(x, _y + _tabHeight, x + tabWidth, onTop ? kWidColor : kDlgColor); + s.hLine(x, _y + _tabHeight, x + tabWidth, kWidColor); x += tabWidth + kTabSpacing; } // fill empty right space - s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor); - s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor); + s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, kWidColor); + s.hLine(_x, _y + _h - 1, _x + _w - 1, kBGColorLo); clearDirty(); // Make all child widgets of currently active tab dirty diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 23c72760d..1856c3f4b 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -101,8 +101,6 @@ void Widget::draw() //cerr << "w"; FBSurface& s = _boss->dialog().surface(); - - bool onTop = _boss->dialog().isOnTop(); int oldX = _x, oldY = _y; // Account for our relative position in the dialog @@ -118,9 +116,7 @@ void Widget::draw() x++; y++; w -= 2; h -= 2; } if(hasBackground()) - s.fillRect(x, y, w, h, !onTop - ? _bgcolorlo - : (_flags & Widget::FLAG_HILITED) && isEnabled() + s.fillRect(x, y, w, h, (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor); else s.invalidateRect(x, y, w, h); @@ -129,9 +125,7 @@ void Widget::draw() // Draw border if(hasBorder()) { - s.frameRect(_x, _y, _w, _h, !onTop - ? kColor - : (_flags & Widget::FLAG_HILITED) && isEnabled() + s.frameRect(_x, _y, _w, _h, (_flags & Widget::FLAG_HILITED) && isEnabled() ? kWidColorHi : kColor); _x += 4; _y += 4; @@ -275,7 +269,6 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr, FBSurface& s = boss->dialog().surface(); int size = int(arr.size()), pos = -1; Widget* tmp; - bool onTop = boss->dialog().isOnTop(); for(int i = 0; i < size; ++i) { @@ -300,9 +293,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr, else tmp->_hasFocus = false; - s.frameRect(x, y, w, h, onTop ? kDlgColor : kBGColorLo); - - //tmp->setDirty(); + s.frameRect(x, y, w, h, kDlgColor); } } @@ -355,10 +346,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr, tmp->setFlags(Widget::FLAG_HILITED); } - if (onTop) - s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed); - - //tmp->setDirty(); + s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed); return tmp; } @@ -439,9 +427,9 @@ void StaticTextWidget::handleMouseLeft() void StaticTextWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); + s.drawString(_font, _label, _x, _y, _w, - isEnabled() && onTop ? _textcolor : kColor, _align, 0, true, _shadowcolor); + isEnabled() ? _textcolor : kColor, _align, 0, true, _shadowcolor); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -558,17 +546,16 @@ void ButtonWidget::setBitmap(const uInt32* bitmap, int bmw, int bmh) void ButtonWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); - s.frameRect(_x, _y, _w, _h, !onTop ? kShadowColor : hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor); + s.frameRect(_x, _y, _w, _h, hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor); if (!_useBitmap) s.drawString(_font, _label, _x, _y + (_h - _lineHeight)/2 + 1, _w, - !(isEnabled() && onTop) ? _textcolorlo : + !isEnabled() ? _textcolorlo : hilite ? _textcolorhi : _textcolor, _align); else s.drawBitmap(_bitmap, _x + (_w - _bmw) / 2, _y + (_h - _bmh) / 2, - !(isEnabled() && onTop) ? _textcolorlo : + !isEnabled() ? _textcolorlo : hilite ? _textcolorhi : _textcolor, _bmw, _bmh); } @@ -703,21 +690,19 @@ void CheckboxWidget::setState(bool state, bool changed) void CheckboxWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - bool onTop = _boss->dialog().isOnTop(); if(_drawBox) - s.frameRect(_x, _y + _boxY, _boxSize, _boxSize, onTop && hilite && isEnabled() && isEditable() ? kWidColorHi : kColor); + s.frameRect(_x, _y + _boxY, _boxSize, _boxSize, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor); // Do we draw a square or cross? s.fillRect(_x + 1, _y + _boxY + 1, _boxSize - 2, _boxSize - 2, - _changed ? onTop ? kDbgChangedColor : kDlgColor : - isEnabled() && onTop ? _bgcolor : kDlgColor); + _changed ? kDbgChangedColor : isEnabled() ? _bgcolor : kDlgColor); if(_state) - s.drawBitmap(_img, _x + 2, _y + _boxY + 2, onTop && isEnabled() ? hilite && isEditable() ? kWidColorHi : kCheckColor + s.drawBitmap(_img, _x + 2, _y + _boxY + 2, isEnabled() ? hilite && isEditable() ? kWidColorHi : kCheckColor : kColor, _boxSize - 4); // Finally draw the label s.drawString(_font, _label, _x + prefixSize(_font), _y + _textY, _w, - onTop && isEnabled() ? kTextColor : kColor); + isEnabled() ? kTextColor : kColor); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 760f32c5c2c0ba11d2aec92ffa09e28182fb51d6 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 19 Nov 2020 23:18:28 +0100 Subject: [PATCH 233/263] changed y-position displayed in tooltip to scanline number --- src/debugger/gui/TiaOutputWidget.cxx | 7 ++++--- src/debugger/gui/TiaZoomWidget.cxx | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/debugger/gui/TiaOutputWidget.cxx b/src/debugger/gui/TiaOutputWidget.cxx index 6d2a1b9cb..424efd0d1 100644 --- a/src/debugger/gui/TiaOutputWidget.cxx +++ b/src/debugger/gui/TiaOutputWidget.cxx @@ -104,14 +104,14 @@ void TiaOutputWidget::saveSnapshot(int execDepth, const string& execPrefix) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaOutputWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) -{ +{ if(b == MouseButton::LEFT) myZoom->setPos(x, y); // Grab right mouse button for command context menu else if(b == MouseButton::RIGHT) { myClickX = x; - myClickY = y; + myClickY = y - 1; dialog().tooltip().hide(); // Add menu at current x,y mouse location @@ -184,6 +184,7 @@ string TiaOutputWidget::getToolTip(const Common::Point& pos) const if(idx.x < 0) return EmptyString; + const uInt32 startLine = instance().console().tia().startLine(); const uInt32 height = instance().console().tia().height(); // limit to 274 lines (PAL default without scaling) const uInt32 yStart = height <= FrameManager::Metrics::baseHeightPAL @@ -194,7 +195,7 @@ string TiaOutputWidget::getToolTip(const Common::Point& pos) const buf << _toolTipText << "X: #" << idx.x - << "\nY: #" << idx.y + << "\nY: #" << idx.y + startLine << "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16); return buf.str(); diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx index 3cbbad8e2..3622c11ac 100644 --- a/src/debugger/gui/TiaZoomWidget.cxx +++ b/src/debugger/gui/TiaZoomWidget.cxx @@ -117,7 +117,7 @@ void TiaZoomWidget::recalc() void TiaZoomWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) { myClickX = x; - myClickY = y; + myClickY = y - 1; // Button 1 is for 'drag'/movement of the image // Button 2 is for context menu @@ -148,7 +148,7 @@ void TiaZoomWidget::handleMouseWheel(int x, int y, int direction) // zoom towards mouse position myClickX = x; - myClickY = y; + myClickY = y - 1; if(direction > 0) { @@ -167,6 +167,7 @@ void TiaZoomWidget::handleMouseMoved(int x, int y) { if(myMouseMoving) { + y--; int diffx = x + myOffXLo - myClickX; int diffy = y + myOffYLo - myClickY; @@ -302,12 +303,13 @@ string TiaZoomWidget::getToolTip(const Common::Point& pos) const return EmptyString; const Int32 i = idx.x + idx.y * instance().console().tia().width(); + const uInt32 startLine = instance().console().tia().startLine(); uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer(); ostringstream buf; buf << _toolTipText << "X: #" << idx.x - << "\nY: #" << idx.y + << "\nY: #" << idx.y + startLine << "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16); return buf.str(); From 8d27e645734b09c58b9f7ef66e0118ba44c3d2ae Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 20 Nov 2020 10:11:40 +0100 Subject: [PATCH 234/263] improved tooltips hiding added tooltip to breakpoint/trap status added tooltip to search/compare buttons and dialogs added tooltips to data operation buttons --- src/debugger/Debugger.cxx | 4 +++- src/debugger/Debugger.hxx | 3 ++- src/debugger/gui/CpuWidget.cxx | 4 ++-- src/debugger/gui/DataGridOpsWidget.cxx | 9 ++++++++- src/debugger/gui/DataGridWidget.cxx | 1 + src/debugger/gui/DebuggerDialog.cxx | 1 + src/debugger/gui/RamWidget.cxx | 6 ++++++ src/debugger/gui/TiaOutputWidget.cxx | 4 +--- src/debugger/gui/TiaZoomWidget.cxx | 1 - src/emucore/DispatchResult.cxx | 4 +++- src/emucore/DispatchResult.hxx | 8 ++++++-- src/emucore/M6502.cxx | 14 ++++++++------ src/emucore/OSystem.cxx | 3 ++- src/gui/Dialog.cxx | 2 ++ src/gui/DialogContainer.cxx | 5 +++++ src/gui/InputTextDialog.cxx | 14 +++++++++++--- src/gui/InputTextDialog.hxx | 2 ++ src/gui/LauncherDialog.cxx | 1 - src/gui/PopUpWidget.cxx | 2 -- 19 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index e363a0b82..abfc63ac1 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -118,7 +118,8 @@ FBInitStatus Debugger::initializeVideo() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Debugger::start(const string& message, int address, bool read) +bool Debugger::start(const string& message, int address, bool read, + const string& toolTip) { if(myOSystem.eventHandler().enterDebugMode()) { @@ -129,6 +130,7 @@ bool Debugger::start(const string& message, int address, bool read) if(address > -1) buf << cartDebug().getLabel(address, read, 4); myDialog->message().setText(buf.str()); + myDialog->message().setToolTip(toolTip); return true; } return false; diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index e7096cd4d..6a53238bb 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -97,7 +97,8 @@ class Debugger : public DialogContainer @param message Message to display when entering debugger @param address An address associated with the message */ - bool start(const string& message = "", int address = -1, bool read = true); + bool start(const string& message = "", int address = -1, bool read = true, + const string& toolTip = ""); bool startWithFatalError(const string& message = ""); /** diff --git a/src/debugger/gui/CpuWidget.cxx b/src/debugger/gui/CpuWidget.cxx index a8719f448..1069e8001 100644 --- a/src/debugger/gui/CpuWidget.cxx +++ b/src/debugger/gui/CpuWidget.cxx @@ -91,7 +91,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n for(int i = 0; i < 4; ++i) { myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w, fontHeight + 1); - myCpuDataSrc[i]->setToolTip("Source label of last load into " + labels[i] + "."); + myCpuDataSrc[i]->setToolTip("Source label of last read for " + labels[i] + "."); myCpuDataSrc[i]->setEditable(false, true); src_y += fontHeight + 2; } @@ -140,7 +140,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n xpos = myCpuDataSrc[0]->getLeft(); new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, ypos + 2, "Dest"); myCpuDataDest = new EditTextWidget(boss, nfont, xpos, ypos, src_w, fontHeight + 1); - myCpuDataDest->setToolTip("Destination label of last store."); + myCpuDataDest->setToolTip("Destination label of last write."); myCpuDataDest->setEditable(false, true); _h = ypos + myPSRegister->getHeight() - y; diff --git a/src/debugger/gui/DataGridOpsWidget.cxx b/src/debugger/gui/DataGridOpsWidget.cxx index 102d7a94d..2a62ec60c 100644 --- a/src/debugger/gui/DataGridOpsWidget.cxx +++ b/src/debugger/gui/DataGridOpsWidget.cxx @@ -33,31 +33,38 @@ DataGridOpsWidget::DataGridOpsWidget(GuiObject* boss, const GUI::Font& font, xpos = x; ypos = y; _zeroButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "0", kDGZeroCmd); - + _zeroButton->setToolTip("Zero currently selected value"); + ypos += bheight + space; _invButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "Inv", kDGInvertCmd); + _invButton->setToolTip("Invert currently selected value"); ypos += bheight + space; _incButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "++", kDGIncCmd); + _incButton->setToolTip("Increase currently selected value."); ypos += bheight + space; _shiftLeftButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "<<", kDGShiftLCmd); + _shiftLeftButton->setToolTip("Shift currently selected value left"); // Move to next column, skip a row xpos = x + bwidth + space; ypos = y + bheight + space; _negButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "Neg", kDGNegateCmd); + _negButton->setToolTip("Negate currently selected value"); ypos += bheight + space; _decButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, "--", kDGDecCmd); + _decButton->setToolTip("Decrease currently selected value"); ypos += bheight + space; _shiftRightButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight, ">>", kDGShiftRCmd); + _shiftRightButton->setToolTip("Shift currently selected value right"); // Calculate real dimensions _w = 2 * (bwidth+space); diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 81840147a..20489912c 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -713,6 +713,7 @@ void DataGridWidget::startEditMode() { if (isEditable() && !_editMode && _selectedItem >= 0) { + dialog().tooltip().hide(); enableEditMode(true); setText("", true); // Erase current entry when starting editing } diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index 07e530ac6..b8a28f579 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -94,6 +94,7 @@ void DebuggerDialog::loadConfig() myRomTab->loadConfig(); myMessageBox->setText(""); + myMessageBox->setToolTip(""); } void DebuggerDialog::saveConfig() diff --git a/src/debugger/gui/RamWidget.cxx b/src/debugger/gui/RamWidget.cxx index 7f651910a..4e097d9be 100644 --- a/src/debugger/gui/RamWidget.cxx +++ b/src/debugger/gui/RamWidget.cxx @@ -78,18 +78,21 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n by += bheight + VGAP * 6; mySearchButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, "Search" + ELLIPSIS, kSearchCmd); + mySearchButton->setToolTip("Search and highlight found values."); wid.push_back(mySearchButton); mySearchButton->setTarget(this); by += bheight + VGAP; myCompareButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, "Compare" + ELLIPSIS, kCmpCmd); + myCompareButton->setToolTip("Compare highlighted values."); wid.push_back(myCompareButton); myCompareButton->setTarget(this); by += bheight + VGAP; myRestartButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight, "Reset", kRestartCmd); + myRestartButton->setToolTip("Reset search/compare mode."); wid.push_back(myRestartButton); myRestartButton->setTarget(this); @@ -366,6 +369,9 @@ void RamWidget::showInputBox(int cmd) myInputBox->show(x, y, dialog().surface().dstRect()); myInputBox->setText(""); myInputBox->setMessage(""); + myInputBox->setToolTip(cmd == kSValEntered + ? "Enter search value (leave blank for all)." + : "Enter relative or absolute value\nto compare with searched values."); myInputBox->setFocus(0); myInputBox->setEmitSignal(cmd); myInputBox->setTitle(cmd == kSValEntered ? "Search" : "Compare"); diff --git a/src/debugger/gui/TiaOutputWidget.cxx b/src/debugger/gui/TiaOutputWidget.cxx index 424efd0d1..d101fa674 100644 --- a/src/debugger/gui/TiaOutputWidget.cxx +++ b/src/debugger/gui/TiaOutputWidget.cxx @@ -23,7 +23,6 @@ #include "Widget.hxx" #include "GuiObject.hxx" #include "Dialog.hxx" -#include "ToolTip.hxx" #include "ContextMenu.hxx" #include "TiaZoomWidget.hxx" #include "Debugger.hxx" @@ -104,7 +103,7 @@ void TiaOutputWidget::saveSnapshot(int execDepth, const string& execPrefix) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TiaOutputWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) -{ +{ if(b == MouseButton::LEFT) myZoom->setPos(x, y); // Grab right mouse button for command context menu @@ -113,7 +112,6 @@ void TiaOutputWidget::handleMouseDown(int x, int y, MouseButton b, int clickCoun myClickX = x; myClickY = y - 1; - dialog().tooltip().hide(); // Add menu at current x,y mouse location myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect()); } diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx index 3622c11ac..af8e468dd 100644 --- a/src/debugger/gui/TiaZoomWidget.cxx +++ b/src/debugger/gui/TiaZoomWidget.cxx @@ -129,7 +129,6 @@ void TiaZoomWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) } else if(b == MouseButton::RIGHT) { - dialog().tooltip().hide(); // Add menu at current x,y mouse location myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect()); } diff --git a/src/emucore/DispatchResult.cxx b/src/emucore/DispatchResult.cxx index 20a208a56..9ba5326ca 100644 --- a/src/emucore/DispatchResult.cxx +++ b/src/emucore/DispatchResult.cxx @@ -31,11 +31,13 @@ void DispatchResult::setOk(uInt64 cycles) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void DispatchResult::setDebugger(uInt64 cycles, const string& message, int address, bool wasReadTrap) +void DispatchResult::setDebugger(uInt64 cycles, const string& message, + const string& tooltip, int address, bool wasReadTrap) { myStatus = Status::debugger; myCycles = cycles; myMessage = message; + myToolTip = tooltip; myAddress = address; myWasReadTrap = wasReadTrap; } diff --git a/src/emucore/DispatchResult.hxx b/src/emucore/DispatchResult.hxx index 6d76cf5ce..38e80a9c5 100644 --- a/src/emucore/DispatchResult.hxx +++ b/src/emucore/DispatchResult.hxx @@ -37,12 +37,14 @@ class DispatchResult bool wasReadTrap() const { assertStatus(Status::debugger); return myWasReadTrap; } + const string& getToolTip() const { assertStatus(Status::debugger, Status::fatal); return myToolTip; } + bool isSuccess() const; void setOk(uInt64 cycles); - void setDebugger(uInt64 cycles, const string& message = "", int address = -1, - bool wasReadTrap = true); + void setDebugger(uInt64 cycles, const string& message = "", + const string& tooltip = "", int address = -1, bool wasReadTrap = true); void setFatal(uInt64 cycles); @@ -73,6 +75,8 @@ class DispatchResult int myAddress{0}; bool myWasReadTrap{false}; + + string myToolTip; }; #endif // DISPATCH_RESULT_HXX diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx index 86b050dfb..295697af2 100644 --- a/src/emucore/M6502.cxx +++ b/src/emucore/M6502.cxx @@ -243,7 +243,9 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) myJustHitReadTrapFlag = myJustHitWriteTrapFlag = false; myLastBreakCycle = mySystem->cycles(); - result.setDebugger(currentCycles, myHitTrapInfo.message, myHitTrapInfo.address, read); + result.setDebugger(currentCycles, myHitTrapInfo.message, + read ? "Read trap" : "Write trap", + myHitTrapInfo.address, read); return; } @@ -264,7 +266,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) ostringstream msg; msg << "BP: $" << Common::Base::HEX4 << PC << ", bank #" << std::dec << int(bank); - result.setDebugger(currentCycles, msg.str()); + result.setDebugger(currentCycles, msg.str(), "Breakpoint"); } return; } @@ -278,7 +280,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) msg << "CBP[" << Common::Base::HEX2 << cond << "]: " << myCondBreakNames[cond]; myLastBreakCycle = mySystem->cycles(); - result.setDebugger(currentCycles, msg.str()); + result.setDebugger(currentCycles, msg.str(), "Conditional breakpoint"); return; } } @@ -327,7 +329,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) { ostringstream msg; msg << "RWP[@ $" << Common::Base::HEX4 << rwpAddr << "]: "; - result.setDebugger(currentCycles, msg.str(), oldPC); + result.setDebugger(currentCycles, msg.str(), "Read from write port", oldPC); return; } } @@ -339,7 +341,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) { ostringstream msg; msg << "WRP[@ $" << Common::Base::HEX4 << wrpAddr << "]: "; - result.setDebugger(currentCycles, msg.str(), oldPC); + result.setDebugger(currentCycles, msg.str(), "Write to read port", oldPC); return; } } @@ -348,7 +350,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) myExecutionStatus |= FatalErrorBit; result.setMessage(e.what()); } catch (const EmulationWarning& e) { - result.setDebugger(currentCycles, e.what(), PC); + result.setDebugger(currentCycles, e.what(), "Emulation exception", PC); return; } diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index e659c1e5c..b8f8842e6 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -775,7 +775,8 @@ double OSystem::dispatchEmulation(EmulationWorker& emulationWorker) myDebugger->start( dispatchResult.getMessage(), dispatchResult.getAddress(), - dispatchResult.wasReadTrap() + dispatchResult.wasReadTrap(), + dispatchResult.getToolTip() ); #endif diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 1b58d7729..392f2b625 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -512,6 +512,8 @@ void Dialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated) { Event::Type e = Event::NoType; + tooltip().hide(); + // FIXME - I don't think this will compile! #if defined(RETRON77) // special keys used for R77 diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index fcdac91a9..0a6730773 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -17,6 +17,7 @@ #include "OSystem.hxx" #include "Dialog.hxx" +#include "ToolTip.hxx" #include "Stack.hxx" #include "EventHandler.hxx" #include "FrameBuffer.hxx" @@ -159,6 +160,10 @@ int DialogContainer::addDialog(Dialog* d) "Unable to show dialog box; FIX THE CODE", MessagePosition::BottomCenter, true); else { + // Close all open tooltips + if(!myDialogStack.empty()) + myDialogStack.top()->tooltip().hide(); + d->setDirty(); myDialogStack.push(d); } diff --git a/src/gui/InputTextDialog.cxx b/src/gui/InputTextDialog.cxx index 54b656a67..4c34de23e 100644 --- a/src/gui/InputTextDialog.cxx +++ b/src/gui/InputTextDialog.cxx @@ -81,9 +81,10 @@ void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont, for(i = 0; i < labels.size(); ++i) { xpos = HBORDER; - new StaticTextWidget(this, lfont, xpos, ypos + 2, - lwidth, fontHeight, - labels[i], TextAlign::Left); + StaticTextWidget* s = new StaticTextWidget(this, lfont, xpos, ypos + 2, + lwidth, fontHeight, + labels[i]); + myLabel.push_back(s); xpos += lwidth + fontWidth; EditTextWidget* w = new EditTextWidget(this, nfont, xpos, ypos, @@ -177,6 +178,13 @@ void InputTextDialog::setTextFilter(const EditableWidget::TextFilter& f, int idx myInput[idx]->setTextFilter(f); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void InputTextDialog::setToolTip(const string& str, int idx) +{ + if(uInt32(idx) < myLabel.size()) + myLabel[idx]->setToolTip(str); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputTextDialog::setFocus(int idx) { diff --git a/src/gui/InputTextDialog.hxx b/src/gui/InputTextDialog.hxx index a06ca4446..059c7ada7 100644 --- a/src/gui/InputTextDialog.hxx +++ b/src/gui/InputTextDialog.hxx @@ -46,6 +46,7 @@ class InputTextDialog : public Dialog, public CommandSender void setText(const string& str, int idx = 0); void setTextFilter(const EditableWidget::TextFilter& f, int idx = 0); + void setToolTip(const string& str, int idx = 0); void setEmitSignal(int cmd) { myCmd = cmd; } void setMessage(const string& title); @@ -61,6 +62,7 @@ class InputTextDialog : public Dialog, public CommandSender void setPosition() override; private: + vector myLabel; vector myInput; StaticTextWidget* myMessage{nullptr}; diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 405be5745..5092299ec 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -568,7 +568,6 @@ void LauncherDialog::handleMouseDown(int x, int y, MouseButton b, int clickCount // Grab right mouse button for context menu, send left to base class if(b == MouseButton::RIGHT) { - dialog().tooltip().hide(); // Dynamically create context menu for ROM list options VariantList items; diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 82f4e2596..eb35ed9c3 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -21,7 +21,6 @@ #include "Font.hxx" #include "ContextMenu.hxx" #include "Dialog.hxx" -#include "ToolTip.hxx" #include "DialogContainer.hxx" #include "PopUpWidget.hxx" @@ -124,7 +123,6 @@ void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount) { if(isEnabled() && !myMenu->isVisible()) { - dialog().tooltip().hide(); // Add menu just underneath parent widget myMenu->show(getAbsX() + _labelWidth, getAbsY() + getHeight(), dialog().surface().dstRect(), myMenu->getSelected()); From 095d83d33548c040576189f510ab0c4be59b46c7 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 20 Nov 2020 10:31:28 +0100 Subject: [PATCH 235/263] updated changes and WhatsNewDialog --- Changes.txt | 10 +++++++++- src/gui/WhatsNewDialog.cxx | 17 ++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Changes.txt b/Changes.txt index 5ae5b0460..4d5776bcb 100644 --- a/Changes.txt +++ b/Changes.txt @@ -14,7 +14,15 @@ 6.4 to 6.5 (December XX, 2020) - * Enhanced cut/copy/paste to allow selecting text (TODO: PromptWidget, doc) + * Enhanced cut/copy/paste for text editing (TODO: PromptWidget) + + * Added undo and redo to text editing (TODO: PromptWidget) + + * Added static tooltips to some UI items + + * Added dynamic tooltips to most debugger items + + * Increased sample size for CDFJ+ -Have fun! diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index 825ed43fe..e94e432a2 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -43,18 +43,13 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const max_w, max_h); #if defined(RETRON77) - add(ypos, "fixed CDF cartridges crash"); - add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); - add(ypos, "fixed bug with launcher not remembering last selected ROM"); + add(ypos, "increased sample size for CDFJ+"); + add(ypos, "fixed navigation bug in Video & Audio settings dialog"); #else - add(ypos, "added basic text cut/copy/paste from/to UI"); - add(ypos, "added color parameters to 'Custom' palette"); - add(ypos, "improved AtariVox-USB adaptor autodetection"); - add(ypos, "fixed fullscreen mode, aspect correction and pixel-exact snapshots"); - add(ypos, "fixed reduced ARM emulation performance for CDF ROMs"); - add(ypos, "fixed crash with SaveKey ROMs (EEPROM file issues)"); - add(ypos, "fixed Atari mouse autodetection"); - add(ypos, "fixed bug with launcher not remembering last selected ROM"); + add(ypos, "enhanced cut/copy/paste for text editing"); + add(ypos, "added undo and redo to text editing"); + add(ypos, "added tooltips to many UI items"); + add(ypos, "increased sample size for CDFJ+"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); #endif From 654ca21817b199d8c68a94de1373437ffac196df Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 20 Nov 2020 10:44:32 -0330 Subject: [PATCH 236/263] Don't forget about Mac for a tooltip. --- src/gui/LauncherDialog.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 5092299ec..cbab575bd 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -183,7 +183,6 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, #ifndef BSPF_MACOS myStartButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 0) / 4, buttonHeight, "Select", kLoadROMCmd); - myStartButton->setToolTip("Start emulation of selected ROM."); wid.push_back(myStartButton); xpos += (buttonWidth + 0) / 4 + BUTTON_GAP; @@ -220,6 +219,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, "Select", kLoadROMCmd); wid.push_back(myStartButton); #endif + myStartButton->setToolTip("Start emulation of selected ROM."); } if(myUseMinimalUI) // Highlight 'Rom Listing' mySelectedItem = 0; From 2eccae50a0951779c9b5a2610704b480f6030c79 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 20 Nov 2020 20:12:30 +0100 Subject: [PATCH 237/263] added tooltips to DeveloperDialog --- src/gui/DeveloperDialog.cxx | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index 6c877351a..e7d4f1e47 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -115,10 +115,11 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) "Console info overlay"); wid.push_back(myFrameStatsWidget); - myDetectedInfoWidget = new CheckboxWidget(myTab, font, myFrameStatsWidget->getRight() + fontWidth * 2.5, ypos + 1, "Detected settings info"); + myDetectedInfoWidget->setToolTip("Display detected controllers, bankswitching\n" + "and TV types at ROM start."); wid.push_back(myDetectedInfoWidget); ypos += lineHeight + VGAP; @@ -131,6 +132,8 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) myConsoleWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 1, ypos, pwidth, lineHeight, items, "Console ", lwidth, kConsole); + myConsoleWidget->setToolTip("Emulate Color/B&W/Pause key and zero\n" + "page RAM initialization differenly."); wid.push_back(myConsoleWidget); ypos += lineHeight + VGAP; @@ -141,6 +144,8 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) myRandomBankWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Random startup bank"); + myRandomBankWidget->setToolTip("Randomize the startup bank for\n" + "most classic bankswitching types."); wid.push_back(myRandomBankWidget); ypos += lineHeight + VGAP; @@ -168,17 +173,23 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) // How to handle undriven TIA pins myUndrivenPinsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Drive unused TIA pins randomly on a read/peek"); + myUndrivenPinsWidget->setToolTip("Read TIA pins random instead of last databus values.\n" + "Helps detecting missing '#' for immediate loads."); wid.push_back(myUndrivenPinsWidget); ypos += lineHeight + VGAP; #ifdef DEBUGGER_SUPPORT myRWPortBreakWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Break on reads from write ports"); + myRWPortBreakWidget->setToolTip("Cause reads from write ports to interrupt\n" + "emulation and enter debugger."); wid.push_back(myRWPortBreakWidget); ypos += lineHeight + VGAP; myWRPortBreakWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Break on writes to read ports"); + myWRPortBreakWidget->setToolTip("Cause writes to read ports to interrupt\n" + "emulation and enter debugger."); wid.push_back(myWRPortBreakWidget); ypos += lineHeight + VGAP; #endif @@ -186,12 +197,16 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font) // Thumb ARM emulation exception myThumbExceptionWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Fatal ARM emulation error throws exception"); + myThumbExceptionWidget->setToolTip("Cause Thumb ARM emulation to throw exceptions\n" + "on fatal errors and enter the debugger."); wid.push_back(myThumbExceptionWidget); ypos += lineHeight + VGAP; // AtariVox/SaveKey EEPROM access myEEPROMAccessWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Display AtariVox/SaveKey EEPROM R/W access"); + myEEPROMAccessWidget->setToolTip("Cause message display when AtariVox/\n" + "SaveKey EEPROM is read or written."); wid.push_back(myEEPROMAccessWidget); // Add items for tab 0 @@ -239,11 +254,15 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) VarList::push_back(items, "Custom", "custom"); myTIATypeWidget = new PopUpWidget(myTab, font, HBORDER + INDENT, ypos - 1, pwidth, lineHeight, items, "Chip type ", 0, kTIAType); + myTIATypeWidget->setToolTip("Select which TIA chip type to emulate.\n" + "Some types cause defined glitches."); wid.push_back(myTIATypeWidget); ypos += lineHeight + VGAP * 1; myInvPhaseLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Inverted HMOVE clock phase for"); + myInvPhaseLabel->setToolTip("Objects react different to too\n" + "early HM" + ELLIPSIS + " after HMOVE changes."); wid.push_back(myInvPhaseLabel); ypos += lineHeight + VGAP * 1; @@ -262,6 +281,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) myPlayfieldLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Delayed playfield"); + myPlayfieldLabel->setToolTip("Playfield reacts one color clock slower to updates."); wid.push_back(myPlayfieldLabel); ypos += lineHeight + VGAP * 1; @@ -275,6 +295,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) myBackgroundLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Delayed background"); + myBackgroundLabel->setToolTip("Background color reacts one color clock slower to updates."); wid.push_back(myBackgroundLabel); ypos += lineHeight + VGAP * 1; @@ -285,6 +306,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font) ostringstream ss; ss << "Delayed VDEL" << ELLIPSIS << " swap for"; mySwapLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, ss.str()); + mySwapLabel->setToolTip("VDELed objects react one color clock slower to updates."); wid.push_back(mySwapLabel); ypos += lineHeight + VGAP * 1; @@ -332,12 +354,14 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font) // TV jitter effect myTVJitterWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "Jitter/roll effect", kTVJitter); + myTVJitterWidget->setToolTip("Enable to emulate TV loss of sync."); wid.push_back(myTVJitterWidget); myTVJitterRecWidget = new SliderWidget(myTab, font, myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1, "Recovery ", 0, kTVJitterChanged); myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20); myTVJitterRecWidget->setTickmarkIntervals(5); + myTVJitterRecWidget->setToolTip("Define speed of sync revovery."); wid.push_back(myTVJitterRecWidget); myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font, myTVJitterRecWidget->getRight() + 4, @@ -347,6 +371,8 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font) myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1, "PAL color-loss"); + myColorLossWidget->setToolTip("PAL games with odd scanline count\n" + "will be displayed without color."); wid.push_back(myColorLossWidget); ypos += lineHeight + VGAP; @@ -485,6 +511,7 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) #endif myStateSizeWidget->setStepValue(20); myStateSizeWidget->setTickmarkIntervals(5); + myStateSizeWidget->setToolTip("Define the total Time Machine buffer size."); wid.push_back(myStateSizeWidget); ypos += lineHeight + VGAP; @@ -498,6 +525,9 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) #endif myUncompressedWidget->setStepValue(20); myUncompressedWidget->setTickmarkIntervals(5); + myUncompressedWidget->setToolTip("Define the number of completely kept states.\n" + "States beyond this number will be slowly removed\n" + "to fit the requested horizon into the buffer."); wid.push_back(myUncompressedWidget); ypos += lineHeight + VGAP; @@ -507,6 +537,7 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) int pwidth = font.getStringWidth("10 seconds"); myStateIntervalWidget = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, "Interval ", 0, kIntervalChanged); + myStateIntervalWidget->setToolTip("Define the interval between each saved state."); wid.push_back(myStateIntervalWidget); ypos += lineHeight + VGAP; @@ -515,6 +546,8 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font) VarList::push_back(items, HORIZONS[i], HOR_SETTINGS[i]); myStateHorizonWidget = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, "Horizon ~ ", 0, kHorizonChanged); + myStateHorizonWidget->setToolTip("Define how far the Time Machine\n" + "will allow moving back in time."); wid.push_back(myStateHorizonWidget); // Add message concerning usage @@ -598,6 +631,7 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font) myGhostReadsTrapWidget = new CheckboxWidget(myTab, font, HBORDER, ypos + 1, "Trap on 'ghost' reads"); + myGhostReadsTrapWidget->setToolTip("Traps will consider CPU 'ghost' reads too."); wid.push_back(myGhostReadsTrapWidget); // Add message concerning usage From e4d9b2ecebc400494b978826c94239a1aa95e05c Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 20 Nov 2020 21:23:48 +0100 Subject: [PATCH 238/263] added wildcard support to launcher dialog filter --- Changes.txt | 12 ++++---- docs/index.html | 7 +++-- src/gui/LauncherDialog.cxx | 56 +++++++++++++++++++++++++++++++++++++- src/gui/LauncherDialog.hxx | 21 ++++++++++++++ src/gui/WhatsNewDialog.cxx | 1 + 5 files changed, 88 insertions(+), 9 deletions(-) diff --git a/Changes.txt b/Changes.txt index 4d5776bcb..6ec962851 100644 --- a/Changes.txt +++ b/Changes.txt @@ -14,15 +14,17 @@ 6.4 to 6.5 (December XX, 2020) - * Enhanced cut/copy/paste for text editing (TODO: PromptWidget) + * Enhanced cut/copy/paste for text editing. (TODO: PromptWidget) - * Added undo and redo to text editing (TODO: PromptWidget) + * Added undo and redo to text editing. (TODO: PromptWidget) - * Added static tooltips to some UI items + * Added wildcard support to launcher dialog filter. - * Added dynamic tooltips to most debugger items + * Added static tooltips to some UI items. - * Increased sample size for CDFJ+ + * Added dynamic tooltips to most debugger items. + + * Increased sample size for CDFJ+. -Have fun! diff --git a/docs/index.html b/docs/index.html index 0d2a8fd48..7e57b22e7 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3695,9 +3695,10 @@ Typing characters here will show only those files that match that pattern. For example, typing 'Activision' will show only files that contain the word 'Activision' in their name. This is very useful for - quickly finding a group of related ROMs. Note that the search is not - case sensitive, so you don't need to worry about capital or lower-case - letters.

    + quickly finding a group of related ROMs.

    +

    + Note that the search is not case sensitive, so you don't need to worry about + capital or lower-case letters. Also you can use '*' and '?' as wildcards.

    ROM Launcher Context Menu

    diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index cbab575bd..11fa0fc06 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -348,6 +348,60 @@ void LauncherDialog::updateUI() loadRomInfo(); } +size_t LauncherDialog::matchWithJoker(const string& str, const string& pattern) +{ + if(str.length() >= pattern.length()) + { + for(size_t pos = 0; pos < str.length() - pattern.length() + 1; ++pos) + { + bool found = true; + + for(size_t i = 0; found && i < pattern.length(); ++i) + if(pattern[i] != str[pos + i] && pattern[i] != '?') + found = false; + + if(found) + return pos; + } + } + return string::npos; +} + +bool LauncherDialog::matchWithWildcards(const string& str, const string& pattern) +{ + string in = str; + string pat = pattern; + size_t pos = string::npos; + + BSPF::toUpperCase(in); + BSPF::toUpperCase(pat); + + for(size_t i = 0; i < pat.length(); ++i) + if(pat[i] == '*') + { + pos = i; + break; + } + + if(pos != string::npos) + { + // '*' found, split pattern into left and right part, search recursively + const string leftPat = pat.substr(0, pos); + const string rightPat = pat.substr(pos + 1); + size_t posLeft = matchWithJoker(in, leftPat); + + if(posLeft != string::npos) + return matchWithWildcards(in.substr(pos + posLeft), rightPat); + else + return false; + } + else + { + // no further '*' found + return matchWithJoker(in, pat) != string::npos; + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void LauncherDialog::applyFiltering() { @@ -361,7 +415,7 @@ void LauncherDialog::applyFiltering() // Skip over files that don't match the pattern in the 'pattern' textbox if(myPattern && myPattern->getText() != "" && - !BSPF::containsIgnoreCase(node.getName(), myPattern->getText())) + !matchWithWildcards(node.getName(), myPattern->getText())) return false; } return true; diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index cc265928b..6fafab663 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -112,6 +112,27 @@ class LauncherDialog : public Dialog void loadConfig() override; void saveConfig() override; void updateUI(); + + /** + Search if string contains pattern including '?' as joker. + + @param str The searched string + @param pattern The pattern to search for + + @return Position of pattern in string. + */ + size_t matchWithJoker(const string& str, const string& pattern); + + /** + Search if string contains pattern including wildcard '*' + and '?' as joker, ignoring case. + + @param str The searched string + @param pattern The pattern to search for + + @return True if pattern was found. + */ + bool matchWithWildcards(const string& str, const string& pattern); void applyFiltering(); float getRomInfoZoom(int listHeight) const; diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index e94e432a2..5892bfcfd 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -48,6 +48,7 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const #else add(ypos, "enhanced cut/copy/paste for text editing"); add(ypos, "added undo and redo to text editing"); + add(ypos, "added wildcard support to launcher dialog filter"); add(ypos, "added tooltips to many UI items"); add(ypos, "increased sample size for CDFJ+"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); From d330d6c716e9fc7a946606c96595bd91316c551a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 20 Nov 2020 23:06:06 +0100 Subject: [PATCH 239/263] tooltips are disabled for R77 --- src/gui/Dialog.cxx | 4 +++- src/gui/DialogContainer.cxx | 8 ++------ src/gui/Widget.cxx | 6 ++++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 392f2b625..2ff6a4539 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -244,7 +244,7 @@ void Dialog::redraw(bool force) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::render() { - cerr << " render " << typeid(*this).name() << endl; + //cerr << " render " << typeid(*this).name() << endl; // Update dialog surface; also render any extra surfaces // Extra surfaces must be rendered afterwards, so they are drawn on top @@ -641,8 +641,10 @@ void Dialog::handleMouseMoved(int x, int y) if (w && (w->getFlags() & Widget::FLAG_TRACK_MOUSE)) w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y)); +#ifndef RETRON77 // Update mouse coordinates for tooltips _toolTip->update(_mouseWidget, Common::Point(x, y)); +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 0a6730773..273b713c8 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -95,11 +95,7 @@ void DialogContainer::draw(bool full) if(myDialogStack.empty()) return; - cerr << "draw " << full << " " << typeid(*this).name() << endl; - - // Make the top dialog dirty if a full redraw is requested - //if(full) - // myDialogStack.top()->setDirty(); + //cerr << "draw " << full << " " << typeid(*this).name() << endl; // Draw and render all dirty dialogs myDialogStack.applyAll([&](Dialog*& d) { @@ -123,7 +119,7 @@ void DialogContainer::render() if(myDialogStack.empty()) return; - cerr << "full re-render " << typeid(*this).name() << endl; + //cerr << "full re-render " << typeid(*this).name() << endl; // Make sure we start in a clean state (with zero'ed buffers) if(!myOSystem.eventHandler().inTIAMode()) diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 1856c3f4b..e0b9a2389 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -75,8 +75,10 @@ void Widget::tick() { if(isEnabled()) { + #ifndef RETRON77 if(wantsToolTip()) dialog().tooltip().request(); + #endif // Recursively tick widget and all child dialogs and widgets Widget* w = _firstWidget; @@ -97,8 +99,8 @@ void Widget::draw() if(isDirty()) { - cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; - //cerr << "w"; + //cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl; + cerr << "w"; FBSurface& s = _boss->dialog().surface(); int oldX = _x, oldY = _y; From 2141469ba7ce0e2827ba73cce32132dd63a1620c Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 20 Nov 2020 19:53:44 -0330 Subject: [PATCH 240/263] Fix typo in tooltip. --- src/gui/DeveloperDialog.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx index e7d4f1e47..31443e1bf 100644 --- a/src/gui/DeveloperDialog.cxx +++ b/src/gui/DeveloperDialog.cxx @@ -361,7 +361,7 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font) "Recovery ", 0, kTVJitterChanged); myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20); myTVJitterRecWidget->setTickmarkIntervals(5); - myTVJitterRecWidget->setToolTip("Define speed of sync revovery."); + myTVJitterRecWidget->setToolTip("Define speed of sync recovery."); wid.push_back(myTVJitterRecWidget); myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font, myTVJitterRecWidget->getRight() + 4, From 1636f1517cad1133096e0156711a3691fd215dbf Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 21 Nov 2020 14:38:32 +0100 Subject: [PATCH 241/263] fixed #732 --- src/emucore/FBSurface.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index 6421dd171..bd7a3ad7b 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -299,6 +299,7 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, void FBSurface::splitString(const GUI::Font& font, const string& s, int w, string& left, string& right) const { +#ifdef GUI_SUPPORT uInt32 pos; int w2 = 0; bool split = false; @@ -329,6 +330,7 @@ void FBSurface::splitString(const GUI::Font& font, const string& s, int w, } left = s.substr(0, pos); right = s.substr(pos); +#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 4c97ec89c9be1c7100c19ab359e5703e2ac89de9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 21 Nov 2020 14:59:31 +0100 Subject: [PATCH 242/263] improved wildcard handling (addresses #154) --- src/gui/Dialog.cxx | 2 +- src/gui/LauncherDialog.cxx | 65 +++++++++++++++++++++++--------------- src/gui/LauncherDialog.hxx | 32 +++++++++++++------ 3 files changed, 63 insertions(+), 36 deletions(-) diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 2ff6a4539..9994bac45 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -264,7 +264,7 @@ void Dialog::render() if(!onTop) { - cerr << " shade " << typeid(*this).name() << endl; + //cerr << " shade " << typeid(*this).name() << endl; _shadeSurface->setDstRect(_surface->dstRect()); _shadeSurface->render(); diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 11fa0fc06..f2b80c7d2 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -352,54 +352,69 @@ size_t LauncherDialog::matchWithJoker(const string& str, const string& pattern) { if(str.length() >= pattern.length()) { - for(size_t pos = 0; pos < str.length() - pattern.length() + 1; ++pos) + // optimize a bit + if(pattern.find('?') != string::npos) { - bool found = true; + for(size_t pos = 0; pos < str.length() - pattern.length() + 1; ++pos) + { + bool found = true; - for(size_t i = 0; found && i < pattern.length(); ++i) - if(pattern[i] != str[pos + i] && pattern[i] != '?') - found = false; + for(size_t i = 0; found && i < pattern.length(); ++i) + if(pattern[i] != str[pos + i] && pattern[i] != '?') + found = false; - if(found) - return pos; + if(found) + return pos; + } } + else + return str.find(pattern); } return string::npos; } bool LauncherDialog::matchWithWildcards(const string& str, const string& pattern) { - string in = str; string pat = pattern; - size_t pos = string::npos; - BSPF::toUpperCase(in); - BSPF::toUpperCase(pat); + // remove leading and trailing '*' + size_t i = 0; + while(pat[i++] == '*'); + pat = pat.substr(i - 1); - for(size_t i = 0; i < pat.length(); ++i) - if(pat[i] == '*') - { - pos = i; - break; - } + i = pat.length(); + while(pat[--i] == '*'); + pat.erase(i + 1); + + // Search for first '*' + size_t pos = pat.find('*'); if(pos != string::npos) { // '*' found, split pattern into left and right part, search recursively const string leftPat = pat.substr(0, pos); const string rightPat = pat.substr(pos + 1); - size_t posLeft = matchWithJoker(in, leftPat); + size_t posLeft = matchWithJoker(str, leftPat); if(posLeft != string::npos) - return matchWithWildcards(in.substr(pos + posLeft), rightPat); + return matchWithWildcards(str.substr(pos + posLeft), rightPat); else return false; } - else - { - // no further '*' found - return matchWithJoker(in, pat) != string::npos; - } + // no further '*' found + return matchWithJoker(str, pat) != string::npos; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool LauncherDialog::matchWithWildcardsIgnoreCase(const string& str, const string& pattern) +{ + string in = str; + string pat = pattern; + + BSPF::toUpperCase(in); + BSPF::toUpperCase(pat); + + return matchWithWildcards(in, pat); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -415,7 +430,7 @@ void LauncherDialog::applyFiltering() // Skip over files that don't match the pattern in the 'pattern' textbox if(myPattern && myPattern->getText() != "" && - !matchWithWildcards(node.getName(), myPattern->getText())) + !matchWithWildcardsIgnoreCase(node.getName(), myPattern->getText())) return false; } return true; diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index 6fafab663..205fd090d 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -113,6 +113,28 @@ class LauncherDialog : public Dialog void saveConfig() override; void updateUI(); + /** + Search if string contains pattern including wildcard '*' + and '?' as joker, ignoring case. + + @param str The searched string + @param pattern The pattern to search for + + @return True if pattern was found. + */ + bool matchWithWildcardsIgnoreCase(const string& str, const string& pattern); + + /** + Search if string contains pattern including wildcard '*' + and '?' as joker. + + @param str The searched string + @param pattern The pattern to search for + + @return True if pattern was found. + */ + bool matchWithWildcards(const string& str, const string& pattern); + /** Search if string contains pattern including '?' as joker. @@ -123,16 +145,6 @@ class LauncherDialog : public Dialog */ size_t matchWithJoker(const string& str, const string& pattern); - /** - Search if string contains pattern including wildcard '*' - and '?' as joker, ignoring case. - - @param str The searched string - @param pattern The pattern to search for - - @return True if pattern was found. - */ - bool matchWithWildcards(const string& str, const string& pattern); void applyFiltering(); float getRomInfoZoom(int listHeight) const; From 1219fe0d2ca2bd8d0b7b820487f7a7fc03c7ce47 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 22 Nov 2020 12:39:17 +0100 Subject: [PATCH 243/263] added subdirectory search to launcher enhanced ProgressDialog --- src/emucore/FSNode.cxx | 106 +++++++++++++++++++++++---- src/emucore/FSNode.hxx | 14 +++- src/gui/ContextMenu.hxx | 2 + src/gui/Dialog.cxx | 7 +- src/gui/Dialog.hxx | 2 + src/gui/DialogContainer.cxx | 2 +- src/gui/FileListWidget.cxx | 39 +++++++++- src/gui/FileListWidget.hxx | 18 ++++- src/gui/LauncherDialog.cxx | 138 +++++++++++++++++++++++++++++------- src/gui/LauncherDialog.hxx | 22 +++--- src/gui/ProgressDialog.cxx | 37 ++++++++-- src/gui/ProgressDialog.hxx | 8 ++- src/gui/ToolTip.cxx | 2 +- 13 files changed, 330 insertions(+), 67 deletions(-) diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index f2e5e477a..6be4078b0 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -76,9 +76,62 @@ bool FilesystemNode::exists() const return _realNode ? _realNode->exists() : false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode, + const NameFilter& filter, + bool includeParentDirectory) const +{ + if(getChildren(fslist, mode, filter, includeParentDirectory)) + { + // Sort only once at the end + #if defined(ZIP_SUPPORT) + // before sorting, replace single file ZIP archive names with contained file names + // because they are displayed using their contained file names + for(auto& i : fslist) + { + if(BSPF::endsWithIgnoreCase(i.getPath(), ".zip")) + { + FilesystemNodeZIP zipNode(i.getPath()); + + i.setName(zipNode.getName()); + } + } + #endif + + std::sort(fslist.begin(), fslist.end(), + [](const FilesystemNode& node1, const FilesystemNode& node2) + { + if(node1.isDirectory() != node2.isDirectory()) + return node1.isDirectory(); + else + return BSPF::compareIgnoreCase(node1.getName(), node2.getName()) < 0; + } + ); + + #if defined(ZIP_SUPPORT) + // After sorting replace zip files with zip nodes + for(auto& i : fslist) + { + if(BSPF::endsWithIgnoreCase(i.getPath(), ".zip")) + { + // Force ZIP c'tor to be called + AbstractFSNodePtr ptr = FilesystemNodeFactory::create(i.getPath(), + FilesystemNodeFactory::Type::ZIP); + FilesystemNode zipNode(ptr); + i = zipNode; + } + } + #endif + return true; + } + + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, const NameFilter& filter, + bool includeChildDirectories, bool includeParentDirectory) const { if (!_realNode || !_realNode->isDirectory()) @@ -90,12 +143,15 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, if (!_realNode->getChildren(tmp, mode)) return false; + // when incuding child directories, everything must be sorted once at the end + if(!includeChildDirectories) + { #if defined(ZIP_SUPPORT) // before sorting, replace single file ZIP archive names with contained file names // because they are displayed using their contained file names - for (auto& i : tmp) + for(auto& i : tmp) { - if (BSPF::endsWithIgnoreCase(i->getPath(), ".zip")) + if(BSPF::endsWithIgnoreCase(i->getPath(), ".zip")) { FilesystemNodeZIP node(i->getPath()); @@ -104,15 +160,16 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, } #endif - std::sort(tmp.begin(), tmp.end(), - [](const AbstractFSNodePtr& node1, const AbstractFSNodePtr& node2) + std::sort(tmp.begin(), tmp.end(), + [](const AbstractFSNodePtr& node1, const AbstractFSNodePtr& node2) { - if (node1->isDirectory() != node2->isDirectory()) + if(node1->isDirectory() != node2->isDirectory()) return node1->isDirectory(); else return BSPF::compareIgnoreCase(node1->getName(), node2->getName()) < 0; } - ); + ); + } // Add parent node, if it is valid to do so if (includeParentDirectory && hasParent()) @@ -130,21 +187,44 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, { // Force ZIP c'tor to be called AbstractFSNodePtr ptr = FilesystemNodeFactory::create(i->getPath(), - FilesystemNodeFactory::Type::ZIP); - FilesystemNode node(ptr); - if (filter(node)) - fslist.emplace_back(node); + FilesystemNodeFactory::Type::ZIP); + FilesystemNode zipNode(ptr); + + if(filter(zipNode)) + { + if(!includeChildDirectories) + fslist.emplace_back(zipNode); + else + { + // filter by zip node but add file node + FilesystemNode node(i); + fslist.emplace_back(node); + } + } } else #endif { // Make directories stand out - if (i->isDirectory()) + if(i->isDirectory()) i->setName(" [" + i->getName() + "]"); FilesystemNode node(i); - if (filter(node)) - fslist.emplace_back(node); + + if(includeChildDirectories) + { + if(i->isDirectory()) + node.getChildren(fslist, mode, filter, includeChildDirectories, false); + else + // do not add directories in this mode + if(filter(node)) + fslist.emplace_back(node); + } + else + { + if(filter(node)) + fslist.emplace_back(node); + } } } diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index cf76f9ac1..b7b93bd5d 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -114,6 +114,17 @@ class FilesystemNode */ bool exists() const; + /** + * Return a list of child nodes of this and all sub-directories. If called on a node + * that does not represent a directory, false is returned. + * + * @return true if successful, false otherwise (e.g. when the directory + * does not exist). + */ + bool getAllChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly, + const NameFilter& filter = [](const FilesystemNode&) { return true; }, + bool includeParentDirectory = true) const; + /** * Return a list of child nodes of this directory node. If called on a node * that does not represent a directory, false is returned. @@ -123,6 +134,7 @@ class FilesystemNode */ bool getChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly, const NameFilter& filter = [](const FilesystemNode&){ return true; }, + bool includeChildDirectories = false, bool includeParentDirectory = true) const; /** @@ -273,8 +285,8 @@ class FilesystemNode string getPathWithExt(const string& ext) const; private: - AbstractFSNodePtr _realNode; explicit FilesystemNode(const AbstractFSNodePtr& realNode); + AbstractFSNodePtr _realNode; void setPath(const string& path); }; diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index f1736e517..6807635ba 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -45,6 +45,8 @@ class ContextMenu : public Dialog, public CommandSender const VariantList& items, int cmd = 0, int width = 0); ~ContextMenu() override = default; + bool isShading() const override { return false; } + /** Set the parent widget's ID */ void setID(uInt32 id) { _id = id; } diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 9994bac45..50fcbd295 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -255,12 +255,11 @@ void Dialog::render() }); } - // Dialog is still on top if e.g a dialog without title is opened - // (e.g. ContextMenu) + // A dialog is still on top if a non-shading dialog (e.g. ContextMenu) + // is opended above it. bool onTop = parent().myDialogStack.top() == this || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this - && !parent().myDialogStack.top()->hasTitle()); - //&& typeid(*parent().myDialogStack.top()) == typeid(ContextMenu)) + && !parent().myDialogStack.top()->isShading()); if(!onTop) { diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 7935f1c95..a6fd7259b 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -94,6 +94,8 @@ class Dialog : public GuiObject void setTitle(const string& title); bool hasTitle() { return !_title.empty(); } + virtual bool isShading() const { return true; } + /** Determine the maximum width/height of a dialog based on the minimum allowable bounds, also taking into account the current window size. diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 273b713c8..16f32536a 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -171,7 +171,7 @@ void DialogContainer::removeDialog() { if(!myDialogStack.empty()) { - cerr << "remove dialog " << typeid(*myDialogStack.top()).name() << endl; + //cerr << "remove dialog " << typeid(*myDialogStack.top()).name() << endl; myDialogStack.pop(); // Inform the frame buffer that it has to render all surfaces diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index cb3b0f5c9..42d497d92 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -20,6 +20,7 @@ #include "ScrollBarWidget.hxx" #include "FileListWidget.hxx" #include "TimerManager.hxx" +#include "ProgressDialog.hxx" #include "bspf.hxx" @@ -72,22 +73,37 @@ void FileListWidget::setDirectory(const FilesystemNode& node, void FileListWidget::setLocation(const FilesystemNode& node, const string& select) { + progress().resetProgress(); + progress().open(); + _node = node; // Read in the data from the file system (start with an empty list) _fileList.clear(); - _fileList.reserve(512); - _node.getChildren(_fileList, _fsmode, _filter); + + if(_includeSubDirs) + { + // Actually this could become HUGE + _fileList.reserve(0x2000); + _node.getAllChildren(_fileList, _fsmode, _filter); + } + else + { + _fileList.reserve(0x200); + _node.getChildren(_fileList, _fsmode, _filter); + } // Now fill the list widget with the names from the file list StringList l; - for(const auto& file: _fileList) + for(const auto& file : _fileList) l.push_back(file.getName()); setList(l); setSelected(select); ListWidget::recalc(); + + progress().close(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -114,6 +130,21 @@ void FileListWidget::reload() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ProgressDialog& FileListWidget::progress() +{ + if(myProgressDialog == nullptr) + myProgressDialog = make_unique(this, _font, "", false); + + return *myProgressDialog; +} + +void FileListWidget::incProgress() +{ + if(_includeSubDirs) + progress().incProgress(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FileListWidget::handleText(char text) { @@ -202,3 +233,5 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300; + +unique_ptr FileListWidget::myProgressDialog{nullptr}; diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx index 8b60fac44..b5ba5bf7e 100644 --- a/src/gui/FileListWidget.hxx +++ b/src/gui/FileListWidget.hxx @@ -19,6 +19,7 @@ #define FILE_LIST_WIDGET_HXX class CommandSender; +class ProgressDialog; #include "FSNode.hxx" #include "Stack.hxx" @@ -59,12 +60,16 @@ class FileListWidget : public StringListWidget _filter = filter; } + // When enabled, all subdirectories will be searched too. + void setIncludeSubDirs(bool enable) { _includeSubDirs = enable; } + /** Set initial directory, and optionally select the given item. - @param node The directory to display. If this is a file, its parent - will instead be used, and the file will be selected - @param select An optional entry to select (if applicable) + @param node The directory to display. If this is a file, its parent + will instead be used, and the file will be selected + @param select An optional entry to select (if applicable) + @param recursive Recursively list sub-directories too */ void setDirectory(const FilesystemNode& node, const string& select = EmptyString); @@ -84,6 +89,12 @@ class FileListWidget : public StringListWidget static void setQuickSelectDelay(uInt64 time) { _QUICK_SELECT_DELAY = time; } + ProgressDialog& progress(); + void incProgress(); + + protected: + static unique_ptr myProgressDialog; + private: /** Very similar to setDirectory(), but also updates the history */ void setLocation(const FilesystemNode& node, const string& select); @@ -99,6 +110,7 @@ class FileListWidget : public StringListWidget FilesystemNode::NameFilter _filter; FilesystemNode _node; FSList _fileList; + bool _includeSubDirs{false}; Common::FixedStack _history; uInt32 _selected{0}; diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index f2b80c7d2..c1e7d1328 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -15,6 +15,9 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ +// TODO: +// - abort current file list reload when typing + #include "bspf.hxx" #include "Bankswitch.hxx" #include "BrowserDialog.hxx" @@ -29,6 +32,7 @@ #include "GlobalPropsDialog.hxx" #include "StellaSettingsDialog.hxx" #include "WhatsNewDialog.hxx" +#include "ProgressDialog.hxx" #include "MessageBox.hxx" #include "ToolTip.hxx" #include "OSystem.hxx" @@ -73,25 +77,71 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, buttonHeight = myUseMinimalUI ? lineHeight - VGAP * 2: lineHeight * 1.25, buttonWidth = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1)); - int xpos = HBORDER, ypos = VBORDER, lwidth = 0, lwidth2 = 0; + int xpos = HBORDER, ypos = VBORDER; WidgetArray wid; - string lblRom = "Select a ROM from the list" + ELLIPSIS; + string lblSelect = "Select a ROM from the list" + ELLIPSIS; + string lblAllFiles = "Show all files"; const string& lblFilter = "Filter"; - const string& lblAllFiles = "Show all files"; - const string& lblFound = "XXXX items found"; + string lblSubDirs = "Incl. subdirectories"; + string lblFound = "12345 items found"; tooltip().setFont(font); - lwidth = font.getStringWidth(lblRom); - lwidth2 = font.getStringWidth(lblAllFiles) + CheckboxWidget::boxSize(font); - int lwidth3 = font.getStringWidth(lblFilter); - int lwidth4 = font.getStringWidth(lblFound); + int lwSelect = font.getStringWidth(lblSelect); + int cwAllFiles = font.getStringWidth(lblAllFiles) + CheckboxWidget::prefixSize(font); + int lwFilter = font.getStringWidth(lblFilter); + int cwSubDirs = font.getStringWidth(lblSubDirs) + CheckboxWidget::prefixSize(font); + int lwFound = font.getStringWidth(lblFound); + int wTotal = HBORDER * 2 + lwSelect + cwAllFiles + lwFilter + cwSubDirs + lwFound + + EditTextWidget::calcWidth(font, "123456") + LBL_GAP * 7; + bool noSelect = false; - if(w < HBORDER * 2 + lwidth + lwidth2 + lwidth3 + lwidth4 + fontWidth * 6 + LBL_GAP * 8) + if(w < wTotal) { // make sure there is space for at least 6 characters in the filter field - lblRom = "Select a ROM" + ELLIPSIS; - lwidth = font.getStringWidth(lblRom); + lblSelect = "Select a ROM" + ELLIPSIS; + int lwSelectShort = font.getStringWidth(lblSelect); + + wTotal -= lwSelect - lwSelectShort; + lwSelect = lwSelectShort; + } + if(w < wTotal) + { + // make sure there is space for at least 6 characters in the filter field + lblSubDirs = "Subdir."; + int cwSubDirsShort = font.getStringWidth(lblSubDirs) + CheckboxWidget::prefixSize(font); + + wTotal -= cwSubDirs - cwSubDirsShort; + cwSubDirs = cwSubDirsShort; + } + if(w < wTotal) + { + // make sure there is space for at least 6 characters in the filter field + lblAllFiles = "All files"; + int cwAllFilesShort = font.getStringWidth(lblAllFiles) + CheckboxWidget::prefixSize(font); + + wTotal -= cwAllFiles - cwAllFilesShort; + cwAllFiles = cwAllFilesShort; + } + if(w < wTotal) + { + // make sure there is space for at least 6 characters in the filter field + lblFound = "12345 found"; + int lwFoundShort = font.getStringWidth(lblFound); + + wTotal -= lwFound - lwFoundShort; + lwFound = lwFoundShort; + myShortCount = true; + } + if(w < wTotal) + { + // make sure there is space for at least 6 characters in the filter field + lblSelect = ""; + int lwSelectShort = font.getStringWidth(lblSelect); + + wTotal -= lwSelect - lwSelectShort; + lwSelect = lwSelectShort; + noSelect = true; } if(myUseMinimalUI) @@ -108,31 +158,51 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, } // Show the header - new StaticTextWidget(this, font, xpos, ypos, lblRom); + new StaticTextWidget(this, font, xpos, ypos, lblSelect); // Shop the files counter - xpos = _w - HBORDER - lwidth4; + xpos = _w - HBORDER - lwFound; myRomCount = new StaticTextWidget(this, font, xpos, ypos, - lwidth4, fontHeight, + lwFound, fontHeight, "", TextAlign::Right); // Add filter that can narrow the results shown in the listing // It has to fit between both labels if(!myUseMinimalUI && w >= 640) { - int fwidth = std::min(15 * fontWidth, xpos - lwidth3 - lwidth2 - lwidth - HBORDER - LBL_GAP * 8); + int fwFilter = std::min(EditTextWidget::calcWidth(font, "123456789012345"), + xpos - cwSubDirs - lwFilter - cwAllFiles + - lwSelect - HBORDER - LBL_GAP * (noSelect ? 5 : 7)); + + // Show the subdirectories checkbox + xpos -= cwSubDirs + LBL_GAP; + mySubDirs = new CheckboxWidget(this, font, xpos, ypos, lblSubDirs, kSubDirsCmd); + mySubDirs->setEnabled(false); + ostringstream tip; + tip << "Search files in subdirectories too.\n" + << "Filter must have at least " << MIN_SUBDIRS_CHARS << " chars."; + mySubDirs->setToolTip(tip.str()); + // Show the filter input field - xpos -= fwidth + LBL_GAP; - myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwidth, lineHeight, ""); - myPattern->setToolTip("Enter filter text to reduce file list."); + xpos -= fwFilter + LBL_GAP; + myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwFilter, lineHeight, ""); + myPattern->setToolTip("Enter filter text to reduce file list.\n" + "Use '*' and '?' as wildcards."); + // Show the "Filter" label - xpos -= lwidth3 + LBL_GAP; + xpos -= lwFilter + LBL_GAP; new StaticTextWidget(this, font, xpos, ypos, lblFilter); + // Show the checkbox for all files - xpos -= lwidth2 + LBL_GAP * 3; + if(noSelect) + xpos = HBORDER; + else + xpos -= cwAllFiles + LBL_GAP * 2; myAllFiles = new CheckboxWidget(this, font, xpos, ypos, lblAllFiles, kAllfilesCmd); myAllFiles->setToolTip("Uncheck to show ROM files only."); + wid.push_back(myAllFiles); wid.push_back(myPattern); + wid.push_back(mySubDirs); } // Add list with game titles @@ -167,11 +237,11 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Add textfield to show current directory xpos = HBORDER; - ypos += myList->getHeight() + VGAP * 2; - lwidth = font.getStringWidth("Path") + LBL_GAP; - myDirLabel = new StaticTextWidget(this, font, xpos, ypos+2, lwidth, fontHeight, + ypos += myList->getHeight() + VGAP; + lwSelect = font.getStringWidth("Path") + LBL_GAP; + myDirLabel = new StaticTextWidget(this, font, xpos, ypos+2, lwSelect, fontHeight, "Path", TextAlign::Left); - xpos += lwidth; + xpos += lwSelect; myDir = new EditTextWidget(this, font, xpos, ypos, _w - xpos - HBORDER, lineHeight, ""); myDir->setEditable(false, true); myDir->clearFlags(Widget::FLAG_RETAIN_FOCUS); @@ -236,9 +306,13 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, myGlobalProps = make_unique(this, myUseMinimalUI ? osystem.frameBuffer().launcherFont() : osystem.frameBuffer().font()); + // since we cannot know how many files there are, use are really high value here + myList->progress().setRange(0, 50000, 5); + myList->progress().setMessage(" Filtering files" + ELLIPSIS + " "); + // Do we show only ROMs or all files? bool onlyROMs = instance().settings().getBool("launcherroms"); - showOnlyROMs(onlyROMs); + if(myAllFiles) myAllFiles->setState(!onlyROMs); } @@ -341,7 +415,7 @@ void LauncherDialog::updateUI() // Indicate how many files were found ostringstream buf; - buf << (myList->getList().size() - 1) << " items found"; + buf << (myList->getList().size() - 1) << (myShortCount ? " found" : " items found"); myRomCount->setLabel(buf.str()); // Update ROM info UI item @@ -422,6 +496,7 @@ void LauncherDialog::applyFiltering() { myList->setNameFilter( [&](const FilesystemNode& node) { + myList->incProgress(); if(!node.isDirectory()) { // Do we want to show only ROMs or all files? @@ -664,6 +739,11 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd, reload(); break; + case kSubDirsCmd: + myList->setIncludeSubDirs(mySubDirs->getState()); + reload(); + break; + case kLoadROMCmd: case FileListWidget::ItemActivated: saveConfig(); @@ -689,9 +769,15 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd, break; case EditableWidget::kChangedCmd: + { + bool subAllowed = myPattern->getText().length() >= MIN_SUBDIRS_CHARS; + + mySubDirs->setEnabled(subAllowed); + myList->setIncludeSubDirs(mySubDirs->getState() && subAllowed); applyFiltering(); // pattern matching taken care of directly in this method reload(); break; + } case kQuitCmd: saveConfig(); diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index 205fd090d..44601d48d 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -100,6 +100,7 @@ class LauncherDialog : public Dialog static constexpr int MIN_ROMINFO_CHARS = 30; static constexpr int MIN_ROMINFO_ROWS = 7; // full lines static constexpr int MIN_ROMINFO_LINES = 4; // extra lines + static constexpr int MIN_SUBDIRS_CHARS = 3; // minimum filter chars for subdirectory search void setPosition() override { positionAt(0); } void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override; @@ -169,19 +170,22 @@ class LauncherDialog : public Dialog // automatically sized font for ROM info viewer unique_ptr myROMInfoFont; - ButtonWidget* myStartButton{nullptr}; - ButtonWidget* myPrevDirButton{nullptr}; - ButtonWidget* myOptionsButton{nullptr}; - ButtonWidget* myQuitButton{nullptr}; + CheckboxWidget* myAllFiles{nullptr}; + EditTextWidget* myPattern{nullptr}; + CheckboxWidget* mySubDirs{nullptr}; + StaticTextWidget* myRomCount{nullptr}; FileListWidget* myList{nullptr}; + StaticTextWidget* myDirLabel{nullptr}; EditTextWidget* myDir{nullptr}; - StaticTextWidget* myRomCount{nullptr}; - EditTextWidget* myPattern{nullptr}; - CheckboxWidget* myAllFiles{nullptr}; - RomInfoWidget* myRomInfoWidget{nullptr}; + ButtonWidget* myStartButton{nullptr}; + ButtonWidget* myPrevDirButton{nullptr}; + ButtonWidget* myOptionsButton{nullptr}; + ButtonWidget* myQuitButton{nullptr}; + + RomInfoWidget* myRomInfoWidget{nullptr}; std::unordered_map myMD5List; int mySelectedItem{0}; @@ -189,9 +193,11 @@ class LauncherDialog : public Dialog bool myShowOnlyROMs{false}; bool myUseMinimalUI{false}; bool myEventHandled{false}; + bool myShortCount{false}; enum { kAllfilesCmd = 'lalf', // show all files (or ROMs only) + kSubDirsCmd = 'lred', kPrevDirCmd = 'PRVD', kOptionsCmd = 'OPTI', kQuitCmd = 'QUIT' diff --git a/src/gui/ProgressDialog.cxx b/src/gui/ProgressDialog.cxx index 04bc2adae..026e0df82 100644 --- a/src/gui/ProgressDialog.cxx +++ b/src/gui/ProgressDialog.cxx @@ -26,8 +26,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font, - const string& message) - : Dialog(boss->instance(), boss->parent()) + const string& message, bool openDialog) + : Dialog(boss->instance(), boss->parent()), + myFont(font) { const int fontWidth = font.getMaxCharWidth(), fontHeight = font.getFontHeight(), @@ -52,13 +53,23 @@ ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font, mySlider->setMinValue(1); mySlider->setMaxValue(100); - open(); + if(openDialog) + open(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ProgressDialog::setMessage(const string& message) { + const int fontWidth = myFont.getMaxCharWidth(), + HBORDER = fontWidth * 1.25; + const int lwidth = myFont.getStringWidth(message); + + // Recalculate real dimensions + _w = HBORDER * 2 + lwidth; + + myMessage->setWidth(lwidth); myMessage->setLabel(message); + mySlider->setWidth(lwidth); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -68,17 +79,25 @@ void ProgressDialog::setRange(int start, int finish, int step) myFinish = finish; myStep = int((step / 100.0) * (myFinish - myStart + 1)); - mySlider->setMinValue(myStart); + mySlider->setMinValue(myStart + myStep); mySlider->setMaxValue(myFinish); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ProgressDialog::resetProgress() +{ + myProgress = myStepProgress = 0; + mySlider->setValue(0); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ProgressDialog::setProgress(int progress) { // Only increase the progress bar if we have arrived at a new step - if(progress - mySlider->getValue() > myStep) + if(progress - myStepProgress >= myStep) { - mySlider->setValue(progress); + myStepProgress = progress; + mySlider->setValue(progress % (myFinish - myStart + 1)); // Since this dialog is usually called in a tight loop that doesn't // yield, we need to manually tell the framebuffer that a redraw is @@ -88,3 +107,9 @@ void ProgressDialog::setProgress(int progress) instance().frameBuffer().update(); } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ProgressDialog::incProgress() +{ + setProgress(++myProgress); +} diff --git a/src/gui/ProgressDialog.hxx b/src/gui/ProgressDialog.hxx index 0ec8731b5..1b36b9cef 100644 --- a/src/gui/ProgressDialog.hxx +++ b/src/gui/ProgressDialog.hxx @@ -23,23 +23,29 @@ class StaticTextWidget; class SliderWidget; #include "bspf.hxx" +#include "Dialog.hxx" class ProgressDialog : public Dialog { public: ProgressDialog(GuiObject* boss, const GUI::Font& font, - const string& message); + const string& message, bool openDialog = true); ~ProgressDialog() override = default; void setMessage(const string& message); void setRange(int begin, int end, int step); + void resetProgress(); void setProgress(int progress); + void incProgress(); private: + const GUI::Font& myFont; StaticTextWidget* myMessage{nullptr}; SliderWidget* mySlider{nullptr}; int myStart{0}, myFinish{0}, myStep{0}; + int myProgress{0}; + int myStepProgress{0}; private: // Following constructors and assignment operators not supported diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index 6e6ef9fc9..a887e0096 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -179,5 +179,5 @@ void ToolTip::show(const string& tip) void ToolTip::render() { if(myTipShown) - mySurface->render(), cerr << " render tooltip" << endl; + mySurface->render(); // , cerr << " render tooltip" << endl; } From 38bea325c35857e1c32d0c030ba12b3fd53384b5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 22 Nov 2020 14:42:46 +0100 Subject: [PATCH 244/263] fixed considering "show all files" at startup fixed launcher focus issues after exiting ROMs --- src/gui/LauncherDialog.cxx | 4 ++-- src/gui/StringListWidget.cxx | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index c1e7d1328..03be5adf3 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -294,7 +294,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, if(myUseMinimalUI) // Highlight 'Rom Listing' mySelectedItem = 0; else - mySelectedItem = 2; + mySelectedItem = 3; addToFocusList(wid); @@ -312,7 +312,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Do we show only ROMs or all files? bool onlyROMs = instance().settings().getBool("launcherroms"); - + showOnlyROMs(onlyROMs); if(myAllFiles) myAllFiles->setState(!onlyROMs); } diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx index 9173d6276..b94d1b5c4 100644 --- a/src/gui/StringListWidget.cxx +++ b/src/gui/StringListWidget.cxx @@ -82,13 +82,8 @@ string StringListWidget::getToolTip(const Common::Point& pos) const bool StringListWidget::changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const { - bool ch = getToolTipIndex(oldPos) != getToolTipIndex(newPos) + return getToolTipIndex(oldPos) != getToolTipIndex(newPos) && getToolTip(oldPos) != getToolTip(newPos); - - if(ch) - cerr << "changed" << endl; - - return ch; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 790ace5c56a37d9a3547a78705037b6736b66e48 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 22 Nov 2020 21:58:49 +0100 Subject: [PATCH 245/263] fixed small font for launcher --- src/emucore/FrameBuffer.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 91cabfe3e..f9ede53ab 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -198,7 +198,7 @@ void FrameBuffer::setupFonts() FontDesc FrameBuffer::getFontDesc(const string& name) const { if(name == "small") - return GUI::consoleBDesc; // 8x13 + return GUI::consoleDesc; // 8x13 else if(name == "low_medium") return GUI::consoleMediumBDesc; // 9x15 else if(name == "medium") From 7049bbfd663f1b6c05d85bab65819da48f65bdae Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 22 Nov 2020 22:01:29 +0100 Subject: [PATCH 246/263] updated docs --- Changes.txt | 2 ++ docs/graphics/rominfo_1x_large.png | Bin 16977 -> 28882 bytes docs/graphics/rominfo_1x_small.png | Bin 12077 -> 19415 bytes docs/graphics/rominfo_2x_small.png | Bin 36268 -> 52980 bytes docs/index.html | 21 +++++++++------------ 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Changes.txt b/Changes.txt index 6ec962851..51992c85b 100644 --- a/Changes.txt +++ b/Changes.txt @@ -20,6 +20,8 @@ * Added wildcard support to launcher dialog filter. + * Added option to search subdirectories in launcher. + * Added static tooltips to some UI items. * Added dynamic tooltips to most debugger items. diff --git a/docs/graphics/rominfo_1x_large.png b/docs/graphics/rominfo_1x_large.png index e5b08d857106049c1e5496a519aa3730529dcb4e..99fee27d28ed56513c134a6d60d39ae67299d18f 100644 GIT binary patch literal 28882 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�KP>XO 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 literal 16977 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 diff --git a/docs/graphics/rominfo_2x_small.png b/docs/graphics/rominfo_2x_small.png index da610bba01d5976ca3b3f9869ecc249a5dd610b1..4aa4d6ccab2a868d54a02d46d8b82a2c21274d0d 100644 GIT binary patch literal 52980 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∓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

    x4ir2PL1;&G{CcAIYNS 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 diff --git a/docs/index.html b/docs/index.html index 7e57b22e7..d9080cae9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3689,16 +3689,19 @@

    ROM Info Viewer width at 50% , UI sized 1280x900, large launcher font:

    -

    The text box in the upper right corner can be used to narrow down the - results in the ROM listing. When this box is empty, all files are shown - (subject to the restrictions from the filtering option, explained below). +

    The 'Show all files' checkbox allows displaying files which do not + have a valid ROM extension. The 'Filter' text box can be used to narrow down + the results in the ROM listing. When this box is empty, all files are shown. Typing characters here will show only those files that match that pattern. For example, typing 'Activision' will show only files that contain the word 'Activision' in their name. This is very useful for quickly finding a group of related ROMs.

    -

    - Note that the search is not case sensitive, so you don't need to worry about - capital or lower-case letters. Also you can use '*' and '?' as wildcards.

    +

    Note that the search is not case sensitive, so you don't need to worry about + capital or lower-case letters. Also you can use '*' and '?' as wildcards. E.g. + for '(198?)*atari' only games from the 1980s made by Atari will be listed.

    +

    When there are least three characters in the filter, the checkbox 'Incl. + subdirectories' gets enabled. When checked, Stella will search files in all + subdirectories too.

    ROM Launcher Context Menu

    @@ -3736,12 +3739,6 @@
    -
  • Show only ROM files: Selecting this reloads the current listing, - showing only files that have a valid ROM extension.
  • - -
  • Show all files: Selecting this reloads the current listing, - showing all files (with no restriction on file name).
  • -
  • Reload listing: Selecting this performs a reload of the current listing. It is an alternative to pressing the 'Control + r' key combo.
  • From 6e4052763b63a8eac7c3ef95d6126653916a75b8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 23 Nov 2020 09:08:26 +0100 Subject: [PATCH 247/263] added launcher reload delay while typing filter --- src/gui/FileListWidget.hxx | 1 + src/gui/LauncherDialog.cxx | 24 ++++++++++++++++++++++-- src/gui/LauncherDialog.hxx | 4 ++++ src/gui/WhatsNewDialog.cxx | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx index b5ba5bf7e..98c149223 100644 --- a/src/gui/FileListWidget.hxx +++ b/src/gui/FileListWidget.hxx @@ -88,6 +88,7 @@ class FileListWidget : public StringListWidget const FilesystemNode& currentDir() const { return _node; } static void setQuickSelectDelay(uInt64 time) { _QUICK_SELECT_DELAY = time; } + uInt64 getQuickSelectDelay() { return _QUICK_SELECT_DELAY; } ProgressDialog& progress(); void incProgress(); diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 03be5adf3..74f08328a 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -35,6 +35,7 @@ #include "ProgressDialog.hxx" #include "MessageBox.hxx" #include "ToolTip.hxx" +#include "TimerManager.hxx" #include "OSystem.hxx" #include "FrameBuffer.hxx" #include "FBSurface.hxx" @@ -358,6 +359,16 @@ void LauncherDialog::reload() { myMD5List.clear(); myList->reload(); + myPendingReload = false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void LauncherDialog::tick() +{ + if(myPendingReload && myReloadTime < TimerManager::getTicks() / 1000) + reload(); + + Dialog::tick(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -771,11 +782,20 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd, case EditableWidget::kChangedCmd: { bool subAllowed = myPattern->getText().length() >= MIN_SUBDIRS_CHARS; + bool subDirs = subAllowed && mySubDirs->getState(); mySubDirs->setEnabled(subAllowed); - myList->setIncludeSubDirs(mySubDirs->getState() && subAllowed); + myList->setIncludeSubDirs(subDirs); applyFiltering(); // pattern matching taken care of directly in this method - reload(); + + if(subDirs) + { + // delay (potentially slow) subdirectories reloads until user stops typing + myReloadTime = TimerManager::getTicks() / 1000 + myList->getQuickSelectDelay(); + myPendingReload = true; + } + else + reload(); break; } diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index 44601d48d..a415f1403 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -95,6 +95,8 @@ class LauncherDialog : public Dialog */ void reload(); + void tick() override; + private: static constexpr int MIN_LAUNCHER_CHARS = 24; static constexpr int MIN_ROMINFO_CHARS = 30; @@ -194,6 +196,8 @@ class LauncherDialog : public Dialog bool myUseMinimalUI{false}; bool myEventHandled{false}; bool myShortCount{false}; + bool myPendingReload{false}; + uInt64 myReloadTime{0}; enum { kAllfilesCmd = 'lalf', // show all files (or ROMs only) diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index 5892bfcfd..7c26ca186 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -49,6 +49,7 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const add(ypos, "enhanced cut/copy/paste for text editing"); add(ypos, "added undo and redo to text editing"); add(ypos, "added wildcard support to launcher dialog filter"); + add(ypos, "added option to search subdirectories in launcher"); add(ypos, "added tooltips to many UI items"); add(ypos, "increased sample size for CDFJ+"); add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')"); From b569444854ce527abf20c62ca45af06227901257 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 23 Nov 2020 22:02:52 +0100 Subject: [PATCH 248/263] added cancel option (button, enter, ESC) to ProgressDialog adapted all ProgressDialog using actions to allow canceling --- docs/index.html | 36 +++++++++++------- src/debugger/DebuggerParser.cxx | 43 +++++++++++++-------- src/emucore/FSNode.cxx | 18 ++++++--- src/emucore/FSNode.hxx | 7 +++- src/gui/FileListWidget.cxx | 24 +++++++----- src/gui/LauncherDialog.cxx | 11 ++---- src/gui/LauncherDialog.hxx | 1 - src/gui/ProgressDialog.cxx | 67 +++++++++++++++++++++++++-------- src/gui/ProgressDialog.hxx | 8 +++- src/gui/RomAuditDialog.cxx | 12 ++++-- src/gui/Widget.cxx | 30 +++++++++++++++ src/gui/Widget.hxx | 4 ++ 12 files changed, 187 insertions(+), 74 deletions(-) diff --git a/docs/index.html b/docs/index.html index d9080cae9..f1a9ecb25 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3689,19 +3689,29 @@

    ROM Info Viewer width at 50% , UI sized 1280x900, large launcher font:

    -

    The 'Show all files' checkbox allows displaying files which do not - have a valid ROM extension. The 'Filter' text box can be used to narrow down - the results in the ROM listing. When this box is empty, all files are shown. - Typing characters here will show only those files that match that - pattern. For example, typing 'Activision' will show only files that - contain the word 'Activision' in their name. This is very useful for - quickly finding a group of related ROMs.

    -

    Note that the search is not case sensitive, so you don't need to worry about - capital or lower-case letters. Also you can use '*' and '?' as wildcards. E.g. - for '(198?)*atari' only games from the 1980s made by Atari will be listed.

    -

    When there are least three characters in the filter, the checkbox 'Incl. - subdirectories' gets enabled. When checked, Stella will search files in all - subdirectories too.

    +

    The dialog items at the top can be used to define the listed files:

    + +
      +
    • + The 'Show all files' checkbox allows displaying files which do not + have a valid ROM extension. +
    • + The 'Filter' text box can be used to narrow down the results in the + ROM listing. When this box is empty, all files are shown. Typing + characters here will show only those files that match that + pattern. For example, typing 'Activision' will show only files that + contain the word 'Activision' in their name. This is very useful for + quickly finding a group of related ROMs.
      + Note that the search is not case sensitive, so you don't need to worry + about capital or lower-case letters. You also can use '*' and '?' as + wildcards. E.g. for '(198?)*atari' only ROMs from the 1980s made by + Atari will be listed. +
    • + If 'Incl. subdirectories' is checked, Stella will list matching files + from all subdirectories too. +
    • +
    +

    ROM Launcher Context Menu

    diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 73f09268f..cd631bc7e 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -1747,9 +1747,13 @@ void DebuggerParser::executeRunTo() // Create a progress dialog box to show the progress searching through the // disassembly, since this may be a time-consuming operation ostringstream buf; - buf << "RunTo searching through " << max_iterations << " disassembled instructions"; - ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str()); + ProgressDialog progress(debugger.baseDialog(), debugger.lfont()); + + buf << "RunTo searching through " << max_iterations << " disassembled instructions" + << progress.ELLIPSIS; + progress.setMessage(buf.str()); progress.setRange(0, max_iterations, 5); + progress.open(); bool done = false; do { @@ -1763,8 +1767,8 @@ void DebuggerParser::executeRunTo() done = (BSPF::findIgnoreCase(next, argStrings[0]) != string::npos); } // Update the progress bar - progress.setProgress(count); - } while(!done && ++count < max_iterations); + progress.incProgress(); + } while(!done && ++count < max_iterations && !progress.isCancelled()); progress.close(); @@ -1789,13 +1793,15 @@ void DebuggerParser::executeRunToPc() uInt32 count = 0; bool done = false; - constexpr uInt32 max_iterations = 1000000; // Create a progress dialog box to show the progress searching through the // disassembly, since this may be a time-consuming operation ostringstream buf; - buf << "RunTo PC searching through " << max_iterations << " instructions"; - ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str()); - progress.setRange(0, max_iterations, 5); + ProgressDialog progress(debugger.baseDialog(), debugger.lfont()); + + buf << " RunTo PC running" << progress.ELLIPSIS << " "; + progress.setMessage(buf.str()); + progress.setRange(0, 100000, 5); + progress.open(); do { debugger.step(false); @@ -1803,8 +1809,9 @@ void DebuggerParser::executeRunToPc() // Update romlist to point to current PC int pcline = cartdbg.addressToLine(debugger.cpuDebug().pc()); done = (pcline >= 0) && (list[pcline].address == args[0]); - progress.setProgress(count); - } while(!done && ++count < max_iterations/*list.size()*/); + progress.incProgress(); + ++count; + } while(!done && !progress.isCancelled()); progress.close(); if(done) @@ -1953,20 +1960,24 @@ void DebuggerParser::executeStepwhile() Expression* expr = YaccParser::getResult(); int ncycles = 0; uInt32 count = 0; - constexpr uInt32 max_iterations = 1000000; // Create a progress dialog box to show the progress searching through the // disassembly, since this may be a time-consuming operation ostringstream buf; - buf << "stepwhile running through " << max_iterations << " disassembled instructions"; - ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str()); - progress.setRange(0, max_iterations, 5); + ProgressDialog progress(debugger.baseDialog(), debugger.lfont()); + + buf << "stepwhile running through disassembled instructions" + << progress.ELLIPSIS; + progress.setMessage(buf.str()); + progress.setRange(0, 100000, 5); + progress.open(); do { ncycles += debugger.step(false); - progress.setProgress(count); - } while (expr->evaluate() && ++count < max_iterations); + progress.incProgress(); + ++count; + } while (expr->evaluate() && !progress.isCancelled()); progress.close(); commandResult << "executed " << ncycles << " cycles"; diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 6be4078b0..6ff0b6482 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -79,9 +79,10 @@ bool FilesystemNode::exists() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode, const NameFilter& filter, - bool includeParentDirectory) const + bool includeParentDirectory, + const CancelCheck& isCancelled) const { - if(getChildren(fslist, mode, filter, includeParentDirectory)) + if(getChildren(fslist, mode, filter, includeParentDirectory, true, isCancelled)) { // Sort only once at the end #if defined(ZIP_SUPPORT) @@ -124,7 +125,6 @@ bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode, #endif return true; } - return false; } @@ -132,7 +132,8 @@ bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode, bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, const NameFilter& filter, bool includeChildDirectories, - bool includeParentDirectory) const + bool includeParentDirectory, + const CancelCheck& isCancelled) const { if (!_realNode || !_realNode->isDirectory()) return false; @@ -146,6 +147,9 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, // when incuding child directories, everything must be sorted once at the end if(!includeChildDirectories) { + if(isCancelled()) + return false; + #if defined(ZIP_SUPPORT) // before sorting, replace single file ZIP archive names with contained file names // because they are displayed using their contained file names @@ -182,6 +186,9 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, // And now add the rest of the entries for (const auto& i: tmp) { + if(isCancelled()) + return false; + #if defined(ZIP_SUPPORT) if (BSPF::endsWithIgnoreCase(i->getPath(), ".zip")) { @@ -214,7 +221,7 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, if(includeChildDirectories) { if(i->isDirectory()) - node.getChildren(fslist, mode, filter, includeChildDirectories, false); + node.getChildren(fslist, mode, filter, includeChildDirectories, false, isCancelled); else // do not add directories in this mode if(filter(node)) @@ -227,7 +234,6 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, } } } - return true; } diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index b7b93bd5d..05378d185 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -57,6 +57,7 @@ class FilesystemNode /** Function used to filter the file listing. Returns true if the filename should be included, else false.*/ using NameFilter = std::function; + using CancelCheck = std::function const; /** * Create a new pathless FilesystemNode. Since there's no path associated @@ -123,7 +124,8 @@ class FilesystemNode */ bool getAllChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly, const NameFilter& filter = [](const FilesystemNode&) { return true; }, - bool includeParentDirectory = true) const; + bool includeParentDirectory = true, + const CancelCheck& isCancelled = []() { return false; }) const; /** * Return a list of child nodes of this directory node. If called on a node @@ -135,7 +137,8 @@ class FilesystemNode bool getChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly, const NameFilter& filter = [](const FilesystemNode&){ return true; }, bool includeChildDirectories = false, - bool includeParentDirectory = true) const; + bool includeParentDirectory = true, + const CancelCheck& isCancelled = []() { return false; }) const; /** * Set/get a string representation of the name of the file. This is can be diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index 42d497d92..be68d632f 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -75,6 +75,9 @@ void FileListWidget::setLocation(const FilesystemNode& node, { progress().resetProgress(); progress().open(); + class FilesystemNode::CancelCheck isCancelled = []() { + return myProgressDialog->isCancelled(); + }; _node = node; @@ -85,21 +88,24 @@ void FileListWidget::setLocation(const FilesystemNode& node, { // Actually this could become HUGE _fileList.reserve(0x2000); - _node.getAllChildren(_fileList, _fsmode, _filter); + _node.getAllChildren(_fileList, _fsmode, _filter, true, isCancelled); } else { _fileList.reserve(0x200); - _node.getChildren(_fileList, _fsmode, _filter); + _node.getChildren(_fileList, _fsmode, _filter, false, true, isCancelled); } - // Now fill the list widget with the names from the file list - StringList l; - for(const auto& file : _fileList) - l.push_back(file.getName()); + if(!isCancelled()) + { + // Now fill the list widget with the names from the file list + StringList l; + for(const auto& file : _fileList) + l.push_back(file.getName()); - setList(l); - setSelected(select); + setList(l); + setSelected(select); + } ListWidget::recalc(); @@ -134,7 +140,7 @@ void FileListWidget::reload() ProgressDialog& FileListWidget::progress() { if(myProgressDialog == nullptr) - myProgressDialog = make_unique(this, _font, "", false); + myProgressDialog = make_unique(this, _font, ""); return *myProgressDialog; } diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 74f08328a..87d0938b4 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -177,10 +177,8 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, // Show the subdirectories checkbox xpos -= cwSubDirs + LBL_GAP; mySubDirs = new CheckboxWidget(this, font, xpos, ypos, lblSubDirs, kSubDirsCmd); - mySubDirs->setEnabled(false); ostringstream tip; - tip << "Search files in subdirectories too.\n" - << "Filter must have at least " << MIN_SUBDIRS_CHARS << " chars."; + tip << "Search files in subdirectories too."; mySubDirs->setToolTip(tip.str()); // Show the filter input field @@ -780,15 +778,14 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd, break; case EditableWidget::kChangedCmd: + case EditableWidget::kAcceptCmd: { - bool subAllowed = myPattern->getText().length() >= MIN_SUBDIRS_CHARS; - bool subDirs = subAllowed && mySubDirs->getState(); + bool subDirs = mySubDirs->getState(); - mySubDirs->setEnabled(subAllowed); myList->setIncludeSubDirs(subDirs); applyFiltering(); // pattern matching taken care of directly in this method - if(subDirs) + if(subDirs && cmd == EditableWidget::kChangedCmd) { // delay (potentially slow) subdirectories reloads until user stops typing myReloadTime = TimerManager::getTicks() / 1000 + myList->getQuickSelectDelay(); diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index a415f1403..a5acc262f 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -102,7 +102,6 @@ class LauncherDialog : public Dialog static constexpr int MIN_ROMINFO_CHARS = 30; static constexpr int MIN_ROMINFO_ROWS = 7; // full lines static constexpr int MIN_ROMINFO_LINES = 4; // extra lines - static constexpr int MIN_SUBDIRS_CHARS = 3; // minimum filter chars for subdirectory search void setPosition() override { positionAt(0); } void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override; diff --git a/src/gui/ProgressDialog.cxx b/src/gui/ProgressDialog.cxx index 026e0df82..e36cf6008 100644 --- a/src/gui/ProgressDialog.cxx +++ b/src/gui/ProgressDialog.cxx @@ -18,6 +18,8 @@ #include "bspf.hxx" #include "OSystem.hxx" #include "FrameBuffer.hxx" +#include "EventHandler.hxx" +#include "TimerManager.hxx" #include "Widget.hxx" #include "Dialog.hxx" #include "Font.hxx" @@ -26,7 +28,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font, - const string& message, bool openDialog) + const string& message) : Dialog(boss->instance(), boss->parent()), myFont(font) { @@ -35,41 +37,56 @@ ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font, lineHeight = font.getLineHeight(), VBORDER = fontHeight / 2, HBORDER = fontWidth * 1.25, - VGAP = fontHeight / 4; - int xpos, ypos, lwidth; + VGAP = fontHeight / 4, + buttonHeight = font.getLineHeight() * 1.25, + BTN_BORDER = fontWidth * 2.5, + buttonWidth = font.getStringWidth("Cancel") + BTN_BORDER, + lwidth = font.getStringWidth(message); + + int xpos, ypos; + WidgetArray wid; // Calculate real dimensions - lwidth = font.getStringWidth(message); - _w = HBORDER * 2 + lwidth; - _h = VBORDER * 2 + lineHeight * 2 + VGAP * 2; + _w = HBORDER * 2 + std::max(lwidth, buttonWidth); + _h = VBORDER * 2 + lineHeight * 2 + buttonHeight + VGAP * 6; xpos = HBORDER; ypos = VBORDER; myMessage = new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight, message, TextAlign::Center); myMessage->setTextColor(kTextColorEm); - xpos = HBORDER; ypos += lineHeight + VGAP * 2; - mySlider = new SliderWidget(this, font, xpos, ypos, lwidth, lineHeight, "", 0, 0); + ypos += lineHeight + VGAP * 2; + mySlider = new SliderWidget(this, font, xpos, ypos, lwidth, lineHeight, + "", 0, 0); mySlider->setMinValue(1); mySlider->setMaxValue(100); - if(openDialog) - open(); + ypos += lineHeight + VGAP * 4; + ButtonWidget* b = new ButtonWidget(this, font, (_w - buttonWidth) / 2, ypos, + buttonWidth, buttonHeight, "Cancel", + Event::UICancel); + wid.push_back(b); + addCancelWidget(b); + addToFocusList(wid); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ProgressDialog::setMessage(const string& message) { const int fontWidth = myFont.getMaxCharWidth(), - HBORDER = fontWidth * 1.25; - const int lwidth = myFont.getStringWidth(message); + HBORDER = fontWidth * 1.25, + lwidth = myFont.getStringWidth(message), + BTN_BORDER = fontWidth * 2.5, + buttonWidth = myFont.getStringWidth("Cancel") + BTN_BORDER; // Recalculate real dimensions - _w = HBORDER * 2 + lwidth; + _w = HBORDER * 2 + std::max(lwidth, buttonWidth); myMessage->setWidth(lwidth); myMessage->setLabel(message); mySlider->setWidth(lwidth); + + _cancelWidget->setPos((_w - buttonWidth) / 2, _cancelWidget->getTop()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -88,6 +105,7 @@ void ProgressDialog::resetProgress() { myProgress = myStepProgress = 0; mySlider->setValue(0); + myIsCancelled = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -100,11 +118,13 @@ void ProgressDialog::setProgress(int progress) mySlider->setValue(progress % (myFinish - myStart + 1)); // Since this dialog is usually called in a tight loop that doesn't - // yield, we need to manually tell the framebuffer that a redraw is - // necessary + // yield, we need to manually: + // - tell the framebuffer that a redraw is necessary + // - poll the events // This isn't really an ideal solution, since all redrawing and // event handling is suspended until the dialog is closed instance().frameBuffer().update(); + instance().eventHandler().poll(TimerManager::getTicks()); } } @@ -113,3 +133,20 @@ void ProgressDialog::incProgress() { setProgress(++myProgress); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ProgressDialog::handleCommand(CommandSender* sender, int cmd, + int data, int id) +{ + switch(cmd) + { + case Event::UICancel: + myIsCancelled = true; + break; + + default: + Dialog::handleCommand(sender, cmd, data, 0); + break; + } +} + diff --git a/src/gui/ProgressDialog.hxx b/src/gui/ProgressDialog.hxx index 1b36b9cef..a62fb8cbf 100644 --- a/src/gui/ProgressDialog.hxx +++ b/src/gui/ProgressDialog.hxx @@ -21,6 +21,7 @@ class GuiObject; class StaticTextWidget; class SliderWidget; +class ButtonWidget; #include "bspf.hxx" #include "Dialog.hxx" @@ -29,7 +30,7 @@ class ProgressDialog : public Dialog { public: ProgressDialog(GuiObject* boss, const GUI::Font& font, - const string& message, bool openDialog = true); + const string& message = ""); ~ProgressDialog() override = default; void setMessage(const string& message); @@ -37,6 +38,7 @@ class ProgressDialog : public Dialog void resetProgress(); void setProgress(int progress); void incProgress(); + bool isCancelled() const { return myIsCancelled; } private: const GUI::Font& myFont; @@ -46,6 +48,10 @@ class ProgressDialog : public Dialog int myStart{0}, myFinish{0}, myStep{0}; int myProgress{0}; int myStepProgress{0}; + bool myIsCancelled{false}; + + private: + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; private: // Following constructors and assignment operators not supported diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx index 09c264025..a95e4fce5 100644 --- a/src/gui/RomAuditDialog.cxx +++ b/src/gui/RomAuditDialog.cxx @@ -119,13 +119,17 @@ void RomAuditDialog::auditRoms() // Create a progress dialog box to show the progress of processing // the ROMs, since this is usually a time-consuming operation - ProgressDialog progress(this, instance().frameBuffer().font(), - "Auditing ROM files ..."); + ostringstream buf; + ProgressDialog progress(this, instance().frameBuffer().font()); + + buf << "Auditing ROM files" << ELLIPSIS; + progress.setMessage(buf.str()); progress.setRange(0, int(files.size()) - 1, 5); + progress.open(); Properties props; uInt32 renamed = 0, notfound = 0; - for(uInt32 idx = 0; idx < files.size(); ++idx) + for(uInt32 idx = 0; idx < files.size() && !progress.isCancelled(); ++idx) { string extension; if(files[idx].isFile() && @@ -156,7 +160,7 @@ void RomAuditDialog::auditRoms() } // Update the progress bar, indicating one more ROM has been processed - progress.setProgress(idx); + progress.incProgress(); } progress.close(); diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index e0b9a2389..61b9296cb 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -173,6 +173,36 @@ void Widget::drawChain() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setPosX(int x) +{ + setPos(x, _y); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setPosY(int y) +{ + setPos(_x, y); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setPos(int x, int y) +{ + setPos(Common::Point(x, y)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setPos(const Common::Point& pos) +{ + if(pos != Common::Point(_x, _y)) + { + _x = pos.x; + _y = pos.y; + // we have to redraw the whole dialog! + dialog().setDirty(); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Widget::handleMouseEntered() { diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 64685813a..cf4637ea1 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -53,6 +53,10 @@ class Widget : public GuiObject virtual int getTop() const { return _y; } virtual int getRight() const { return _x + getWidth(); } virtual int getBottom() const { return _y + getHeight(); } + virtual void setPosX(int x); + virtual void setPosY(int y); + virtual void setPos(int x, int y); + virtual void setPos(const Common::Point& pos); virtual bool handleText(char text) { return false; } virtual bool handleKeyDown(StellaKey key, StellaMod mod) { return false; } From c51d4846d8193cdad75e65ff10904a3ff91e31f3 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Mon, 23 Nov 2020 17:39:43 -0330 Subject: [PATCH 249/263] Fix compile warning and error in clang. --- src/gui/FileListWidget.cxx | 2 +- src/gui/FileListWidget.hxx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index be68d632f..c0a889f1b 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -75,7 +75,7 @@ void FileListWidget::setLocation(const FilesystemNode& node, { progress().resetProgress(); progress().open(); - class FilesystemNode::CancelCheck isCancelled = []() { + FilesystemNode::CancelCheck isCancelled = []() { return myProgressDialog->isCancelled(); }; diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx index 98c149223..63c39136f 100644 --- a/src/gui/FileListWidget.hxx +++ b/src/gui/FileListWidget.hxx @@ -69,7 +69,6 @@ class FileListWidget : public StringListWidget @param node The directory to display. If this is a file, its parent will instead be used, and the file will be selected @param select An optional entry to select (if applicable) - @param recursive Recursively list sub-directories too */ void setDirectory(const FilesystemNode& node, const string& select = EmptyString); From bc3c8518a2db76794ed95485c0489163b3dff38a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 24 Nov 2020 12:50:43 +0100 Subject: [PATCH 250/263] added path info to launcher tooltips when displaying sub directories fixed launcher files list when filtering was canceled added persisting 'incl. subdirectories' setting --- src/emucore/FBSurface.cxx | 2 +- src/emucore/Settings.cxx | 2 ++ src/gui/FileListWidget.cxx | 48 +++++++++++++++++++++++++++++------- src/gui/FileListWidget.hxx | 5 ++++ src/gui/LauncherDialog.cxx | 28 +++++++++++---------- src/gui/StringListWidget.hxx | 4 +-- 6 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx index bd7a3ad7b..16030b579 100644 --- a/src/emucore/FBSurface.cxx +++ b/src/emucore/FBSurface.cxx @@ -336,7 +336,7 @@ void FBSurface::splitString(const GUI::Font& font, const string& s, int w, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FBSurface::isWhiteSpace(const char s) const { - const string WHITESPACES = " ,.;:+-*/'([\n"; + const string WHITESPACES = " ,.;:+-*/\\'([\n"; for(size_t i = 0; i < WHITESPACES.length(); ++i) if(s == WHITESPACES[i]) diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index f7fa27ae8..a074f5697 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -145,6 +145,7 @@ Settings::Settings() setPermanent("launcherres", Common::Size(900, 600)); setPermanent("launcherfont", "medium"); setPermanent("launcherroms", "true"); + setPermanent("launchersubdirs", "false"); setPermanent("romviewer", "1"); setPermanent("lastrom", ""); @@ -542,6 +543,7 @@ void Settings::usage() const << " large12|large14|\n" << " large16>\n" << " -launcherroms <1|0> Show only ROMs in the launcher (vs. all files)\n" + << " -launchersubdirs <1|0> Show files from subdirectories too\n" << " -romviewer Show ROM info viewer at given zoom level in ROM\n" << " launcher (use 0 for off)\n" << " -followlauncher <0|1> Default ROM path follows launcher navigation\n" diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index c0a889f1b..6aaa9be1c 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -75,7 +75,7 @@ void FileListWidget::setLocation(const FilesystemNode& node, { progress().resetProgress(); progress().open(); - FilesystemNode::CancelCheck isCancelled = []() { + class FilesystemNode::CancelCheck isCancelled = []() { return myProgressDialog->isCancelled(); }; @@ -96,17 +96,26 @@ void FileListWidget::setLocation(const FilesystemNode& node, _node.getChildren(_fileList, _fsmode, _filter, false, true, isCancelled); } - if(!isCancelled()) - { - // Now fill the list widget with the names from the file list - StringList l; - for(const auto& file : _fileList) - l.push_back(file.getName()); + // Now fill the list widget with the names from the file list, + // even if cancelled + StringList l; + size_t orgLen = node.getShortPath().length(); - setList(l); - setSelected(select); + _dirList.clear(); + for(const auto& file : _fileList) + { + const string path = file.getShortPath(); + + l.push_back(file.getName()); + // display only relative path in tooltip + if(path.length() >= orgLen) + _dirList.push_back(path.substr(orgLen)); + else + _dirList.push_back(path); } + setList(l); + setSelected(select); ListWidget::recalc(); progress().close(); @@ -237,6 +246,27 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int setTarget(this); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string FileListWidget::getToolTip(const Common::Point& pos) const +{ + Common::Rect rect = getEditRect(); + int idx = getToolTipIndex(pos); + + if(idx < 0) + return EmptyString; + + if(_includeSubDirs && _dirList.size() > idx) + return _toolTipText + _dirList[idx]; + + const string value = _list[idx]; + + if(uInt32(_font.getStringWidth(value)) > rect.w()) + return _toolTipText + value; + else + return _toolTipText; +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300; diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx index 63c39136f..088ed56b3 100644 --- a/src/gui/FileListWidget.hxx +++ b/src/gui/FileListWidget.hxx @@ -53,6 +53,8 @@ class FileListWidget : public StringListWidget int x, int y, int w, int h); ~FileListWidget() override = default; + string getToolTip(const Common::Point& pos) const override; + /** Determines how to display files/folders; either setDirectory or reload must be called after any of these are called. */ void setListMode(FilesystemNode::ListMode mode) { _fsmode = mode; } @@ -69,6 +71,7 @@ class FileListWidget : public StringListWidget @param node The directory to display. If this is a file, its parent will instead be used, and the file will be selected @param select An optional entry to select (if applicable) + @param recursive Recursively list sub-directories too */ void setDirectory(const FilesystemNode& node, const string& select = EmptyString); @@ -112,6 +115,8 @@ class FileListWidget : public StringListWidget FSList _fileList; bool _includeSubDirs{false}; + StringList _dirList; + Common::FixedStack _history; uInt32 _selected{0}; string _selectedFile; diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 87d0938b4..ca4101601 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -15,9 +15,6 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -// TODO: -// - abort current file list reload when typing - #include "bspf.hxx" #include "Bankswitch.hxx" #include "BrowserDialog.hxx" @@ -90,10 +87,10 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, int lwSelect = font.getStringWidth(lblSelect); int cwAllFiles = font.getStringWidth(lblAllFiles) + CheckboxWidget::prefixSize(font); - int lwFilter = font.getStringWidth(lblFilter); int cwSubDirs = font.getStringWidth(lblSubDirs) + CheckboxWidget::prefixSize(font); + int lwFilter = font.getStringWidth(lblFilter); int lwFound = font.getStringWidth(lblFound); - int wTotal = HBORDER * 2 + lwSelect + cwAllFiles + lwFilter + cwSubDirs + lwFound + int wTotal = HBORDER * 2 + lwSelect + cwAllFiles + cwSubDirs + lwFilter + lwFound + EditTextWidget::calcWidth(font, "123456") + LBL_GAP * 7; bool noSelect = false; @@ -174,13 +171,6 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, xpos - cwSubDirs - lwFilter - cwAllFiles - lwSelect - HBORDER - LBL_GAP * (noSelect ? 5 : 7)); - // Show the subdirectories checkbox - xpos -= cwSubDirs + LBL_GAP; - mySubDirs = new CheckboxWidget(this, font, xpos, ypos, lblSubDirs, kSubDirsCmd); - ostringstream tip; - tip << "Search files in subdirectories too."; - mySubDirs->setToolTip(tip.str()); - // Show the filter input field xpos -= fwFilter + LBL_GAP; myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwFilter, lineHeight, ""); @@ -191,11 +181,18 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, xpos -= lwFilter + LBL_GAP; new StaticTextWidget(this, font, xpos, ypos, lblFilter); + // Show the subdirectories checkbox + xpos -= cwSubDirs + LBL_GAP * 2; + mySubDirs = new CheckboxWidget(this, font, xpos, ypos, lblSubDirs, kSubDirsCmd); + ostringstream tip; + tip << "Search files in subdirectories too."; + mySubDirs->setToolTip(tip.str()); + // Show the checkbox for all files if(noSelect) xpos = HBORDER; else - xpos -= cwAllFiles + LBL_GAP * 2; + xpos -= cwAllFiles + LBL_GAP; myAllFiles = new CheckboxWidget(this, font, xpos, ypos, lblAllFiles, kAllfilesCmd); myAllFiles->setToolTip("Uncheck to show ROM files only."); @@ -386,6 +383,10 @@ void LauncherDialog::loadConfig() instance().settings().setValue("stella.version", STELLA_VERSION); } + bool subDirs = instance().settings().getBool("launchersubdirs"); + mySubDirs->setState(subDirs); + myList->setIncludeSubDirs(subDirs); + // Assume that if the list is empty, this is the first time that loadConfig() // has been called (and we should reload the list) if(myList->getList().empty()) @@ -408,6 +409,7 @@ void LauncherDialog::loadConfig() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void LauncherDialog::saveConfig() { + instance().settings().setValue("launchersubdirs", mySubDirs->getState()); if(instance().settings().getBool("followlauncher")) instance().settings().setValue("romdir", myList->currentDir().getShortPath()); } diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx index f0bf8544b..668414c4c 100644 --- a/src/gui/StringListWidget.hxx +++ b/src/gui/StringListWidget.hxx @@ -41,6 +41,7 @@ class StringListWidget : public ListWidget void lostFocusWidget() override { setDirty(); } bool hasToolTip() const override { return true; } + int getToolTipIndex(const Common::Point& pos) const; void drawWidget(bool hilite) override; Common::Rect getEditRect() const override; @@ -49,9 +50,6 @@ class StringListWidget : public ListWidget bool _hilite{false}; int _textOfs{0}; - private: - int getToolTipIndex(const Common::Point& pos) const; - private: // Following constructors and assignment operators not supported StringListWidget() = delete; From 8f1c84b3cc5d89af1a4de81542bc7fce9219aee4 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Tue, 24 Nov 2020 10:01:27 -0330 Subject: [PATCH 251/263] Fixed compile error and warnings from g++. --- src/debugger/gui/TiaZoomWidget.hxx | 4 +++- src/gui/FileListWidget.cxx | 4 ++-- src/gui/FileListWidget.hxx | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/debugger/gui/TiaZoomWidget.hxx b/src/debugger/gui/TiaZoomWidget.hxx index d46787f23..1cc53068f 100644 --- a/src/debugger/gui/TiaZoomWidget.hxx +++ b/src/debugger/gui/TiaZoomWidget.hxx @@ -27,12 +27,14 @@ class ContextMenu; class TiaZoomWidget : public Widget, public CommandSender { public: + using Widget::setPos; + TiaZoomWidget(GuiObject *boss, const GUI::Font& font, int x, int y, int w, int h); ~TiaZoomWidget() override = default; void loadConfig() override; - void setPos(int x, int y); + void setPos(int x, int y) override; string getToolTip(const Common::Point& pos) const override; bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index 6aaa9be1c..d2cff5261 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -75,7 +75,7 @@ void FileListWidget::setLocation(const FilesystemNode& node, { progress().resetProgress(); progress().open(); - class FilesystemNode::CancelCheck isCancelled = []() { + FilesystemNode::CancelCheck isCancelled = []() { return myProgressDialog->isCancelled(); }; @@ -255,7 +255,7 @@ string FileListWidget::getToolTip(const Common::Point& pos) const if(idx < 0) return EmptyString; - if(_includeSubDirs && _dirList.size() > idx) + if(_includeSubDirs && static_cast(_dirList.size()) > idx) return _toolTipText + _dirList[idx]; const string value = _list[idx]; diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx index 088ed56b3..32f6517f7 100644 --- a/src/gui/FileListWidget.hxx +++ b/src/gui/FileListWidget.hxx @@ -71,7 +71,6 @@ class FileListWidget : public StringListWidget @param node The directory to display. If this is a file, its parent will instead be used, and the file will be selected @param select An optional entry to select (if applicable) - @param recursive Recursively list sub-directories too */ void setDirectory(const FilesystemNode& node, const string& select = EmptyString); From 8a2cace6c85b225f6bddc6eb5ea7d87f8e492ee9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 25 Nov 2020 17:21:57 +0100 Subject: [PATCH 252/263] fixed #735 (trackball fire) --- src/emucore/PointingDevice.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emucore/PointingDevice.cxx b/src/emucore/PointingDevice.cxx index cbd7f89c9..b48c372a3 100644 --- a/src/emucore/PointingDevice.cxx +++ b/src/emucore/PointingDevice.cxx @@ -81,7 +81,7 @@ void PointingDevice::update() return; // Update horizontal direction - cerr << myEvent.get(Event::MouseAxisXMove) << ", " << myHCounterRemainder << endl; + //cerr << myEvent.get(Event::MouseAxisXMove) << ", " << myHCounterRemainder << endl; updateDirection( myEvent.get(Event::MouseAxisXMove), myHCounterRemainder, myTrackBallLeft, myTrackBallLinesH, myScanCountH, myFirstScanOffsetH); @@ -90,7 +90,7 @@ void PointingDevice::update() myTrackBallDown, myTrackBallLinesV, myScanCountV, myFirstScanOffsetV); // We allow left and right mouse buttons for fire button - setPin(DigitalPin::Six, !getAutoFireState(myEvent.get(Event::JoystickZeroFire) == 0 || + setPin(DigitalPin::Six, !getAutoFireState(myEvent.get(Event::JoystickZeroFire) || myEvent.get(Event::MouseButtonLeftValue) || myEvent.get(Event::MouseButtonRightValue))); } From 1282c1411d008b342384f1d24a2326f66fe6599a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 25 Nov 2020 17:23:05 +0100 Subject: [PATCH 253/263] fixed doc --- docs/graphics/rominfo_1x_large.png | Bin 28882 -> 45401 bytes docs/graphics/rominfo_1x_small.png | Bin 19415 -> 36557 bytes docs/graphics/rominfo_2x_small.png | Bin 52980 -> 76225 bytes docs/index.html | 6 +++--- src/emucore/FrameBuffer.cxx | 3 ++- src/gui/ProgressDialog.cxx | 2 +- src/gui/TimeLineWidget.cxx | 2 +- 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/graphics/rominfo_1x_large.png b/docs/graphics/rominfo_1x_large.png index 99fee27d28ed56513c134a6d60d39ae67299d18f..5a01334046ab195f6b983a5077581135c1e8cb29 100644 GIT binary patch literal 45401 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�KP>XO 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 diff --git a/docs/graphics/rominfo_1x_small.png b/docs/graphics/rominfo_1x_small.png index 4d6429409df619219390778884f73515b3afcc5a..99d23e135be7bca145549ed99477c3d58bba1d7c 100644 GIT binary patch literal 36557 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%0D}y@og`N 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 literal 52980 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∓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

    x4ir2PL1;&G{CcAIYNS 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 The 'Show all files' checkbox allows displaying files which do not have a valid ROM extension. +

  • + If 'Incl. subdirectories' is checked, Stella will list matching files + from all subdirectories too.
  • The 'Filter' text box can be used to narrow down the results in the ROM listing. When this box is empty, all files are shown. Typing @@ -3706,9 +3709,6 @@ about capital or lower-case letters. You also can use '*' and '?' as wildcards. E.g. for '(198?)*atari' only ROMs from the 1980s made by Atari will be listed. -
  • - If 'Incl. subdirectories' is checked, Stella will list matching files - from all subdirectories too.

  • diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index f9ede53ab..2171382c5 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -707,7 +707,8 @@ inline bool FrameBuffer::drawMessage() if(myMsg.dirty) { - cerr << "--- draw message ---" << endl; + cerr << "m"; + //cerr << "--- draw message ---" << endl; // Draw the bounded box and text const Common::Rect& dst = myMsg.surface->dstRect(); diff --git a/src/gui/ProgressDialog.cxx b/src/gui/ProgressDialog.cxx index e36cf6008..80aafc8c4 100644 --- a/src/gui/ProgressDialog.cxx +++ b/src/gui/ProgressDialog.cxx @@ -86,7 +86,7 @@ void ProgressDialog::setMessage(const string& message) myMessage->setLabel(message); mySlider->setWidth(lwidth); - _cancelWidget->setPos((_w - buttonWidth) / 2, _cancelWidget->getTop()); + _cancelWidget->setPosX((_w - buttonWidth) / 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/TimeLineWidget.cxx b/src/gui/TimeLineWidget.cxx index 4e6b9e9a0..5f6e0e687 100644 --- a/src/gui/TimeLineWidget.cxx +++ b/src/gui/TimeLineWidget.cxx @@ -143,7 +143,7 @@ void TimeLineWidget::drawWidget(bool hilite) { FBSurface& s = _boss->dialog().surface(); - cerr << "TimeLineWidget::drawWidget " << typeid(s).name() << endl; + //cerr << "TimeLineWidget::drawWidget " << typeid(s).name() << endl; // Draw the label, if any if(_labelWidth > 0) From a8e83b63edabd7eee02760d258c3b6ff96931352 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 28 Nov 2020 12:54:20 +0100 Subject: [PATCH 254/263] updated changes.txt --- Changes.txt | 2 ++ src/gui/WhatsNewDialog.cxx | 1 + 2 files changed, 3 insertions(+) diff --git a/Changes.txt b/Changes.txt index 51992c85b..c2767093b 100644 --- a/Changes.txt +++ b/Changes.txt @@ -28,6 +28,8 @@ * Increased sample size for CDFJ+. + * Fixed autofire bug for trackball controllers. + -Have fun! diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx index 7c26ca186..4baa36101 100644 --- a/src/gui/WhatsNewDialog.cxx +++ b/src/gui/WhatsNewDialog.cxx @@ -45,6 +45,7 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const #if defined(RETRON77) add(ypos, "increased sample size for CDFJ+"); add(ypos, "fixed navigation bug in Video & Audio settings dialog"); + add(ypos, "fixed autofire bug for trackball controllers"); #else add(ypos, "enhanced cut/copy/paste for text editing"); add(ypos, "added undo and redo to text editing"); From 853370913950b6f17efd61a6e8944af22b30aa7d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 28 Nov 2020 12:55:50 +0100 Subject: [PATCH 255/263] added some more tooltips to UI --- src/cheat/CheatCodeDialog.cxx | 1 + src/gui/EmulationDialog.cxx | 1 + src/gui/EventMappingWidget.cxx | 3 +++ src/gui/UIDialog.cxx | 5 +++++ 4 files changed, 10 insertions(+) diff --git a/src/cheat/CheatCodeDialog.cxx b/src/cheat/CheatCodeDialog.cxx index 09ac1cd3c..481dcbcd5 100644 --- a/src/cheat/CheatCodeDialog.cxx +++ b/src/cheat/CheatCodeDialog.cxx @@ -100,6 +100,7 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent, return (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9'); }; myCheatInput->setTextFilter(f1, 1); + myCheatInput->setToolTip("See Stella documentation for details.", 1); addToFocusList(wid); diff --git a/src/gui/EmulationDialog.cxx b/src/gui/EmulationDialog.cxx index dcbb42859..a2c0bee9c 100644 --- a/src/gui/EmulationDialog.cxx +++ b/src/gui/EmulationDialog.cxx @@ -99,6 +99,7 @@ EmulationDialog::EmulationDialog(OSystem& osystem, DialogContainer& parent, // Use sync to vblank myUseVSync = new CheckboxWidget(this, _font, xpos, ypos + 1, "VSync"); + myUseVSync->setToolTip("Check to enable vertical synced display updates."); wid.push_back(myUseVSync); ypos += lineHeight + VGAP; diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index 8051e4a56..7b3ae540b 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -97,6 +97,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myCancelMapButton = new ButtonWidget(boss, font, xpos, ypos, buttonWidth, buttonHeight, "Cancel", kStopMapCmd); + myCancelMapButton->setToolTip("Cancel current mapping."); myCancelMapButton->setTarget(this); myCancelMapButton->clearFlags(Widget::FLAG_ENABLED); addFocusWidget(myCancelMapButton); @@ -106,12 +107,14 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, buttonWidth, buttonHeight, "Erase", kEraseCmd); myEraseButton->setTarget(this); + myEraseButton->setToolTip("Erase any mapping for selected event."); addFocusWidget(myEraseButton); ypos += buttonHeight + VGAP; myResetButton = new ButtonWidget(boss, font, xpos, ypos, buttonWidth, buttonHeight, "Reset", kResetCmd); + myResetButton->setToolTip("Reset mapping for selected event to defaults."); myResetButton->setTarget(this); addFocusWidget(myResetButton); diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx index 12f710bc0..2d773b888 100644 --- a/src/gui/UIDialog.cxx +++ b/src/gui/UIDialog.cxx @@ -109,6 +109,8 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, xpos = myDialogFontPopup->getRight() + fontWidth * 5; myHidpiWidget = new CheckboxWidget(myTab, font, xpos, ypos + 1, "HiDPI mode (*)"); + myHidpiWidget->setToolTip("Scale the UI by a factor of two when enabled."); + wid.push_back(myHidpiWidget); // Dialog position @@ -126,6 +128,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, // Center window (in windowed mode) xpos = myHidpiWidget->getLeft(); myCenter = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Center windows"); + myCenter->setToolTip("Check to center all windows, else remember last position."); wid.push_back(myCenter); // Delay between quick-selecting characters in ListWidget @@ -138,6 +141,8 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent, myListDelaySlider->setMaxValue(1000); myListDelaySlider->setStepValue(50); myListDelaySlider->setTickmarkIntervals(5); + myListDelaySlider->setToolTip("Set delay between key presses in file lists" + " before a search string resets."); wid.push_back(myListDelaySlider); ypos += lineHeight + VGAP; From c1ddf81b825d1437ad4f0321edbbe5d2ccb43a10 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 28 Nov 2020 12:57:24 +0100 Subject: [PATCH 256/263] improved debugger's RAM labels --- src/debugger/CartDebug.cxx | 63 +++++++++++++++++++++++++------------- src/debugger/CartDebug.hxx | 6 ++-- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index d62b16b66..ab988e000 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -605,7 +605,8 @@ bool CartDebug::removeLabel(const string& label) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) const +bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, + int places, bool isRam) const { switch(addressType(addr)) { @@ -662,21 +663,24 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) con { // RAM can use user-defined labels; otherwise we default to // standard mnemonics - auto iter = myUserLabels.find(addr); - if(iter != myUserLabels.end()) - { - buf << iter->second; - } - else - { - uInt16 a = addr & 0xFF, offset = addr & 0xFF00; - if((iter = myUserLabels.find(a)) != myUserLabels.end()) + AddrToLabel::const_iterator iter; + uInt16 a = addr & 0xFF, offset = addr & 0xFF00; + bool found = false; + + // Search for nearest label + for(uInt16 i = a; i >= 0x80; --i) + if((iter = myUserLabels.find(i)) != myUserLabels.end()) + { buf << iter->second; - else - buf << ourZPMnemonic[a - 0x80]; - if(offset > 0) - buf << "|$" << Base::HEX2 << offset; - } + if(a != i) + buf << "+$" << Base::HEX1 << (a - i); + found = true; + break; + } + if(!found) + buf << ourZPMnemonic[a - 0x80]; + if(offset > 0) + buf << "|$" << Base::HEX2 << offset; return true; } @@ -684,11 +688,28 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) con case AddrType::ROM: { // These addresses can never be in the system labels list - const auto& iter = myUserLabels.find(addr); - if(iter != myUserLabels.end()) + if(isRam) // cartridge RAM { - buf << iter->second; - return true; + AddrToLabel::const_iterator iter; + + // Search for nearest label + for(uInt16 i = addr; i >= (addr & 0xf000); --i) + if((iter = myUserLabels.find(i)) != myUserLabels.end()) + { + buf << iter->second; + if(addr != i) + buf << "+$" << Base::HEX1 << (addr - i); + return true; + } + } + else + { + const auto& iter = myUserLabels.find(addr); + if(iter != myUserLabels.end()) + { + buf << iter->second; + return true; + } } break; } @@ -713,10 +734,10 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) con } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartDebug::getLabel(uInt16 addr, bool isRead, int places) const +string CartDebug::getLabel(uInt16 addr, bool isRead, int places, bool isRam) const { ostringstream buf; - getLabel(buf, addr, isRead, places); + getLabel(buf, addr, isRead, places, isRam); return buf.str(); } diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index 9d71de51b..25dd59e63 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -211,8 +211,10 @@ class CartDebug : public DebuggerSystem If places is not -1 and a label hasn't been defined, return a formatted hexidecimal address */ - bool getLabel(ostream& buf, uInt16 addr, bool isRead, int places = -1) const; - string getLabel(uInt16 addr, bool isRead, int places = -1) const; + bool getLabel(ostream& buf, uInt16 addr, bool isRead, + int places = -1, bool isRam = false) const; + string getLabel(uInt16 addr, bool isRead, + int places = -1, bool isRam = false) const; int getAddress(const string& label) const; /** From 038557ba69ee3720800a5ae3821c64d1c60e2724 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sat, 28 Nov 2020 12:59:07 +0100 Subject: [PATCH 257/263] Fix bad use of constexpr. --- src/gui/ToolTip.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx index a887e0096..12ede067a 100644 --- a/src/gui/ToolTip.cxx +++ b/src/gui/ToolTip.cxx @@ -123,12 +123,13 @@ void ToolTip::release(bool emptyTip) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToolTip::show(const string& tip) { + uInt32 maxRows = MAX_ROWS; myTipPos = myMousePos; uInt32 maxWidth = std::min(myWidth - myTextXOfs * 2, uInt32(myFont->getStringWidth(tip))); mySurface->fillRect(1, 1, maxWidth + myTextXOfs * 2 - 2, myHeight - 2, kWidColor); - int lines = std::min(MAX_ROWS, + int lines = std::min(maxRows, uInt32(mySurface->drawString(*myFont, tip, myTextXOfs, myTextYOfs, maxWidth, myHeight - myTextYOfs * 2, kTextColor))); From 5711d5cec39a902f98836613894d0e5f9019043d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 28 Nov 2020 12:59:45 +0100 Subject: [PATCH 258/263] improved debugger's RAM labels (part 2) --- src/debugger/gui/CartEnhancedWidget.cxx | 2 +- src/debugger/gui/DataGridRamWidget.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index 97beb1f6b..80da02ffd 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -392,5 +392,5 @@ uInt8 CartridgeEnhancedWidget::internalRamGetValue(int addr) string CartridgeEnhancedWidget::internalRamLabel(int addr) { CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + ADDR_BASE + myCart.myReadOffset, false); + return dbg.getLabel(addr + ADDR_BASE + myCart.myReadOffset, false, -1, true); } diff --git a/src/debugger/gui/DataGridRamWidget.cxx b/src/debugger/gui/DataGridRamWidget.cxx index 9be4c4f14..7445f1d90 100644 --- a/src/debugger/gui/DataGridRamWidget.cxx +++ b/src/debugger/gui/DataGridRamWidget.cxx @@ -48,7 +48,7 @@ string DataGridRamWidget::getToolTip(const Common::Point& pos) const ostringstream buf; - buf << _ram.getLabel(addr) << '\n' << tip; + buf << label << '\n' << tip; return buf.str(); } From f0c599bfe4e13b65aa5ae0c5a17615c944031555 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sat, 28 Nov 2020 13:32:29 +0100 Subject: [PATCH 259/263] Fix null pointer. --- src/gui/LauncherDialog.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index ca4101601..4a8f437d4 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -384,7 +384,7 @@ void LauncherDialog::loadConfig() } bool subDirs = instance().settings().getBool("launchersubdirs"); - mySubDirs->setState(subDirs); + if (mySubDirs) mySubDirs->setState(subDirs); myList->setIncludeSubDirs(subDirs); // Assume that if the list is empty, this is the first time that loadConfig() From 41bb891cc0eb0eb04095b42a833dbe6253852453 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Sat, 28 Nov 2020 13:32:57 +0100 Subject: [PATCH 260/263] Avoid endless loop and heap corruption of doom. --- src/gui/FileListWidget.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index d2cff5261..613b05811 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -51,7 +51,7 @@ void FileListWidget::setDirectory(const FilesystemNode& node, // Initialize history FilesystemNode tmp = _node; - while(tmp.hasParent()) + while(tmp.hasParent() && !_history.full()) { string name = tmp.getName(); if(name.back() == '/' || name.back() == '\\') From b7943546796db5269006838f7734051c52e69048 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 28 Nov 2020 10:48:00 -0330 Subject: [PATCH 261/263] Move Linux builds to use C++17 by default. --- Changes.txt | 2 ++ Makefile | 4 ++-- configure | 2 +- docs/index.html | 4 ++-- src/libretro/Makefile | 6 +++--- src/libretro/jni/Android.mk | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Changes.txt b/Changes.txt index c2767093b..6140d6f59 100644 --- a/Changes.txt +++ b/Changes.txt @@ -30,6 +30,8 @@ * Fixed autofire bug for trackball controllers. + * Codebase now uses C++17 features. + -Have fun! diff --git a/Makefile b/Makefile index 87a2c9847..d9dc607c9 100644 --- a/Makefile +++ b/Makefile @@ -48,11 +48,11 @@ endif CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter ifdef HAVE_GCC - CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 + CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17 endif ifdef HAVE_CLANG - CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14 + CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17 endif ifdef CLANG_WARNINGS diff --git a/configure b/configure index 31281ec4c..ad2ebbed7 100755 --- a/configure +++ b/configure @@ -385,7 +385,7 @@ else fi for compiler in $compilers; do - if test_compiler "$compiler -std=c++14"; then + if test_compiler "$compiler -std=c++17"; then CXX=$compiler echo $CXX break diff --git a/docs/index.html b/docs/index.html index 0c6598b56..369598e23 100644 --- a/docs/index.html +++ b/docs/index.html @@ -260,7 +260,7 @@
      -
    • High speed emulation using optimized C++14 code
    • +
    • High speed emulation using optimized C++17 code
    • Supports high quality TIA emulation using the cycle-exact TIA core from 6502.ts by Christian Speckner
    • @@ -350,7 +350,7 @@
    • OpenGL capable video card
    • Other architectures (MIPS, PPC, PPC64, etc.) have been confirmed to work, but aren't as well tested as i386/x86_64
    • -
    • GNU g++ v/6 or Clang v/3.9 (with C++14 support) and the make utility are required for compiling the Stella source code
    • +
    • GNU g++ v/7 or Clang v/5 (with C++17 support) and the make utility are required for compiling the Stella source code

    diff --git a/src/libretro/Makefile b/src/libretro/Makefile index 8d17db9db..6f8eb6599 100644 --- a/src/libretro/Makefile +++ b/src/libretro/Makefile @@ -43,7 +43,7 @@ TARGET_NAME = stella ifeq (,$(findstring msvc,$(platform))) - CXXFLAGS += -std=c++14 -fno-rtti + CXXFLAGS += -std=c++17 -fno-rtti LIBS := -lm else LIBS := @@ -282,8 +282,8 @@ else ifneq (,$(filter $(platform), ngc wii wiiu)) else ifeq ($(platform), emscripten) TARGET := $(TARGET_NAME)_libretro_$(platform).bc STATIC_LINKING = 1 - CXXFLAGS += $(PTHREAD_FLAGS) -std=c++14 - LDFLAGS += $(PTHREAD_FLAGS) -std=c++14 + CXXFLAGS += $(PTHREAD_FLAGS) -std=c++17 + LDFLAGS += $(PTHREAD_FLAGS) -std=c++17 # Genode else ifeq ($(platform), genode) diff --git a/src/libretro/jni/Android.mk b/src/libretro/jni/Android.mk index 3115baa53..644f983ae 100644 --- a/src/libretro/jni/Android.mk +++ b/src/libretro/jni/Android.mk @@ -14,6 +14,6 @@ endif include $(CLEAR_VARS) LOCAL_MODULE := retro LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C) -LOCAL_CXXFLAGS := $(COREFLAGS) -std=c++14 +LOCAL_CXXFLAGS := $(COREFLAGS) -std=c++17 LOCAL_LDFLAGS := -Wl,-version-script=$(CORE_DIR)/libretro/link.T include $(BUILD_SHARED_LIBRARY) From b3576478193e79120497f13086e851c7275bae44 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 28 Nov 2020 16:12:54 +0100 Subject: [PATCH 262/263] minimized redraws in debugger --- src/debugger/gui/DataGridWidget.cxx | 51 ++++++++++++++++++-------- src/debugger/gui/DataGridWidget.hxx | 2 +- src/debugger/gui/DebuggerDialog.cxx | 12 ------ src/debugger/gui/RomListWidget.cxx | 3 +- src/debugger/gui/TiaInfoWidget.cxx | 6 ++- src/debugger/gui/ToggleBitWidget.cxx | 6 ++- src/debugger/gui/TogglePixelWidget.cxx | 19 ++++++++-- src/debugger/gui/TogglePixelWidget.hxx | 2 +- src/gui/ColorWidget.cxx | 17 ++++++++- src/gui/ColorWidget.hxx | 2 +- src/gui/EditTextWidget.cxx | 6 ++- src/gui/EditableWidget.cxx | 8 ++-- src/gui/PopUpWidget.cxx | 11 +++++- src/gui/ScrollBarWidget.cxx | 6 ++- src/gui/TabWidget.cxx | 5 ++- src/gui/Widget.cxx | 20 +++++----- 16 files changed, 117 insertions(+), 59 deletions(-) diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx index 20489912c..9fa82bcdc 100644 --- a/src/debugger/gui/DataGridWidget.cxx +++ b/src/debugger/gui/DataGridWidget.cxx @@ -107,15 +107,21 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font, void DataGridWidget::setList(const IntArray& alist, const IntArray& vlist, const BoolArray& changed) { -/* -cerr << "alist.size() = " << alist.size() - << ", vlist.size() = " << vlist.size() - << ", changed.size() = " << changed.size() - << ", _rows*_cols = " << _rows * _cols << endl << endl; -*/ + /* + cerr << "alist.size() = " << alist.size() + << ", vlist.size() = " << vlist.size() + << ", changed.size() = " << changed.size() + << ", _rows*_cols = " << _rows * _cols << endl << endl; + */ int size = int(vlist.size()); // assume the alist is the same size assert(size == _rows * _cols); + bool dirty = _editMode + || !std::equal(_valueList.begin(), _valueList.end(), + vlist.begin(), vlist.end()) + || !std::equal(_changedList.begin(), _changedList.end(), + changed.begin(), changed.end()); + _addrList.clear(); _valueList.clear(); _valueStringList.clear(); @@ -130,19 +136,22 @@ cerr << "alist.size() = " << alist.size() for(int i = 0; i < size; ++i) _valueStringList.push_back(Common::Base::toString(_valueList[i], _base)); -/* -cerr << "_addrList.size() = " << _addrList.size() - << ", _valueList.size() = " << _valueList.size() - << ", _changedList.size() = " << _changedList.size() - << ", _valueStringList.size() = " << _valueStringList.size() - << ", _rows*_cols = " << _rows * _cols << endl << endl; -*/ + /* + cerr << "_addrList.size() = " << _addrList.size() + << ", _valueList.size() = " << _valueList.size() + << ", _changedList.size() = " << _changedList.size() + << ", _valueStringList.size() = " << _valueStringList.size() + << ", _rows*_cols = " << _rows * _cols << endl << endl; + */ enableEditMode(false); - // Send item selected signal for starting with cell 0 - sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id); + if(dirty) + { + // Send item selected signal for starting with cell 0 + sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id); - setDirty(); + setDirty(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -708,6 +717,16 @@ int DataGridWidget::getWidth() const return _w + (_scrollBar ? ScrollBarWidget::scrollBarWidth(_font) : 0); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void DataGridWidget::setCrossed(bool enable) +{ + if(_crossGrid != enable) + { + _crossGrid = enable; + setDirty(); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DataGridWidget::startEditMode() { diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx index 848993311..ed1b6be02 100644 --- a/src/debugger/gui/DataGridWidget.hxx +++ b/src/debugger/gui/DataGridWidget.hxx @@ -82,7 +82,7 @@ class DataGridWidget : public EditableWidget void setOpsWidget(DataGridOpsWidget* w) { _opsWidget = w; } - void setCrossed(bool enable) { _crossGrid = enable; } + void setCrossed(bool enable); string getToolTip(const Common::Point& pos) const override; bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override; diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index b8a28f579..f2ac5c230 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -272,84 +272,72 @@ void DebuggerDialog::handleCommand(CommandSender* sender, int cmd, void DebuggerDialog::doStep() { instance().debugger().parser().run("step"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doTrace() { instance().debugger().parser().run("trace"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doAdvance() { instance().debugger().parser().run("frame #1"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doScanlineAdvance() { instance().debugger().parser().run("scanline #1"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doRewind() { instance().debugger().parser().run("rewind"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doUnwind() { instance().debugger().parser().run("unwind"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doRewind10() { instance().debugger().parser().run("rewind #10"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doUnwind10() { instance().debugger().parser().run("unwind #10"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doRewindAll() { instance().debugger().parser().run("rewind #1000"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doUnwindAll() { instance().debugger().parser().run("unwind #1000"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doExitDebugger() { instance().debugger().parser().run("run"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::doExitRom() { instance().debugger().parser().run("exitrom"); - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx index c226398a6..9f8b9d589 100644 --- a/src/debugger/gui/RomListWidget.cxx +++ b/src/debugger/gui/RomListWidget.cxx @@ -553,7 +553,8 @@ void RomListWidget::drawWidget(bool hilite) checkBreakPoint(dlist[pos].address, instance().debugger().cartDebug().getBank(dlist[pos].address))); myCheckList[i]->setDirty(); - // draw immediately, because chain order is not deterministic + // All checkboxes have to be redrawn because RomListWidget clears its whole area + // Also draw immediately, because chain order is not deterministic myCheckList[i]->draw(); // Draw highlighted item in a frame diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index 2690f8b4f..fe2ce6d9b 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -81,7 +81,6 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total"); myTotalCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight); - myTotalCycles->setToolTip("Total CPU cycles executed for this session (E notation)."); myTotalCycles->setEditable(false, true); // Left: Delta Cycles @@ -170,7 +169,10 @@ void TiaInfoWidget::loadConfig() uInt64 total = tia.cyclesLo() + (uInt64(tia.cyclesHi()) << 32); uInt64 totalOld = oldTia.info[2] + (uInt64(oldTia.info[3]) << 32); myTotalCycles->setText(Common::Base::toString(uInt32(total) / 1000000, Common::Base::Fmt::_10_6) + "e6", - total != totalOld); + total / 1000000 != totalOld / 1000000); + myTotalCycles->setToolTip("Total CPU cycles (E notation) executed for this session (" + + std::to_string(total) + ")."); + uInt64 delta = total - totalOld; myDeltaCycles->setText(Common::Base::toString(uInt32(delta), Common::Base::Fmt::_10_8)); // no coloring diff --git a/src/debugger/gui/ToggleBitWidget.cxx b/src/debugger/gui/ToggleBitWidget.cxx index 994d73aa9..629e58c57 100644 --- a/src/debugger/gui/ToggleBitWidget.cxx +++ b/src/debugger/gui/ToggleBitWidget.cxx @@ -70,12 +70,14 @@ void ToggleBitWidget::setList(const StringList& off, const StringList& on) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ToggleBitWidget::setState(const BoolArray& state, const BoolArray& changed) { + if(!std::equal(_changedList.begin(), _changedList.end(), + changed.begin(), changed.end())) + setDirty(); + _stateList.clear(); _stateList = state; _changedList.clear(); _changedList = changed; - - setDirty(); } diff --git a/src/debugger/gui/TogglePixelWidget.cxx b/src/debugger/gui/TogglePixelWidget.cxx index 1cdb80bae..c26600130 100644 --- a/src/debugger/gui/TogglePixelWidget.cxx +++ b/src/debugger/gui/TogglePixelWidget.cxx @@ -51,15 +51,18 @@ void TogglePixelWidget::setState(const BoolArray& state) for(int col = 0; col < _cols; col++) { int pos = row * _cols + col; + bool changed = _stateList[pos] != state[pos]; - _changedList[pos] = _stateList[pos] != state[pos]; + if(_changedList[pos] != changed) + { + _changedList[pos] = changed; + setDirty(); + } } } _stateList.clear(); _stateList = state; - - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -113,6 +116,16 @@ int TogglePixelWidget::getIntState() return value; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TogglePixelWidget::setCrossed(bool enable) +{ + if(_crossBits != enable) + { + _crossBits = enable; + setDirty(); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TogglePixelWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/TogglePixelWidget.hxx b/src/debugger/gui/TogglePixelWidget.hxx index fe63cd964..503404c6f 100644 --- a/src/debugger/gui/TogglePixelWidget.hxx +++ b/src/debugger/gui/TogglePixelWidget.hxx @@ -39,7 +39,7 @@ class TogglePixelWidget : public ToggleWidget void setIntState(int value, bool swap = false); int getIntState(); - void setCrossed(bool enable) { _crossBits = enable; } + void setCrossed(bool enable); private: ColorId _pixelColor{kNone}, _backgroundColor{kDlgColor}; diff --git a/src/gui/ColorWidget.cxx b/src/gui/ColorWidget.cxx index 5f31df35d..94ef4bbf4 100644 --- a/src/gui/ColorWidget.cxx +++ b/src/gui/ColorWidget.cxx @@ -37,8 +37,21 @@ ColorWidget::ColorWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ColorWidget::setColor(ColorId color) { - _color = color; - setDirty(); + if(_color != color) + { + _color = color; + setDirty(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ColorWidget::setCrossed(bool enable) +{ + if(_crossGrid != enable) + { + _crossGrid = enable; + setDirty(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ColorWidget.hxx b/src/gui/ColorWidget.hxx index 4d39871fa..0ec099a95 100644 --- a/src/gui/ColorWidget.hxx +++ b/src/gui/ColorWidget.hxx @@ -42,7 +42,7 @@ class ColorWidget : public Widget, public CommandSender void setColor(ColorId color); ColorId getColor() const { return _color; } - void setCrossed(bool enable) { _crossGrid = enable; } + void setCrossed(bool enable); protected: void drawWidget(bool hilite) override; diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx index 6a0f32877..dde104002 100644 --- a/src/gui/EditTextWidget.cxx +++ b/src/gui/EditTextWidget.cxx @@ -46,7 +46,11 @@ void EditTextWidget::setText(const string& str, bool changed) { EditableWidget::setText(str, changed); _backupString = str; - _changed = changed; + if(_changed != changed) + { + _changed = changed; + setDirty(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx index e015dd899..eaadbaeeb 100644 --- a/src/gui/EditableWidget.cxx +++ b/src/gui/EditableWidget.cxx @@ -43,14 +43,18 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EditableWidget::setText(const string& str, bool) +void EditableWidget::setText(const string& str, bool changed) { + const string oldEditString = _editString; // Filter input string _editString = ""; for(char c: str) if(_filter(tolower(c))) _editString.push_back(c); + if(oldEditString != _editString) + setDirty(); + myUndoHandler->reset(); myUndoHandler->doo(_editString); @@ -60,8 +64,6 @@ void EditableWidget::setText(const string& str, bool) _editScrollOffset = (_font.getStringWidth(_editString) - (getEditRect().w())); if (_editScrollOffset < 0) _editScrollOffset = 0; - - setDirty(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index eb35ed9c3..b4dd27b84 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -78,7 +78,11 @@ void PopUpWidget::setSelected(const Variant& tag, const Variant& def) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PopUpWidget::setSelectedIndex(int idx, bool changed) { - _changed = changed; + if(_changed != changed) + { + _changed = changed; + setDirty(); + } myMenu->setSelectedIndex(idx); setText(myMenu->getSelectedName()); } @@ -86,6 +90,11 @@ void PopUpWidget::setSelectedIndex(int idx, bool changed) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PopUpWidget::setSelectedMax(bool changed) { + if(_changed != changed) + { + _changed = changed; + setDirty(); + } _changed = changed; myMenu->setSelectedMax(); setText(myMenu->getSelectedName()); diff --git a/src/gui/ScrollBarWidget.cxx b/src/gui/ScrollBarWidget.cxx index 4bacbeece..c9d68cb82 100644 --- a/src/gui/ScrollBarWidget.cxx +++ b/src/gui/ScrollBarWidget.cxx @@ -251,6 +251,9 @@ void ScrollBarWidget::handleMouseLeft() void ScrollBarWidget::recalc() { //cerr << "ScrollBarWidget::recalc()\n"; + int oldSliderHeight = _sliderHeight, + oldSliderPos = _sliderPos; + if(_numEntries > _entriesPerPage) { _sliderHeight = (_h - 2 * _upDownBoxHeight) * _entriesPerPage / _numEntries; @@ -268,7 +271,8 @@ void ScrollBarWidget::recalc() _sliderPos = _upDownBoxHeight; } - setDirty(); + if(oldSliderHeight != _sliderHeight || oldSliderPos != _sliderPos) + setDirty(); // only set dirty when something changed } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx index 3c7d48258..89967d041 100644 --- a/src/gui/TabWidget.cxx +++ b/src/gui/TabWidget.cxx @@ -110,6 +110,9 @@ void TabWidget::setActiveTab(int tabID, bool show) _tabs[_activeTab].firstWidget = _firstWidget; } + if(_activeTab != tabID) + setDirty(); + _activeTab = tabID; _firstWidget = _tabs[tabID].firstWidget; @@ -138,8 +141,6 @@ void TabWidget::updateActiveTab() if(_tabs[_activeTab].parentWidget) _tabs[_activeTab].parentWidget->loadConfig(); - setDirty(); - // Redraw focused areas _boss->redrawFocus(); // TJ: Does nothing! } diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx index 61b9296cb..38c46bdbe 100644 --- a/src/gui/Widget.cxx +++ b/src/gui/Widget.cxx @@ -425,20 +425,19 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StaticTextWidget::setValue(int value) { - _label = std::to_string(value); - - setDirty(); + setLabel(std::to_string(value)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StaticTextWidget::setLabel(const string& label) { - _label = label; - - setDirty(); + if(_label != label) + { + _label = label; + setDirty(); + } } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void StaticTextWidget::handleMouseEntered() { @@ -710,12 +709,13 @@ void CheckboxWidget::setFill(FillType type) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CheckboxWidget::setState(bool state, bool changed) { - if(_state != state) + if(_state != state || _changed != changed) { - _state = state; setDirty(); + + _state = state; + _changed = changed; } - _changed = changed; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 5a650122c76a1ce6bfbeaabb6f18926b4790ddfa Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 28 Nov 2020 16:54:23 +0100 Subject: [PATCH 263/263] made DelayQueueWidget use setDirty removed superfluous code from TiaWidget --- src/debugger/gui/DelayQueueWidget.cxx | 12 ++++++++++-- src/debugger/gui/TiaWidget.cxx | 4 ---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/debugger/gui/DelayQueueWidget.cxx b/src/debugger/gui/DelayQueueWidget.cxx index cca5644c6..d0ad50351 100644 --- a/src/debugger/gui/DelayQueueWidget.cxx +++ b/src/debugger/gui/DelayQueueWidget.cxx @@ -50,7 +50,11 @@ void DelayQueueWidget::loadConfig() { using Common::Base; for (auto&& line : myLines) { if (!delayQueueIterator->isValid()) { - line = ""; + if(line != "") + { + setDirty(); + line = ""; + } continue; } @@ -81,7 +85,11 @@ void DelayQueueWidget::loadConfig() { break; } - line = ss.str(); + if(line != ss.str()) + { + setDirty(); + line = ss.str(); + } delayQueueIterator->next(); } } diff --git a/src/debugger/gui/TiaWidget.cxx b/src/debugger/gui/TiaWidget.cxx index c330bf386..f6bc43e6e 100644 --- a/src/debugger/gui/TiaWidget.cxx +++ b/src/debugger/gui/TiaWidget.cxx @@ -919,14 +919,10 @@ void TiaWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) case kRefP0ID: tia.refP0(myRefP0->getState() ? 1 : 0); - myGRP0->setIntState(myGRP0->getIntState(), !myRefP0->getState()); - myGRP0Old->setIntState(myGRP0Old->getIntState(), !myRefP0->getState()); break; case kRefP1ID: tia.refP1(myRefP1->getState() ? 1 : 0); - myGRP1->setIntState(myGRP1->getIntState(), !myRefP1->getState()); - myGRP1Old->setIntState(myGRP1Old->getIntState(), !myRefP1->getState()); break; case kDelP0ID:

    Features