From: Shamus Hammons Date: Fri, 3 Oct 2014 14:48:02 +0000 (-0500) Subject: Fixed controller profile system. X-Git-Tag: 2.1.1~10 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=virtualjaguar;a=commitdiff_plain;h=62587015fb12ec54b1702bfa17077e4b8af44b19 Fixed controller profile system. What this means is that you have to set up profiles for controllers you plug in now. Virtual Jaguar will try to do the right thing, but it's still possible to make it screw up and do the wrong thing. Hopefully this will be fixed in a future update. :-P --- diff --git a/cross-compile b/cross-compile index 896ef11..4a8c443 100755 --- a/cross-compile +++ b/cross-compile @@ -5,10 +5,14 @@ # by James Hammons # (C) 2012 Underground Software # -echo "Cross compiling for Win32..." +#PREFIX=i686-pc-mingw32.static +#echo "Cross compiling for Win32..." +echo "Cross compiling for Win64..." export PATH=/opt/mxe/usr/bin:$PATH rm makefile-qt -make CROSS=i686-pc-mingw32- +#make CROSS=i686-pc-mingw32.static- +make CROSS=x86_64-w64-mingw32.static- #rel=`svn info | grep Revision | cut -f 2 -d ' '` rel=`git log -1 --pretty=format:%ci | cut -d ' ' -f 1 | tr -d -` cd release && upx -9v virtualjaguar.exe && zip -9v vj-$rel.zip virtualjaguar.exe + diff --git a/src/dsp.cpp b/src/dsp.cpp index b3ca25e..e255cde 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -457,12 +457,14 @@ void dsp_reset_stats(void) dsp_opcode_use[i] = 0; } + void DSPReleaseTimeslice(void) { //This does absolutely nothing!!! !!! FIX !!! dsp_releaseTimeSlice_flag = 1; } + void dsp_build_branch_condition_table(void) { // Fill in the mirror table @@ -502,6 +504,7 @@ void dsp_build_branch_condition_table(void) } } + uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -522,22 +525,20 @@ uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) { uint32_t data = DSPReadLong(offset & 0xFFFFFFFC, who); - if ((offset&0x03)==0) - return(data>>24); - else - if ((offset&0x03)==1) - return((data>>16)&0xff); - else - if ((offset&0x03)==2) - return((data>>8)&0xff); - else - if ((offset&0x03)==3) - return(data&0xff); + if ((offset & 0x03) == 0) + return (data >> 24); + else if ((offset & 0x03) == 1) + return ((data >> 16) & 0xFF); + else if ((offset & 0x03) == 2) + return ((data >> 8) & 0xFF); + else if ((offset & 0x03) == 3) + return (data & 0xFF); } return JaguarReadByte(offset, who); } + uint16_t DSPReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -565,6 +566,7 @@ uint16_t DSPReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) return JaguarReadWord(offset, who); } + uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -609,12 +611,13 @@ uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) return JaguarReadLong(offset, who); } + void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) WriteLog("DSP: WriteByte--Attempt to write to DSP register file by %s!\n", whoName[who]); - if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) + if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE + 0x2000)) { offset -= DSP_WORK_RAM_BASE; dsp_ram_8[offset] = data; @@ -626,7 +629,7 @@ void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) }*/ return; } - if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20)) { uint32_t reg = offset & 0x1C; int bytenum = offset & 0x03; @@ -645,9 +648,11 @@ void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) } // WriteLog("dsp: writing %.2x at 0x%.8x\n",data,offset); //Should this *ever* happen??? Shouldn't we be saying "unknown" here??? +// Well, yes, it can. There are 3 MMU users after all: 68K, GPU & DSP...! JaguarWriteByte(offset, data, who); } + void DSPWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -709,6 +714,7 @@ SET16(ram2, offset, data); JaguarWriteWord(offset, data, who); } + //bool badWrite = false; void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) { @@ -889,6 +895,7 @@ WriteLog("DSP: Modulo data %08X written by %s.\n", data, whoName[who]); JaguarWriteLong(offset, data, who); } + // // Update the DSP register file pointers depending on REGPAGE bit // @@ -909,6 +916,7 @@ void DSPUpdateRegisterBanks(void) #endif } + // // Check for and handle any asserted DSP IRQs // @@ -1054,6 +1062,7 @@ ctrl2[0] = regs2[30] = dsp_pc; FlushDSPPipeline(); } + // // Non-pipelined version... // @@ -1159,6 +1168,7 @@ ctrl1[0] = regs1[30] = dsp_pc; //!!!!!!!! } + // // Set the specified DSP IRQ line to a given state // @@ -1193,11 +1203,13 @@ DSPHandleIRQsNP(); // GPUSetIRQLine(GPUIRQ_DSP, ASSERT_LINE); } + bool DSPIsRunning(void) { return (DSP_RUNNING ? true : false); } + void DSPInit(void) { // memory_malloc_secure((void **)&dsp_ram_8, 0x2000, "DSP work RAM"); @@ -1208,6 +1220,7 @@ void DSPInit(void) DSPReset(); } + void DSPReset(void) { dsp_pc = 0x00F1B000; @@ -1238,6 +1251,7 @@ void DSPReset(void) *((uint32_t *)(&dsp_ram_8[i])) = rand(); } + void DSPDumpDisassembly(void) { char buffer[512]; @@ -1253,6 +1267,7 @@ void DSPDumpDisassembly(void) } } + void DSPDumpRegisters(void) { //Shoud add modulus, etc to dump here... @@ -1280,6 +1295,7 @@ void DSPDumpRegisters(void) } } + void DSPDone(void) { int i, j; diff --git a/src/file.cpp b/src/file.cpp index 00ef5f3..4586245 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -8,9 +8,10 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 01/16/2010 Created this log ;-) -// JLH 02/28/2010 Added functions to look inside .ZIP files and handle contents +// JLH 02/28/2010 Added functions to look inside .ZIP files and handle +// contents // JLH 06/01/2012 Added function to check ZIP file CRCs against file DB // @@ -107,8 +108,9 @@ uint32_t JaguarLoadROM(uint8_t * &rom, char * path) // // Jaguar file loading -// We do a more intelligent file analysis here instead of relying on (possible false) -// file extensions which people don't seem to give two shits about anyway. :-( +// We do a more intelligent file analysis here instead of relying on (possible +// false) file extensions which people don't seem to give two shits about +// anyway. :-( // bool JaguarLoadFile(char * path) { @@ -287,7 +289,8 @@ bool AlpineLoadFile(char * path) delete[] buffer; // Maybe instead of this, we could try requiring the STUBULATOR ROM? Just a thought... - // Try setting the vector to say, $1000 and putting an instruction there that loops forever: + // Try setting the vector to say, $1000 and putting an instruction there + // that loops forever: // This kludge works! Yeah! SET32(jaguarMainRAM, 0x10, 0x00001000); // Set Exception #4 (Illegal Instruction) SET16(jaguarMainRAM, 0x1000, 0x60FE); // Here: bra Here diff --git a/src/filedb.cpp b/src/filedb.cpp index ee12846..dd64da5 100644 --- a/src/filedb.cpp +++ b/src/filedb.cpp @@ -7,7 +7,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 02/15/2010 Created this file // diff --git a/src/gui/configdialog.cpp b/src/gui/configdialog.cpp index f8c8d4f..3f870fc 100644 --- a/src/gui/configdialog.cpp +++ b/src/gui/configdialog.cpp @@ -7,7 +7,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 01/29/2010 Created this file // JLH 06/23/2011 Added initial implementation // JLH 10/14/2011 Fixed possibly missing final slash in paths @@ -87,6 +87,7 @@ void ConfigDialog::LoadDialogFromSettings(void) } #warning "!!! Need to load settings from controller profile !!!" +// We do this now, but not here. Need to fix this... #if 0 for(int i=0; i<21; i++) { @@ -122,12 +123,15 @@ void ConfigDialog::UpdateVJSettings(void) } #warning "!!! Need to save settings to controller profile !!!" +// We do this now, but not here. Need to fix this... +#if 0 for(int i=0; i<21; i++) { // We need to find the right profile and load it up here... vjs.p1KeyBindings[i] = controllerTab1->controllerWidget->keys[i]; // vjs.p2KeyBindings[i] = controllerTab2->controllerWidget->keys[i]; } +#endif } diff --git a/src/gui/controllertab.cpp b/src/gui/controllertab.cpp index 9808003..7ff002f 100644 --- a/src/gui/controllertab.cpp +++ b/src/gui/controllertab.cpp @@ -11,8 +11,31 @@ // --- ---------- ------------------------------------------------------------ // JLH 06/23/2011 Created this file // JLH 07/20/2011 Fixed a bunch of stuff +// JLH 10/02/2014 Fixed even more stuff, related to the profile system // +/* +To really fix this shit, we have to straighten out some stuff. So here goes: + +We have a database of profiles consisting of a device list (devices that have +been seen already) and map list (consisting of a key into the device list, a +human readable name, a preferred slot #, and a key/button mapping). This is a +list that can hold up to 64 different profiles. + +We have a a list of attached gamepads in Gamepad::. There can be 8 at most +attached any one time. + +There are two game port slots that a controller can be hooked into. + +So, what we need to do when configuring and/or using this system is this. + + - Populate the device combobox with the list of attached devices from the + profile database. + - Populate the map to combobox with the profiles associated with that profile + device number. + - Save stuff when the user changes stuff (this happens already) +*/ + #include "controllertab.h" #include "controllerwidget.h" @@ -84,42 +107,6 @@ ControllerTab::ControllerTab(QWidget * parent/*= 0*/): QWidget(parent), mapToList->addItem(tr("Controller #2"), CONTROLLER2); mapToList->addItem(tr("Either one that's free"), CONTROLLER1 | CONTROLLER2); } -/* -So now we come to implementation. When changing devices, could have a helper function -in profile.cpp that fills the mapNameList combobox with the appropriate names/profile -numbers. - -There needs to be some way of getting data from the ControllerWidget and the current -profile. - -Gamepad will have to have some way of knowing which profile is mapped to which -Jaguar controllers and filtering out everything else. - -Will have to have some intelligent handling of profiles when first run, to see first -what is connected and second, to assign profiles to Jaguar controllers. In this -case, keyboard is the lowest priority--if a controller is plugged in and assigned to -the same Jaguar controller as a keyboard, the controller is used. Not sure what to -do in the case of multiple controllers plugged in and assigned to the same Jaguar -controller. - -Also, need a way to load/save profiles. - -Meaning of checkboxes: None checked == profile not used. -1 checked == prefer connection to Jaguar controller X. -2 checked == no preference, use any available. - -Single mapping cannot be deleted ("-" will be disabled). Can always add, up to the max -limit of profiles (MAX_PROFILES). - ------------------------------- - -Now the main window passes in/removes the last edited profile #. From here, when starting -up, we need to pull that number from the profile store and populate all our boxes. - -------------------------------- - -Need to do AutoConnectProfiles from here, and detect any conflicts -*/ ControllerTab::~ControllerTab() @@ -135,9 +122,6 @@ void ControllerTab::SetupLastUsedProfile(void) if (deviceNumIndex == -1 || mapNumIndex == -1) { // We're doing the default, so set it up... -// mapToList->setCurrentIndex(mapToList->findData(profile[0].preferredController)); -//printf("ControllerTab::SetupLastUsedProfile: [FAILED] profileNum=%i, controllerIndex=%i, preferredController=%i\n", profileNum, controllerIndex, profile[0].preferredController); -// return; deviceNumIndex = 0; mapNumIndex = 0; profileNum = 0; @@ -145,11 +129,9 @@ void ControllerTab::SetupLastUsedProfile(void) deviceList->setCurrentIndex(deviceNumIndex); mapNameList->setCurrentIndex(mapNumIndex); -//no more: #warning "!!! bug in here where it doesn't save your preferred controller !!!" - int controllerIndex = mapToList->findData(profile[profileNum].preferredController); + int controllerIndex = mapToList->findData(profile[profileNum].preferredSlot); mapToList->setCurrentIndex(controllerIndex); -//printf("ControllerTab::SetupLastUsedProfile: profileNum=%i, controllerIndex=%i, preferredController=%i\n", profileNum, controllerIndex, profile[profileNum].preferredController); // We have to do this manually, since it's no longer done automagically... ChangeDevice(deviceNumIndex); @@ -190,36 +172,32 @@ void ControllerTab::UpdateProfileKeys(int mapPosition, uint32_t key) void ControllerTab::UpdateProfileConnections(int selection) { -// profile[profileNum].preferredController = (controller1->isChecked() ? CONTROLLER1 : 0) | (controller2->isChecked() ? CONTROLLER2 : 0); - profile[profileNum].preferredController = mapToList->itemData(selection).toInt(); -//printf("Setting profile #%i 'Maps To' to %i...\n", profileNum, mapToList->itemData(selection).toInt()); + profile[profileNum].preferredSlot = mapToList->itemData(selection).toInt(); } void ControllerTab::ChangeDevice(int selection) { -//printf("ControllerTab::ChangeDevice\n"); int deviceNum = deviceList->itemData(selection).toInt(); mapNameList->clear(); int numberOfMappings = FindMappingsForDevice(deviceNum, mapNameList); + // Make sure to disable the "-" button is there's only one mapping for this + // device... deleteMapName->setDisabled(numberOfMappings == 1 ? true : false); -//printf("Found %i mappings for device #%u...\n", numberOfMappings, deviceNum); + // Set up new profile #... + ChangeMapName(0); } void ControllerTab::ChangeMapName(int selection) { -//printf("ControllerTab::ChangeMapName\n"); profileNum = mapNameList->itemData(selection).toInt(); -//printf("You selected mapping: %s (profile #%u)\n", (mapNameList->itemText(selection)).toAscii().data(), profileNum); for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++) controllerWidget->keys[i] = profile[profileNum].map[i]; controllerWidget->update(); -// controller1->setChecked(profile[profileNum].preferredController & CONTROLLER1); -// controller2->setChecked(profile[profileNum].preferredController & CONTROLLER2); - mapToList->setCurrentIndex(mapToList->findData(profile[profileNum].preferredController)); + mapToList->setCurrentIndex(mapToList->findData(profile[profileNum].preferredSlot)); } @@ -230,16 +208,7 @@ void ControllerTab::AddMapName(void) if (freeProfile == -1) { // Oh crap, we're out of room! Alert the media! - // (Really, tho, we should pop this up *before* asking for user input. - // Which we now do!) -#if 0 - QMessageBox msg; - msg.setText(QString(tr("Can't create any more profiles!"))); - msg.setIcon(QMessageBox::Warning); - msg.exec(); -#else QMessageBox::warning(this, tr("Houston, we have a problem..."), tr("Can't create any more profiles!")); -#endif return; } @@ -254,7 +223,7 @@ void ControllerTab::AddMapName(void) profile[profileNum].device = deviceList->itemData(deviceList->currentIndex()).toInt(); strncpy(profile[profileNum].mapName, text.toAscii().data(), 31); profile[profileNum].mapName[31] = 0; - profile[profileNum].preferredController = CONTROLLER1; + profile[profileNum].preferredSlot = CONTROLLER1; for(int i=BUTTON_FIRST; icount() == 1) ; - QMessageBox::StandardButton retVal = QMessageBox::question(this, tr("Remove Mapping"), tr("Are you sure you want to remove this mapping?"), QMessageBox::No | QMessageBox::Yes, QMessageBox::No); if (retVal == QMessageBox::No) @@ -282,76 +246,3 @@ void ControllerTab::DeleteMapName(void) DeleteProfile(profileToRemove); } - -/* -The profiles need the following: - - - The name of the controller - - A unique human readable ID - - The key definitions for that controller (keyboard keys can be mixed in) - -So there can be more than one profile for each unique controller; the -relationship is many-to-one. So basically, how it works it like this: SDL -reports all connected controllers. If there are none connected, the default -controller is the keyboard (which can have multiple profiles). The UI only -presents those profiles which are usuable with the controllers that are plugged -in, all else is ignored. The user can pick the profile for the controller and -configure the keys for it; the UI automagically saves everything. - -How to handle the case of identical controllers being plugged in? How does the -UI know which is which? Each controller will have a mapping to a default -Jaguar controller (#1 or #2). Still doesn't prevent confusion though. Actually, -it can: The profile can have a field that maps it to a preferred Jaguar -controller, which can also be both (#1 AND #2--in this case we can set it to -zero which means no preference). If the UI detects two of the same controller -and each can be mapped to the same profile, it assigns them in order since it -doesn't matter, the profiles are identical. - -The default profile is always available and is the keyboard (hey, we're PC -centric here). The default profile is usually #0. - -Can there be more than one keyboard profile? Why not? You will need separate -ones for controller #1 and controller #2. - -A profile might look like this: - -Field 1: Nostomo N45 Analog -Field 2: Dad's #1 -Field 3: Jaguar controller #1 -Field 4: The button/stick mapping - -Profile # would be implicit in the order that they are stored in the internal -data structure. - -When a new controller is plugged in with no profiles attached, it defaults to -a set keyboard layout which the user can change. So every new controller will -always have at least one profile. - -Data structures: -The Gamepad class has the name of the controller (except for Keyboard) -The profile list is just a list -The controller name index + profile index makes a unique key -Probably the best way to deal with it is to stuff the name/profile indices -into the key definition structure. - -#define CONTROLLER1 0x01 -#define CONTROLLER2 0x02 - -struct Profile -{ - int device; // Host device number - char mapName[32]; // Human readable map name - int preferredController; // CONTROLLER1 and/or CONTROLLER2 - int map[21]; // Keys/buttons/axes -}; - -NOTE that device is an int, and the list is maintained elsewhere. It is -*not* the same as what you see in GetJoystickName(); the device names have -to be able to persist even when not available. - -Where to store the master profile list? It has to be accessible to this class. -vjs.profile[x] would be good, but it's not really a concern for the Jaguar core. -So it shouldn't go there. There should be a separate global setting place for -GUI stuff... -*/ - diff --git a/src/gui/controllerwidget.cpp b/src/gui/controllerwidget.cpp index 53a747a..ca27cb5 100644 --- a/src/gui/controllerwidget.cpp +++ b/src/gui/controllerwidget.cpp @@ -19,8 +19,8 @@ #include "keygrabber.h" -// These tables are used to convert Qt keycodes into human readable form. Note that -// a lot of these are just filler. +// These tables are used to convert Qt keycodes into human readable form. Note +// that a lot of these are just filler. char ControllerWidget::keyName1[96][16] = { "Space", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", diff --git a/src/gui/gamepad.cpp b/src/gui/gamepad.cpp index 93989ee..b8ebdde 100644 --- a/src/gui/gamepad.cpp +++ b/src/gui/gamepad.cpp @@ -7,7 +7,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 01/05/2013 Created this file // @@ -18,7 +18,7 @@ // Class member initialization /*static*/ int Gamepad::numJoysticks = 0; /*static*/ SDL_Joystick * Gamepad::pad[8]; -/*static*/ const char * Gamepad::padName[8]; +/*static*/ char Gamepad::padName[8][128]; /*static*/ int Gamepad::numButtons[8]; /*static*/ int Gamepad::numHats[8]; /*static*/ int Gamepad::numAxes[8]; @@ -51,18 +51,27 @@ void Gamepad::AllocateJoysticks(void) for(int i=0; i 127 if (pad[i]) { numButtons[i] = SDL_JoystickNumButtons(pad[i]); numHats[i] = SDL_JoystickNumHats(pad[i]); numAxes[i] = SDL_JoystickNumAxes(pad[i]); + WriteLog("Gamepad: Joystick #%i: %s\n", i, padName[i]); } } WriteLog("Gamepad: Found %u joystick%s.\n", numJoysticks, (numJoysticks == 1 ? "" : "s")); +#if 0 +for(int i=0; i= 8) return NULL; +//printf("GAMEPAD: Getting name (%s) for joystick #%i...\n", padName[joystickID], joystickID); return padName[joystickID]; } @@ -127,6 +137,7 @@ bool Gamepad::GetState(int joystickID, int buttonID) } +//UNUSED int Gamepad::CheckButtonPressed(void) { // This translates the hat direction to a mask index. @@ -165,6 +176,7 @@ int Gamepad::CheckButtonPressed(void) } +// UNUSED int Gamepad::GetButtonID(void) { // Return single button ID being pressed (if any) @@ -172,6 +184,7 @@ int Gamepad::GetButtonID(void) } +// UNUSED int Gamepad::GetJoystickID(void) { // Return joystick ID of button being pressed (if any) @@ -198,6 +211,7 @@ void Gamepad::Update(void) } +// However, SDL 2 *does* support hot-plugging! :-D #if 0 // Need to test this. It may be that the only time joysticks are detected is // when the program is first run. That would suck. diff --git a/src/gui/gamepad.h b/src/gui/gamepad.h index a7085a4..73aaef8 100644 --- a/src/gui/gamepad.h +++ b/src/gui/gamepad.h @@ -30,7 +30,7 @@ class Gamepad { // really should make all methods and members be static so that we can -// call this stuff without instantiating one. :-) +// call this stuff without instantiating one. :-) [DONE] public: Gamepad(); ~Gamepad(); @@ -48,7 +48,7 @@ class Gamepad // Support up to 8 gamepads static int numJoysticks; static SDL_Joystick * pad[8]; - static const char * padName[8]; + static char padName[8][128]; static int numButtons[8]; static int numAxes[8]; static int numHats[8]; diff --git a/src/gui/glwidget.h b/src/gui/glwidget.h index e7d7406..7557ea6 100644 --- a/src/gui/glwidget.h +++ b/src/gui/glwidget.h @@ -8,6 +8,7 @@ #include #include +#include class GLWidget: public QGLWidget { diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index f4dda13..713ec11 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -6,7 +6,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 12/23/2009 Created this file // JLH 12/20/2010 Added settings, menus & toolbars // JLH 07/05/2011 Added CD BIOS functionality to GUI @@ -16,14 +16,16 @@ // // - Add dbl click/enter to select in cart list, ESC to dimiss [DONE] // - Autoscan/autoload all available BIOS from 'software' folder [DONE] -// - Add 1 key jumping in cartridge list (press 'R', jumps to carts starting with 'R', etc) [DONE] +// - Add 1 key jumping in cartridge list (press 'R', jumps to carts starting +// with 'R', etc) [DONE] // - Controller configuration [DONE] // // STILL TO BE DONE: // // - Fix bug in switching between PAL & NTSC in fullscreen mode. // - Remove SDL dependencies (sound, mainly) from Jaguar core lib -// - Fix inconsistency with trailing slashes in paths (eeproms needs one, software doesn't) +// - Fix inconsistency with trailing slashes in paths (eeproms needs one, +// software doesn't) // // SFDX CODE: S1E9T8H5M23YS @@ -562,6 +564,9 @@ void MainWin::HandleKeys(QKeyEvent * e, bool state) } +// +// N.B.: The profile system AutoConnect functionality sets the gamepad IDs here. +// void MainWin::HandleGamepads(void) { Gamepad::Update(); @@ -569,13 +574,10 @@ void MainWin::HandleGamepads(void) for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++) { if (vjs.p1KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS)) - joypad0Buttons[i] = (Gamepad::GetState(0, vjs.p1KeyBindings[i]) ? 0x01 : 0x00); -/*{ -if (vjs.p1KeyBindings[i] & JOY_AXIS) - printf("Axis state (HandleGamepads): %i\n", joypad0Buttons[i]); -}*/ + joypad0Buttons[i] = (Gamepad::GetState(gamepadIDSlot1, vjs.p1KeyBindings[i]) ? 0x01 : 0x00); + if (vjs.p2KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS)) - joypad1Buttons[i] = (Gamepad::GetState(1, vjs.p2KeyBindings[i]) ? 0x01 : 0x00); + joypad1Buttons[i] = (Gamepad::GetState(gamepadIDSlot2, vjs.p2KeyBindings[i]) ? 0x01 : 0x00); } } @@ -593,9 +595,15 @@ void MainWin::Configure(void) dlg.generalTab->useUnknownSoftware->setChecked(allowUnknownSoftware); dlg.controllerTab1->profileNum = lastEditedProfile; dlg.controllerTab1->SetupLastUsedProfile(); +// maybe instead of this, we tell the controller tab to work on a copy that gets +// written if the user hits 'OK'. + SaveProfiles(); // Just in case user cancels if (dlg.exec() == false) + { + RestoreProfiles(); return; + } QString before = vjs.ROMPath; QString alpineBefore = vjs.alpineROMPath; @@ -613,6 +621,7 @@ void MainWin::Configure(void) //ick. allowUnknownSoftware = dlg.generalTab->useUnknownSoftware->isChecked(); lastEditedProfile = dlg.controllerTab1->profileNum; + AutoConnectProfiles(); // We rescan the "software" folder if the user either changed the path or // checked/unchecked the "Allow unknown files" option in the config dialog. diff --git a/src/gui/profile.cpp b/src/gui/profile.cpp index 71e6946..114b98c 100644 --- a/src/gui/profile.cpp +++ b/src/gui/profile.cpp @@ -7,10 +7,27 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 05/01/2013 Created this file +// JLH 10/02/2014 Finally fixed stuff so it works the way it should +// +// This is a profile database with two parts: One, a list of devices, and two, +// a list of profiles each containing a pointer to the device list, and map +// name, a preferred slot #, and a key/button map. All the heavy lifting (incl. +// autoconnection of devices to profiles to slots) is done here. +// +// Basically, how this works is that we connect the device the user plugs into +// the computer to a profile in the database to a slot in the virtual Jaguar. +// Hopefully the configuration that the user gives us is sane enough for us to +// figure out how to do the right thing! By default, there is always a keyboard +// device plugged in; any other device that gets plugged in and wants to be in +// slot #0 can override it. This is so there is always a sane configuration if +// nothing is plugged in. +// +// Devices go into the database when the user plugs them in and runs VJ, and +// subsequently does anything to alter any of the existing profiles. Once a +// device has been seen, it can't be unseen! // - #include "profile.h" #include @@ -19,14 +36,16 @@ #include "settings.h" +//#define DEBUG_PROFILES #define MAX_DEVICES 64 Profile profile[MAX_PROFILES]; +Profile profileBackup[MAX_PROFILES]; int controller1Profile; int controller2Profile; -int gamepad1Slot; -int gamepad2Slot; +int gamepadIDSlot1; +int gamepadIDSlot2; int numberOfProfiles; int numberOfDevices; char deviceNames[MAX_DEVICES][128]; @@ -37,11 +56,28 @@ uint32_t defaultMap[21] = { '3', 'L', 'K', 'J', 'O', 'P' }; + // Function Prototypes -int ConnectProfileToDevice(int deviceNum); +int ConnectProfileToDevice(int deviceNum, int gamepadID = -1); int FindProfileForDevice(int deviceNum, int preferred, int * found); +// +// These two functions are mainly to support the controller configuration GUI. +// Could just as easily go there as well (and be better placed there). +// +void SaveProfiles(void) +{ + memcpy(&profileBackup, &profile, sizeof(Profile) * MAX_PROFILES); +} + + +void RestoreProfiles(void) +{ + memcpy(&profile, &profileBackup, sizeof(Profile) * MAX_PROFILES); +} + + void ReadProfiles(QSettings * set) { // Assume no profiles, until we read them @@ -59,39 +95,49 @@ void ReadProfiles(QSettings * set) { set->setArrayIndex(i - 1); strcpy(deviceNames[i], set->value("deviceName").toString().toAscii().data()); -//printf("Read device name: %s\n", deviceNames[i]); +#ifdef DEBUG_PROFILES +printf("Read device name: %s\n", deviceNames[i]); +#endif } set->endArray(); numberOfProfiles = set->beginReadArray("profiles"); -//printf("Number of profiles: %u\n", numberOfProfiles); +#ifdef DEBUG_PROFILES +printf("Number of profiles: %u\n", numberOfProfiles); +#endif for(int i=0; isetArrayIndex(i); profile[i].device = set->value("deviceNum").toInt(); strcpy(profile[i].mapName, set->value("mapName").toString().toAscii().data()); - profile[i].preferredController = set->value("preferredController").toInt(); + profile[i].preferredSlot = set->value("preferredSlot").toInt(); for(int j=0; j<21; j++) { QString string = QString("map%1").arg(j); profile[i].map[j] = set->value(string).toInt(); } -//printf("Profile #%u: device=%u (%s)\n", i, profile[i].device, deviceNames[profile[i].device]); +#ifdef DEBUG_PROFILES +printf("Profile #%u: device=%u (%s)\n", i, profile[i].device, deviceNames[profile[i].device]); +#endif } set->endArray(); -//printf("Number of profiles found: %u\n", numberOfProfiles); +#ifdef DEBUG_PROFILES +printf("Number of profiles found: %u\n", numberOfProfiles); +#endif // Set up a reasonable default if no profiles were found if (numberOfProfiles == 0) { -//printf("Setting up default profile...\n"); +#ifdef DEBUG_PROFILES +printf("Setting up default profile...\n"); +#endif numberOfProfiles++; profile[0].device = 0; // Keyboard is always device #0 strcpy(profile[0].mapName, "Default"); - profile[0].preferredController = CONTROLLER1; + profile[0].preferredSlot = CONTROLLER1; for(int i=0; i<21; i++) profile[0].map[i] = defaultMap[i]; @@ -123,7 +169,7 @@ void WriteProfiles(QSettings * set) set->setArrayIndex(i); set->setValue("deviceNum", profile[i].device); set->setValue("mapName", profile[i].mapName); - set->setValue("preferredController", profile[i].preferredController); + set->setValue("preferredSlot", profile[i].preferredSlot); for(int j=0; j<21; j++) { @@ -172,12 +218,22 @@ int FindDeviceNumberForName(const char * name) for(int i=0; iaddItem(QString("Keyboard::%1").arg(profile[j].mapName), j); found++; @@ -246,7 +303,7 @@ int FindUsableProfiles(QComboBox * combo) for(int j=0; jaddItem(QString("%1::%2").arg(Gamepad::GetJoystickName(i)).arg(profile[j].mapName), j); found++; @@ -260,6 +317,10 @@ int FindUsableProfiles(QComboBox * combo) bool ConnectProfileToController(int profileNum, int controllerNum) { + // Sanity checks... + if (profileNum < 0) + return false; + if (profile[profileNum].device == -1) return false; @@ -276,141 +337,113 @@ bool ConnectProfileToController(int profileNum, int controllerNum) } -// -// This is a pretty crappy way of doing autodetection. What it does is scan for -// keyboard profiles first, then look for plugged in gamepads next. If more -// than one plugged in gamepad matches a preferred controller slot, the last -// one found is chosen. -// -// There has to be a better way to do this, I just can't think of what it -// should be ATM... :-P -// /* -Here's the rules: If preferred Jaguar controller is not checked, the profile is -skipped. If one or the other is checked, it's put into that slot. If *both* are -checked, it will take over any slot that isn't claimed by another gamepad. If -there are ties, present it to the user *once* and ask them which gamepad should -be #1; don't ask again unless a), they change the profiles and b), the -situation warrants it. - -Also, there is a problem with this approach and having multiple devices -that are the same. Currently, if two of the same device are plugged in -and the profile is set to both controllers, it will broadcast buttons -pressed from either gamepad, no matter who is pressing them. This is -BAD(tm). [Not true, but there's a different problem described under 'How to -solve?', so GOOD(tm).] - -Also, the gamepad logic doesn't distinguish inputs by controller, it just -grabs them all regardless. This is also BAD(tm). [Actually, it doesn't. It -properly segregates the inputs. So this is GOOD(tm).] - -How to solve? - -Seems there's yet ANOTHER dimension to all this: The physical gamepads -plugged into their ports. Now the device # can map these fine if they're -different, but we still run into problems with the handling in the MainWin -because it's hardwired to take pad 0 in slot 0 and pad 1 in slot 1. If you have -them configured other than this, you won't get anything. So we need to also -map the physical devices to their respective slots. - - -Steps: - -1) Make a list of all devices attached to the system. - -2) Make a list of all profiles belonging to those devices, as long as they have - one or more Jaguar controllers that are "mapped to". - -3) See if there are any conflicts. If there are, see if the user has already - been asked to resolve and chosen a resolution; otherwise, ask the user to - resolve. - - a) Loop through all found profiles. If they are set to a single controller, - set it in the appropriate list (one list for controller 1, another for - controller 2). - - b) Loop through all found profiles. If they are set to both controllers, - ... (first stab at it:) - Check for list #1. If nothing there, assign it to list #1. - Else, check for List #2. If nothing there, assign to list #2. - [But the wording of it implies that it will assign it to both. - Does that mean we should make another combobox will all the possible - combinations laid out? Probably. Not many people will understand that - checking both means "assign to either one that's free".] - -4) Connect profiles to controllers, and set gamepad slots (for the MainWin - handler). - +One more stab at this... + + - Connect keyboard to slot #0. + - Loop thru all connected devices. For each device: + - Grab all profiles for the device. For each profile: + - Check to see what its preferred device is. + - If PD is slot #0, see if slot is already taken (gamepadIDSlot1 != -1). + If not taken, take it; otherwise put in list to tell user to solve the + conflict for us. + - If the slot is already taken and *it's the same device* as the one + we're looking at, set it in slot #1. + - If PD is slot #1, see if slot is already taken. If not, take it; + otherwise, put in list to tell user to solve conflict for us. + - If PD is slot #0 & #1, see if either is already taken. Try #0 first, + then try #1. If both are already taken, skip it. Do this *after* we've + connected devices with preferred slots. */ void AutoConnectProfiles(void) { int foundProfiles[MAX_PROFILES]; - int controller1Profile = -1; - int controller2Profile = -1; + controller1Profile = -1; + controller2Profile = -1; + gamepadIDSlot1 = -1; + gamepadIDSlot2 = -1; - // Check for Keyboard device profiles first, if anything else is plugged in - // it will default to it instead. -#if 0 - for(int i=0; i= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20)) { DSPWriteByte(offset, data, who); return; } - else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) + else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE + 0x2000)) { DSPWriteByte(offset, data, who); return; @@ -596,7 +640,7 @@ WriteLog("JERRYWriteByte: Unhandled byte write to JOYSTICK by %s.\n", whoName[wh if (offset >= 0xF1D000 && offset <= 0xF1DFFF) return; - jerry_ram_8[offset & 0xFFFF] = data; +// jerry_ram_8[offset & 0xFFFF] = data; } @@ -605,6 +649,10 @@ WriteLog("JERRYWriteByte: Unhandled byte write to JOYSTICK by %s.\n", whoName[wh // void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/) { + // Moved here tentatively, so we can see everything written to JERRY. + jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF; + jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF; + #ifdef JERRY_DEBUG WriteLog( "JERRY: Writing word %04X at %06X\n", data, offset); #endif @@ -634,12 +682,12 @@ else if (offset == 0xF10020) (data & 0x10 ? "ASI " : ""), (data & 0x20 ? "I2S " : "")); #endif - if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20)) { DSPWriteWord(offset, data, who); return; } - else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) + else if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE + 0x2000)) { DSPWriteWord(offset, data, who); return; @@ -694,11 +742,6 @@ else if (offset == 0xF10020) return; } -/* else if (offset >= 0xF10010 && offset < 0xF10016) - { - clock_word_write(offset, data); - return; - }//*/ // JERRY -> 68K interrupt enables/latches (need to be handled!) else if (offset >= 0xF10020 && offset <= 0xF10022) { @@ -708,12 +751,6 @@ else if (offset == 0xF10020) //WriteLog("JERRY: (Previous is partially handled... IRQMask=$%04X)\n", jerryInterruptMask); return; } -/* else if (offset >= 0xF17C00 && offset < 0xF17C02) - { -//I think this was removed from the Jaguar. If so, then we don't need this...! - anajoy_word_write(offset, data); - return; - }*/ else if (offset >= 0xF14000 && offset < 0xF14003) { JoystickWriteWord(offset, data); @@ -730,8 +767,8 @@ else if (offset == 0xF10020) if (offset >= 0xF1D000 && offset <= 0xF1DFFF) return; - jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF; - jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF; +// jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF; +// jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF; } diff --git a/src/jerry.h b/src/jerry.h index cff1c25..868c5a0 100644 --- a/src/jerry.h +++ b/src/jerry.h @@ -11,6 +11,7 @@ void JERRYInit(void); void JERRYReset(void); void JERRYDone(void); +void JERRYDumpIORegistersToLog(void); uint8_t JERRYReadByte(uint32_t offset, uint32_t who = UNKNOWN); uint16_t JERRYReadWord(uint32_t offset, uint32_t who = UNKNOWN); diff --git a/src/memory.cpp b/src/memory.cpp index 7ebdb2f..3782200 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -23,6 +23,8 @@ the I/O function would take care of any weird stuff... Actually: writes would tuck in the value, but reads would have to be handled correctly since some registers do not fall on the same address as far as reading goes... Still completely doable though. :-) + +N.B.: Jaguar RAM is only 2 megs. ROM is 6 megs max, IO is 128K */ #include "memory.h" diff --git a/src/mmu.cpp b/src/mmu.cpp index 3897389..3eaf312 100644 --- a/src/mmu.cpp +++ b/src/mmu.cpp @@ -197,7 +197,10 @@ struct MemDesc { MemDesc memoryMap[] = { - { 0x000000, 0x3FFFFF, MM_RAM, jaguarMainRAM }, + { 0x000000, 0x1FFFFF, MM_RAM, jaguarMainRAM }, + { 0x200000, 0x3FFFFF, MM_RAM, jaguarMainRAM }, // Mirror of 1st 2 megs + { 0x400000, 0x5FFFFF, MM_RAM, jaguarMainRAM }, // " " + { 0x600000, 0x7FFFFF, MM_RAM, jaguarMainRAM }, // " " { 0x800000, 0xDFFEFF, MM_ROM, jaguarMainROM }, { 0xDFFF00, 0xDFFF03, MM_IO, &butch }, // base of Butch == interrupt control register, R/W diff --git a/src/settings.cpp b/src/settings.cpp index 078bc4a..7cf1efa 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -7,7 +7,7 @@ // JLH = James Hammons // // Who When What -// --- ---------- ------------------------------------------------------------- +// --- ---------- ------------------------------------------------------------ // JLH 01/16/2010 Created this log // JLH 02/23/2013 Finally removed commented out stuff :-P // diff --git a/src/settings.h b/src/settings.h index 8c2d226..efd1306 100644 --- a/src/settings.h +++ b/src/settings.h @@ -10,7 +10,11 @@ #include #define MAX_PATH _POSIX_PATH_MAX #else -#include // for MAX_PATH on MinGW/Darwin +#include // for MAX_PATH on MinGW/Darwin +// Kludge for Win64 +#ifndef MAX_PATH +#define MAX_PATH _MAX_PATH // Urgh. +#endif #endif #include @@ -19,8 +23,8 @@ struct VJSettings { bool useJoystick; - int32_t joyport; // Joystick port - bool hardwareTypeNTSC; // Set to false for PAL + int32_t joyport; // Joystick port + bool hardwareTypeNTSC; // Set to false for PAL bool useJaguarBIOS; bool GPUEnabled; bool DSPEnabled; diff --git a/src/tom.cpp b/src/tom.cpp index cefee64..34d7696 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -307,6 +307,7 @@ #define HEQ 0x54 // Horizontal equalization end #define BG 0x58 // Background color #define INT1 0xE0 +#define INT2 0xE2 //NOTE: These arbitrary cutoffs are NOT taken into account for PAL jaguar screens. !!! FIX !!! [DONE] @@ -1083,6 +1084,7 @@ void TOMInit(void) void TOMDone(void) { + TOMDumpIORegistersToLog(); OPDone(); BlitterDone(); WriteLog("TOM: Resolution %i x %i %s\n", TOMGetVideoModeWidth(), TOMGetVideoModeHeight(), @@ -1090,10 +1092,6 @@ void TOMDone(void) // WriteLog("\ntom: object processor:\n"); // WriteLog("tom: pointer to object list: 0x%.8x\n",op_get_list_pointer()); // WriteLog("tom: INT1=0x%.2x%.2x\n",TOMReadByte(0xf000e0),TOMReadByte(0xf000e1)); -// gpu_done(); -// dsp_done(); -// memory_free(tomRam8); -// memory_free(tom_cry_rgb_mix_lut); } @@ -1249,6 +1247,7 @@ void TOMReset(void) if (vjs.hardwareTypeNTSC) { SET16(tomRam8, MEMCON1, 0x1861); +// SET16(tomRam8, MEMCON1, 0x1865);//Bunch of BS SET16(tomRam8, MEMCON2, 0x35CC); SET16(tomRam8, HP, 844); // Horizontal Period (1-based; HP=845) SET16(tomRam8, HBB, 1713); // Horizontal Blank Begin @@ -1296,6 +1295,50 @@ void TOMReset(void) } +// +// Dump all TOM register values to the log +// +void TOMDumpIORegistersToLog(void) +{ + WriteLog("\n\n---------------------------------------------------------------------\n"); + WriteLog("TOM I/O Registers\n"); + WriteLog("---------------------------------------------------------------------\n"); + WriteLog("F000%02X (MEMCON1): $%04X\n", MEMCON1, GET16(tomRam8, MEMCON1)); + WriteLog("F000%02X (MEMCON2): $%04X\n", MEMCON2, GET16(tomRam8, MEMCON2)); + WriteLog("F000%02X (HC): $%04X\n", HC, GET16(tomRam8, HC)); + WriteLog("F000%02X (VC): $%04X\n", VC, GET16(tomRam8, VC)); + WriteLog("F000%02X (OLP): $%08X\n", OLP, GET32(tomRam8, OLP)); + WriteLog("F000%02X (OBF): $%04X\n", OBF, GET16(tomRam8, OBF)); + WriteLog("F000%02X (VMODE): $%04X\n", VMODE, GET16(tomRam8, VMODE)); + WriteLog("F000%02X (BORD1): $%04X\n", BORD1, GET16(tomRam8, BORD1)); + WriteLog("F000%02X (BORD2): $%04X\n", BORD2, GET16(tomRam8, BORD2)); + WriteLog("F000%02X (HP): $%04X\n", HP, GET16(tomRam8, HP)); + WriteLog("F000%02X (HBB): $%04X\n", HBB, GET16(tomRam8, HBB)); + WriteLog("F000%02X (HBE): $%04X\n", HBE, GET16(tomRam8, HBE)); + WriteLog("F000%02X (HS): $%04X\n", HS, GET16(tomRam8, HS)); + WriteLog("F000%02X (HVS): $%04X\n", HVS, GET16(tomRam8, HVS)); + WriteLog("F000%02X (HDB1): $%04X\n", HDB1, GET16(tomRam8, HDB1)); + WriteLog("F000%02X (HDB2): $%04X\n", HDB2, GET16(tomRam8, HDB2)); + WriteLog("F000%02X (HDE): $%04X\n", HDE, GET16(tomRam8, HDE)); + WriteLog("F000%02X (VP): $%04X\n", VP, GET16(tomRam8, VP)); + WriteLog("F000%02X (VBB): $%04X\n", VBB, GET16(tomRam8, VBB)); + WriteLog("F000%02X (VBE): $%04X\n", VBE, GET16(tomRam8, VBE)); + WriteLog("F000%02X (VS): $%04X\n", VS, GET16(tomRam8, VS)); + WriteLog("F000%02X (VDB): $%04X\n", VDB, GET16(tomRam8, VDB)); + WriteLog("F000%02X (VDE): $%04X\n", VDE, GET16(tomRam8, VDE)); + WriteLog("F000%02X (VEB): $%04X\n", VEB, GET16(tomRam8, VEB)); + WriteLog("F000%02X (VEE): $%04X\n", VEE, GET16(tomRam8, VEE)); + WriteLog("F000%02X (VI): $%04X\n", VI, GET16(tomRam8, VI)); + WriteLog("F000%02X (PIT0): $%04X\n", PIT0, GET16(tomRam8, PIT0)); + WriteLog("F000%02X (PIT1): $%04X\n", PIT1, GET16(tomRam8, PIT1)); + WriteLog("F000%02X (HEQ): $%04X\n", HEQ, GET16(tomRam8, HEQ)); + WriteLog("F000%02X (BG): $%04X\n", BG, GET16(tomRam8, BG)); + WriteLog("F000%02X (INT1): $%04X\n", INT1, GET16(tomRam8, INT1)); + WriteLog("F000%02X (INT2): $%04X\n", INT2, GET16(tomRam8, INT2)); + WriteLog("---------------------------------------------------------------------\n\n\n"); +} + + // // TOM byte access (read) // @@ -1396,6 +1439,9 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) // void TOMWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) { + // Moved here tentatively, so we can see everything written to TOM. + tomRam8[offset & 0x3FFF] = data; + #ifdef TOM_DEBUG WriteLog("TOM: Writing byte %02X at %06X", data, offset); #endif @@ -1470,7 +1516,7 @@ void TOMWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) tomRam8[offset] = data, tomRam8[offset + 0x200] = data; } - tomRam8[offset & 0x3FFF] = data; +// tomRam8[offset & 0x3FFF] = data; } @@ -1479,6 +1525,10 @@ void TOMWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) // void TOMWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/) { + // Moved here tentatively, so we can see everything written to TOM. + tomRam8[(offset + 0) & 0x3FFF] = data >> 8; + tomRam8[(offset + 1) & 0x3FFF] = data & 0xFF; + #ifdef TOM_DEBUG WriteLog("TOM: Writing byte %04X at %06X", data, offset); #endif @@ -1584,8 +1634,8 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) data &= 0x03FF; // These are all 10-bit registers // Fix a lockup bug... :-P - TOMWriteByte(0xF00000 | offset, data >> 8, who); - TOMWriteByte(0xF00000 | (offset+1), data & 0xFF, who); +// TOMWriteByte(0xF00000 | offset, data >> 8, who); +// TOMWriteByte(0xF00000 | (offset+1), data & 0xFF, who); if (offset == MEMCON1) WriteLog("TOM: Memory Config 1 written by %s: $%04X\n", whoName[who], data); @@ -1654,6 +1704,7 @@ if (offset == HEQ) // TOM Shouldn't be mucking around with this, it's up to the host system to properly // handle this kind of crap. // NOTE: This is needed somehow, need to get rid of the dependency on this crap. +// N.B.: It's used in the rendering functions... So... #warning "!!! Need to get rid of this dependency !!!" #if 1 if ((offset >= 0x28) && (offset <= 0x4F)) diff --git a/src/tom.h b/src/tom.h index 3ffc186..ed89b93 100644 --- a/src/tom.h +++ b/src/tom.h @@ -41,6 +41,8 @@ uint8_t TOMGetVideoMode(void); uint8_t * TOMGetRamPointer(void); uint16_t TOMGetHDB(void); uint16_t TOMGetVDB(void); +void TOMDumpIORegistersToLog(void); + int TOMIRQEnabled(int irq); uint16_t TOMIRQControlReg(void); diff --git a/virtualjaguar.pro b/virtualjaguar.pro index 75b07cb..635f0c0 100644 --- a/virtualjaguar.pro +++ b/virtualjaguar.pro @@ -6,20 +6,22 @@ # # See the README and GPLv3 files for licensing and warranty information # -# NOTE: M68000 core is built and linked in as a library, so there should be no more -# problems with using the qmake build system as-is. :-) -# Other than on the Mac, where it stupidly defaults to making XCode binaries. >:-( -# Well, we fixed it in the Makefile, by doing platfrom detection there. :-/ +# NOTE: M68000 core is built and linked in as a library, so there should be no +# more problems with using the qmake build system as-is. :-) +# Other than on the Mac, where it stupidly defaults to making XCode +# binaries. >:-( Well, we fixed it in the Makefile, by doing platform +# detection there. :-/ # TARGET = virtualjaguar CONFIG += qt warn_on release # debug RESOURCES += virtualjaguar.qrc -LIBS += -Lobj -ljaguarcore -lz -lm68k +LIBS += -Lobj -Lsrc/m68000/obj -ljaguarcore -lz -lm68k QT += opengl -# We stuff all the intermediate crap into obj/ so it won't confuse us mere mortals ;-) +# We stuff all the intermediate crap into obj/ so it won't confuse us mere +# mortals ;-) OBJECTS_DIR = obj MOC_DIR = obj RCC_DIR = obj @@ -35,19 +37,23 @@ macx { LIBS += `sdl-config --static-libs` } else { LIBS += `$(CROSS)sdl-config --libs` } # Icon on Win32, Mac -win32 { LIBS += res/vj-ico.o } +#win32 { LIBS += res/vj-ico.o } +win32 { ICON = res/vj.ico } macx { ICON = res/vj-icon.icns } # C/C++ flags... # NOTE: May have to put -Wall back in, but only on non-release cycles. It can -# cause problems if you're not careful. (Can do this via command line in qmake) +# cause problems if you're not careful. (Can do this via command line in +# qmake) QMAKE_CFLAGS += `$(CROSS)sdl-config --cflags` QMAKE_CXXFLAGS += `$(CROSS)sdl-config --cflags` # Need to add libcdio stuffola (checking/including)... -# Translations. NB: Nobody has stepped up to do any :-P so these are dummy translations -TRANSLATIONS = virtualjaguar_fr.ts \ +# Translations. NB: Nobody has stepped up to do any :-P so these are dummy +# translations +TRANSLATIONS = \ + virtualjaguar_fr.ts \ virtualjaguar_gr.ts INCLUDEPATH += \ @@ -84,8 +90,7 @@ HEADERS = \ src/gui/debug/m68kdasmbrowser.h \ src/gui/debug/memorybrowser.h \ src/gui/debug/opbrowser.h \ - src/gui/debug/riscdasmbrowser.h \ -# src/gui/sdljoystick.h + src/gui/debug/riscdasmbrowser.h SOURCES = \ src/gui/about.cpp \ @@ -109,5 +114,5 @@ SOURCES = \ src/gui/debug/m68kdasmbrowser.cpp \ src/gui/debug/memorybrowser.cpp \ src/gui/debug/opbrowser.cpp \ - src/gui/debug/riscdasmbrowser.cpp \ -# src/gui/sdljoystick.cpp + src/gui/debug/riscdasmbrowser.cpp +