#include "gamepad.h"
#include "log.h"
#include "mainwin.h"
+#include "profile.h"
#include "settings.h"
#include "version.h"
WriteLog("VJ: SDL (joystick, audio) successfully initialized.\n");
App app(argc, argv); // Declare an instance of the application
Gamepad::AllocateJoysticks();
+ AutoConnectProfiles();
retVal = app.exec(); // And run it!
Gamepad::DeallocateJoysticks();
#include "settings.h"
-ConfigDialog::ConfigDialog(QWidget * parent/*= 0*/): QDialog(parent)
+ConfigDialog::ConfigDialog(QWidget * parent/*= 0*/): QDialog(parent),
+ tabWidget(new QTabWidget),
+ generalTab(new GeneralTab(this)),
+ controllerTab1(new ControllerTab(this))
{
- tabWidget = new QTabWidget;
- generalTab = new GeneralTab(this);
- controllerTab1 = new ControllerTab(this);
- controllerTab2 = new ControllerTab(this);
+// tabWidget = new QTabWidget;
+// generalTab = new GeneralTab(this);
+// controllerTab1 = new ControllerTab(this);
+//// controllerTab2 = new ControllerTab(this);
- if (vjs.hardwareTypeAlpine)
- alpineTab = new AlpineTab(this);
+// if (vjs.hardwareTypeAlpine)
+// alpineTab = new AlpineTab(this);
tabWidget->addTab(generalTab, tr("General"));
- tabWidget->addTab(controllerTab1, tr("Controller #1"));
- tabWidget->addTab(controllerTab2, tr("Controller #2"));
+ tabWidget->addTab(controllerTab1, tr("Controllers"));
+// tabWidget->addTab(controllerTab2, tr("Controller #2"));
if (vjs.hardwareTypeAlpine)
+ {
+ alpineTab = new AlpineTab(this);
tabWidget->addTab(alpineTab, tr("Alpine"));
+ }
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
setLayout(mainLayout);
setWindowTitle(tr("Virtual Jaguar Settings"));
-
LoadDialogFromSettings();
-// controllerTab1->UpdateLabel(); // Now it's safe to do this... ;-)
-// controllerTab2->UpdateLabel(); // Now it's safe to do this... ;-)
}
alpineTab->writeROM->setChecked(vjs.allowWritesToROM);
}
+#warning "!!! Need to load settings from controller profile !!!"
+#if 0
for(int i=0; i<21; i++)
{
+// We need to find the right profile and load it up here...
controllerTab1->controllerWidget->keys[i] = vjs.p1KeyBindings[i];
- controllerTab2->controllerWidget->keys[i] = vjs.p2KeyBindings[i];
+// controllerTab2->controllerWidget->keys[i] = vjs.p2KeyBindings[i];
}
+#endif
}
vjs.allowWritesToROM = alpineTab->writeROM->isChecked();
}
+#warning "!!! Need to save settings to controller profile !!!"
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];
+// vjs.p2KeyBindings[i] = controllerTab2->controllerWidget->keys[i];
}
}
public:
GeneralTab * generalTab;
ControllerTab * controllerTab1;
- ControllerTab * controllerTab2;
+// ControllerTab * controllerTab2;
AlpineTab * alpineTab;
};
#include "gamepad.h"
#include "joystick.h"
#include "keygrabber.h"
+#include "profile.h"
ControllerTab::ControllerTab(QWidget * parent/*= 0*/): QWidget(parent),
- label(new QLabel(tr("Controller:"))),
- profileList(new QComboBox(this)),
+ label1(new QLabel(tr("Host Device:"))),
+ label2(new QLabel(tr("Map Name:"))),
+ label3(new QLabel(tr("Maps to:"))),
+ deviceList(new QComboBox(this)),
+ mapNameList(new QComboBox(this)),
+ controller1(new QCheckBox(tr("Jaguar Controller #1"))),
+ controller2(new QCheckBox(tr("Jaguar Controller #2"))),
+ addMapName(new QPushButton(tr("+"))),
+ deleteMapName(new QPushButton(tr("-"))),
redefineAll(new QPushButton(tr("Define All Inputs"))),
controllerWidget(new ControllerWidget(this))
{
+// mapNameList->setEditable(true);
+
QVBoxLayout * layout = new QVBoxLayout;
QHBoxLayout * top = new QHBoxLayout;
+ QVBoxLayout * left = new QVBoxLayout;
+ QVBoxLayout * right = new QVBoxLayout;
+ QHBoxLayout * middle = new QHBoxLayout;
+ top->addLayout(left, 0);
+ top->addLayout(right, 1);
layout->addLayout(top);
- top->addWidget(label);
- top->addWidget(profileList, 0, Qt::AlignLeft);
+ left->addWidget(label1, 0, Qt::AlignRight);
+ left->addWidget(label2, 0, Qt::AlignRight);
+ left->addWidget(label3, 0, Qt::AlignRight);
+ left->addWidget(new QLabel);
+ right->addWidget(deviceList);
+
+ right->addLayout(middle);
+ middle->addWidget(mapNameList, 1);
+ middle->addWidget(addMapName, 0);
+ middle->addWidget(deleteMapName, 0);
+// right->addWidget(mapNameList);
+
+ right->addWidget(controller1);
+ right->addWidget(controller2);
layout->addWidget(controllerWidget);
layout->addWidget(redefineAll, 0, Qt::AlignHCenter);
setLayout(layout);
setFixedWidth(sizeHint().width());
connect(redefineAll, SIGNAL(clicked()), this, SLOT(DefineAllKeys()));
- connect(profileList, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeProfile(int)));
+ connect(deviceList, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeDevice(int)));
+ connect(mapNameList, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeMapName(int)));
+ connect(addMapName, SIGNAL(clicked()), this, SLOT(AddMapName()));
+ connect(deleteMapName, SIGNAL(clicked()), this, SLOT(DeleteMapName()));
+ connect(controllerWidget, SIGNAL(KeyDefined(int, uint32_t)), this, SLOT(UpdateProfileKeys(int, uint32_t)));
+ connect(controller1, SIGNAL(clicked()), this, SLOT(UpdateProfileConnections()));
+ connect(controller2, SIGNAL(clicked()), this, SLOT(UpdateProfileConnections()));
- // Set up the profile combobox (Keyboard is the default, and always
+ // Set up the device combobox (Keyboard is the default, and always
// present)
- profileList->addItem(tr("Keyboard"));
+ deviceList->addItem(tr("Keyboard"), 0);
+ // Set up map name combobox (Default is default, and always present)
+// mapNameList->addItem(tr("Default"));
for(int i=0; i<Gamepad::numJoysticks; i++)
- profileList->addItem(Gamepad::GetJoystickName(i));
+ {
+ int deviceNum = FindDeviceNumberForName(Gamepad::GetJoystickName(i));
+ deviceList->addItem(Gamepad::GetJoystickName(i), deviceNum);
+ }
}
+/*
+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.
+*/
ControllerTab::~ControllerTab()
}
+void ControllerTab::SetupLastUsedProfile(void)
+{
+ int deviceNum = deviceList->findData(profile[profileNum].device);
+ int mapNum = mapNameList->findText(profile[profileNum].mapName);
+
+ if (deviceNum == -1 || mapNum == -1)
+ return;
+
+ ChangeDevice(deviceNum);
+ ChangeMapName(mapNum);
+}
+
+
void ControllerTab::DefineAllKeys(void)
{
// char jagButtonName[21][10] = { "Up", "Down", "Left", "Right",
for(int i=BUTTON_FIRST; i<=BUTTON_LAST; i++)
{
-// keyGrab.SetText(jagButtonName[orderToDefine[i]]);
keyGrab.SetKeyText(orderToDefine[i]);
keyGrab.exec();
int key = keyGrab.key;
// Otherwise, populate the appropriate spot in the settings & update screen...
controllerWidget->keys[orderToDefine[i]] = key;
controllerWidget->update();
+ profile[profileNum].map[orderToDefine[i]] = key;
}
}
-void ControllerTab::ChangeProfile(int profile)
+void ControllerTab::UpdateProfileKeys(int mapPosition, uint32_t key)
{
-printf("You selected profile: %s\n", (profile == 0 ? "Keyboard" : Gamepad::GetJoystickName(profile - 1)));
+ profile[profileNum].map[mapPosition] = key;
}
-#if 0
+
+void ControllerTab::UpdateProfileConnections(void)
+{
+ profile[profileNum].preferredController = (controller1->isChecked() ? CONTROLLER1 : 0) | (controller2->isChecked() ? CONTROLLER2 : 0);
+}
+
+
+void ControllerTab::ChangeDevice(int selection)
+{
+ int deviceNum = deviceList->itemData(selection).toInt();
+ mapNameList->clear();
+ int numberOfMappings = FindMappingsForDevice(deviceNum, mapNameList);
+ deleteMapName->setDisabled(numberOfMappings == 1 ? true : false);
+//printf("Found %i mappings for device #%u...\n", numberOfMappings, deviceNum);
+}
+
+
+void ControllerTab::ChangeMapName(int selection)
+{
+ 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);
+}
+
+
+void ControllerTab::AddMapName(void)
+{
+printf("Add new mapping (TODO)...\n");
+}
+
+
+void ControllerTab::DeleteMapName(void)
+{
+printf("Delete current mapping (TODO)...\n");
+}
+
+
+/*
The profiles need the following:
- The name of the controller
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.
-#endif
+
+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...
+*/
ControllerTab(QWidget * parent = 0);
~ControllerTab();
+ void SetupLastUsedProfile(void);
+
protected slots:
void DefineAllKeys(void);
- void ChangeProfile(int);
+ void UpdateProfileKeys(int, uint32_t);
+ void UpdateProfileConnections(void);
+ void ChangeDevice(int);
+ void ChangeMapName(int);
+ void AddMapName(void);
+ void DeleteMapName(void);
private:
- QLabel * label;
- QComboBox * controllerList;
- QComboBox * profileList;
+ QLabel * label1;
+ QLabel * label2;
+ QLabel * label3;
+ QComboBox * deviceList;
+ QComboBox * mapNameList;
+ QCheckBox * controller1;
+ QCheckBox * controller2;
+ QPushButton * addMapName;
+ QPushButton * deleteMapName;
QPushButton * redefineAll;
public:
ControllerWidget * controllerWidget;
- int profile;
+ int profileNum;
};
#endif // __CONTROLLERTAB_H__
int key = keyGrab.key;
if (key != Qt::Key_Escape)
+ {
keys[keyToHighlightSave] = key;
+ emit(KeyDefined(keyToHighlightSave, key));
+ }
keyToHighlight = keyToHighlightSave;
update();
private:
void DrawBorderedText(QPainter &, int, int, QString);
+ signals:
+ void KeyDefined(int, uint32_t);
+
public:
uint32_t keys[21];
{
pad[i] = SDL_JoystickOpen(i);
padName[i] = SDL_JoystickName(i);
- numButtons[i] = numHats[i] = 0;
+ numButtons[i] = numHats[i] = numAxes[i] = 0;
if (pad[i])
{
{
int axisNum = (buttonID & JOY_AXISNUM_MASK) >> 1;
int direction = (buttonID & JOY_AXISDIR_MASK);
+//printf("Checking pad #%u axis %u: axis = %i, direction = %u\n", joystickID, axisNum, axis[joystickID][axisNum], direction);
if (axis[joystickID][axisNum] != 0)
{
- if (axis[joystickID][axisNum] > 16000 && (direction == 0))
+ if ((axis[joystickID][axisNum] > 32000) && (direction == 0))
+//{
+//printf("Axis + hit!\n");
return true;
+//}
- if (axis[joystickID][axisNum] < -16000 && (direction == 1))
+ if ((axis[joystickID][axisNum] < -32000) && (direction == 1))
+//{
+//printf("Axis - hit!\n");
return true;
+//}
}
}
#include "app.h"
#include "about.h"
#include "configdialog.h"
+#include "controllertab.h"
#include "filepicker.h"
#include "gamepad.h"
#include "generaltab.h"
#include "glwidget.h"
#include "help.h"
+#include "profile.h"
#include "settings.h"
#include "version.h"
#include "debug/cpubrowser.h"
{
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]);
+}*/
if (vjs.p2KeyBindings[i] & (JOY_BUTTON | JOY_HAT | JOY_AXIS))
joypad1Buttons[i] = (Gamepad::GetState(1, vjs.p2KeyBindings[i]) ? 0x01 : 0x00);
}
ConfigDialog dlg(this);
//ick.
dlg.generalTab->useUnknownSoftware->setChecked(allowUnknownSoftware);
+ dlg.controllerTab1->profileNum = lastEditedProfile;
+ dlg.controllerTab1->SetupLastUsedProfile();
if (dlg.exec() == false)
return;
bool allowOld = allowUnknownSoftware;
//ick.
allowUnknownSoftware = dlg.generalTab->useUnknownSoftware->isChecked();
+ lastEditedProfile = dlg.controllerTab1->profileNum;
// We rescan the "software" folder if the user either changed the path or
// checked/unchecked the "Allow unknown files" option in the config dialog.
zoomLevel = settings.value("zoom", 2).toInt();
allowUnknownSoftware = settings.value("showUnknownSoftware", false).toBool();
+ lastEditedProfile = settings.value("lastEditedProfile", 0).toInt();
vjs.useJoystick = settings.value("useJoystick", false).toBool();
vjs.joyport = settings.value("joyport", 0).toInt();
vjs.p2KeyBindings[BUTTON_9] = settings.value("p2k_9", Qt::Key_9).toInt();
vjs.p2KeyBindings[BUTTON_d] = settings.value("p2k_pound", Qt::Key_Slash).toInt();
vjs.p2KeyBindings[BUTTON_s] = settings.value("p2k_star", Qt::Key_Asterisk).toInt();
+
+ ReadProfiles(&settings);
}
settings.setValue("zoom", zoomLevel);
settings.setValue("showUnknownSoftware", allowUnknownSoftware);
+ settings.setValue("lastEditedProfile", lastEditedProfile);
settings.setValue("useJoystick", vjs.useJoystick);
settings.setValue("joyport", vjs.joyport);
settings.setValue("p2k_9", vjs.p2KeyBindings[BUTTON_9]);
settings.setValue("p2k_pound", vjs.p2KeyBindings[BUTTON_d]);
settings.setValue("p2k_star", vjs.p2KeyBindings[BUTTON_s]);
+
+ WriteProfiles(&settings);
}
settings.setValue("zoom", zoomLevel);
}
+
private:
QPoint mainWinPosition;
// QSize mainWinSize;
+ int lastEditedProfile;
QMenu * fileMenu;
QMenu * helpMenu;
QMenu * debugMenu;
--- /dev/null
+//
+// profile.cpp - Global profile storage/definition/manipulation
+//
+// by James Hammons
+// (C) 2013 Underground Software
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// Who When What
+// --- ---------- -------------------------------------------------------------
+// JLH 05/01/2013 Created this file
+//
+
+
+#include "profile.h"
+#include <QtGui>
+#include "gamepad.h"
+#include "settings.h"
+
+
+#define MAX_DEVICES 64
+
+
+Profile profile[MAX_PROFILES];
+int controller1Profile;
+int controller2Profile;
+int gamepad1Slot;
+int gamepad2Slot;
+int numberOfProfiles;
+int numberOfDevices;
+char deviceNames[MAX_DEVICES][128];
+
+// This is so that new devices have something reasonable to show for default
+uint32_t defaultMap[21] = {
+ 'S', 'X', 'Z', 'C', '-','7', '4', '1', '0', '8', '5', '2', '=', '9', '6',
+ '3', 'L', 'K', 'J', 'O', 'P'
+};
+
+
+void ReadProfiles(QSettings * set)
+{
+ // Assume no profiles, until we read them
+ numberOfProfiles = 0;
+
+ // There is always at least one device present, and it's the keyboard
+ // (hey, we're PC centric here ;-)
+ numberOfDevices = 1;
+ strcpy(deviceNames[0], "Keyboard");
+
+ // Read the rest of the devices (if any)
+ numberOfDevices += set->beginReadArray("devices");
+
+ for(int i=1; i<numberOfDevices; i++)
+ {
+ set->setArrayIndex(i - 1);
+ strcpy(deviceNames[i], set->value("deviceName").toString().toAscii().data());
+//printf("Read device name: %s\n", deviceNames[i]);
+ }
+
+ set->endArray();
+ numberOfProfiles = set->beginReadArray("profiles");
+//printf("Number of profiles: %u\n", numberOfProfiles);
+
+ for(int i=0; i<numberOfProfiles; i++)
+ {
+ set->setArrayIndex(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();
+
+ 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]);
+ }
+
+ set->endArray();
+
+//printf("Number of profiles found: %u\n", numberOfProfiles);
+ // Set up a reasonable default if no profiles were found
+ if (numberOfProfiles == 0)
+ {
+//printf("Setting up default profile...\n");
+ numberOfProfiles++;
+ profile[0].device = 0; // Keyboard is always device #0
+ strcpy(profile[0].mapName, "Default");
+ profile[0].preferredController = CONTROLLER1;
+
+ for(int i=0; i<21; i++)
+ profile[0].map[i] = defaultMap[i];
+ }
+}
+
+
+void WriteProfiles(QSettings * set)
+{
+#if 0
+ // Don't write anything for now...
+ return;
+#endif
+ // NB: Should only do this if something changed; otherwise, no need to do
+ // this.
+ set->beginWriteArray("devices");
+
+ for(int i=1; i<numberOfDevices; i++)
+ {
+ set->setArrayIndex(i - 1);
+ set->setValue("deviceName", deviceNames[i]);
+ }
+
+ set->endArray();
+ set->beginWriteArray("profiles");
+
+ for(int i=0; i<numberOfProfiles; i++)
+ {
+ set->setArrayIndex(i);
+ set->setValue("deviceNum", profile[i].device);
+ set->setValue("mapName", profile[i].mapName);
+ set->setValue("preferredController", profile[i].preferredController);
+
+ for(int j=0; j<21; j++)
+ {
+ QString string = QString("map%1").arg(j);
+ set->setValue(string, profile[i].map[j]);
+ }
+ }
+
+ set->endArray();
+}
+
+
+int FindDeviceNumberForName(const char * name)
+{
+ for(int i=0; i<numberOfDevices; i++)
+ {
+ if (strcmp(deviceNames[i], name) == 0)
+ return i;
+ }
+
+ if (numberOfDevices == MAX_DEVICES)
+ return -1;
+
+ // If the device wasn't found, it must be new; so add it to the list.
+ int deviceNum = numberOfDevices;
+ deviceNames[deviceNum][127] = 0;
+ strncpy(deviceNames[deviceNum], name, 127);
+ numberOfDevices++;
+
+ return deviceNum;
+}
+
+
+int FindMappingsForDevice(int deviceNum, QComboBox * combo)
+{
+ int found = 0;
+
+ for(int i=0; i<numberOfProfiles; i++)
+ {
+ if (profile[i].device == -1)
+ continue;
+
+ if (profile[i].device == deviceNum)
+ {
+ combo->addItem(profile[i].mapName, i);
+ found++;
+ }
+ }
+
+ // If no mappings were found, create a default one for it
+ if (found == 0)
+ {
+ profile[numberOfProfiles].device = deviceNum;
+ strcpy(profile[numberOfProfiles].mapName, "Default");
+ profile[numberOfProfiles].preferredController = CONTROLLER1;
+
+ for(int i=0; i<21; i++)
+ profile[numberOfProfiles].map[i] = defaultMap[i];
+
+ combo->addItem(profile[numberOfProfiles].mapName, numberOfProfiles);
+ numberOfProfiles++;
+ found++;
+ }
+
+ return found;
+}
+
+
+bool ConnectProfileToController(int profileNum, int controllerNum)
+{
+ if (profile[profileNum].device == -1)
+ return false;
+
+ if (controllerNum < 0 || controllerNum > 2)
+ return false;
+
+ uint32_t * dest = (controllerNum == 0 ? &vjs.p1KeyBindings[0] : &vjs.p2KeyBindings[0]);
+
+ for(int i=0; i<21; i++)
+ dest[i] = profile[profileNum].map[i];
+
+printf("Successfully mapped device '%s' (%s) to controller #%u...\n", deviceNames[profile[profileNum].device], profile[profileNum].mapName, controllerNum);
+ return true;
+}
+
+
+//
+// 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
+//
+/*
+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.
+*/
+void AutoConnectProfiles(void)
+{
+ int controller1Profile = -1;
+ int controller2Profile = -1;
+
+ // Nothing plugged in, we fall back to the default keyboard device profiles
+// if (Gamepad::numJoysticks == 0)
+ {
+// Check for Keyboard device first, if anything else is plugged in it will
+// default to it instead
+ for(int i=0; i<numberOfProfiles; i++)
+ {
+ // Skip profile if it's not Keyboard device
+ if (profile[i].device != 0)
+ continue;
+
+ if (profile[i].preferredController & CONTROLLER1)
+ controller1Profile = i;
+
+ if (profile[i].preferredController & CONTROLLER2)
+ controller2Profile = i;
+ }
+ }
+// else
+ {
+//printf("Number of gamepads found: %u\n", Gamepad::numJoysticks);
+ for(int i=0; i<Gamepad::numJoysticks; i++)
+ {
+ int deviceNum = FindDeviceNumberForName(Gamepad::GetJoystickName(i));
+//printf("Attempting to find valid gamepad profile. Device=%u\n", deviceNum);
+
+ for(int j=0; j<numberOfProfiles; j++)
+ {
+ // Skip profile if it's not discovered device
+ if (profile[j].device != deviceNum)
+ continue;
+
+ if (profile[j].preferredController & CONTROLLER1)
+ controller1Profile = j;
+
+ if (profile[j].preferredController & CONTROLLER2)
+ controller2Profile = j;
+ }
+ }
+ }
+
+ if (controller1Profile != -1)
+ ConnectProfileToController(controller1Profile, 0);
+
+ if (controller2Profile != -1)
+ ConnectProfileToController(controller2Profile, 1);
+}
+
--- /dev/null
+#ifndef __PROFILE_H__
+#define __PROFILE_H__
+
+#include <stdint.h>
+
+class QComboBox;
+class QSettings;
+
+#define MAX_PROFILES 64
+#define CONTROLLER1 0x01
+#define CONTROLLER2 0x02
+
+
+struct Profile
+{
+ int device; // Host device number (-1 == invalid profile)
+ char mapName[32]; // Human readable map name
+ int preferredController; // CONTROLLER1 and/or CONTROLLER2
+ uint32_t map[21]; // Keys/buttons/axes
+};
+
+
+// Function prototypes
+void ReadProfiles(QSettings *);
+void WriteProfiles(QSettings *);
+int FindDeviceNumberForName(const char *);
+int FindMappingsForDevice(int, QComboBox *);
+bool ConnectProfileToController(int, int);
+void AutoConnectProfiles(void);
+
+
+// Exported variables
+extern Profile profile[];
+extern int controller1Profile;
+extern int controller2Profile;
+extern int gamepad1Slot;
+extern int gamepad2Slot;
+//extern int numberOfProfiles;
+
+#endif // __PROFILE_H__
+
// return anajoy_byte_read(offset);
else if (offset >= 0xF14000 && offset <= 0xF14003)
// return JoystickReadByte(offset) | EepromReadByte(offset);
- return JoystickReadWord(offset & 0xFE) | EepromReadByte(offset);
+ {
+ uint16_t value = JoystickReadWord(offset & 0xFE);
+
+ if (offset & 0x01)
+ value &= 0xFF;
+ else
+ value >>= 8;
+
+ // This is wrong, should only have the lowest bit from $F14001
+ return value | EepromReadByte(offset);
+ }
else if (offset >= 0xF14000 && offset <= 0xF1A0FF)
return EepromReadByte(offset);
}*/
else if ((offset >= 0xF14000) && (offset <= 0xF14003))
{
+WriteLog("JERRYWriteByte: Unhandled byte write to JOYSTICK by %s.\n", whoName[who]);
// JoystickWriteByte(offset, data);
JoystickWriteWord(offset & 0xFE, (uint16_t)data);
+// This is wrong, EEPROM is never written here
EepromWriteByte(offset, data);
return;
}
return ~data;
#else
if (!joysticksEnabled)
- return 0xFF;
+ return 0xFFFF;
// Joystick data returns active low for buttons pressed, high for non-
// pressed.
if (offset0 != 0xFF)
{
uint16_t mask[4] = { 0xFEFF, 0xFDFF, 0xFBFF, 0xF7FF };
+// uint16_t mask[4] = { 0xFFFE, 0xFFFD, 0xFFFB, 0xFFF7 };
for(uint8_t i=0; i<4; i++)
data &= (joypad0Buttons[offset0 + i] ? mask[i] : 0xFFFF);
if (offset1 != 0xFF)
{
uint16_t mask[4] = { 0xEFFF, 0xDFFF, 0xBFFF, 0x7FFF };
+// uint16_t mask[4] = { 0xFFEF, 0xFFDF, 0xFFBF, 0xFF7F };
for(uint8_t i=0; i<4; i++)
data &= (joypad1Buttons[offset1 + i] ? mask[i] : 0xFFFF);
}
// return joystick_ram[offset];
- return 0xFF;
+ return 0xFFFF;
}
src/gui/imagedelegate.h \
src/gui/keygrabber.h \
src/gui/mainwin.h \
+ src/gui/profile.h \
src/gui/debug/cpubrowser.h \
src/gui/debug/m68kdasmbrowser.h \
src/gui/debug/memorybrowser.h \
src/gui/imagedelegate.cpp \
src/gui/keygrabber.cpp \
src/gui/mainwin.cpp \
+ src/gui/profile.cpp \
src/gui/debug/cpubrowser.cpp \
src/gui/debug/m68kdasmbrowser.cpp \
src/gui/debug/memorybrowser.cpp \
<context>
<name>AboutWindow</name>
<message id="0">
- <location filename="src/gui/about.cpp" line="25"/>
+ <location filename="src/gui/about.cpp" line="26"/>
+ <location filename="src/gui/controllertab.cpp" line="25"/>
<location filename="src/gui/debug/cpubrowser.cpp" line="27"/>
<location filename="src/gui/debug/m68kdasmbrowser.cpp" line="27"/>
<location filename="src/gui/debug/memorybrowser.cpp" line="24"/>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/about.cpp" line="32"/>
+ <location filename="src/gui/about.cpp" line="33"/>
<source><img src=':/res/vj_title_small.png' style='float: right'><table><tr><td align='right'><b>Version: </b></td><td></source>
<translation type="unfinished"></translation>
</message>
<context>
<name>ControllerTab</name>
<message>
- <location filename="src/gui/controllertab.cpp" line="26"/>
- <source>Define All Keys</source>
+ <location filename="src/gui/controllertab.cpp" line="27"/>
+ <source>Define All Inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="src/gui/controllertab.cpp" line="47"/>
+ <source>Keyboard</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainWin</name>
<message>
- <location filename="src/gui/mainwin.cpp" line="95"/>
+ <location filename="src/gui/mainwin.cpp" line="102"/>
<source>Virtual Jaguar </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="98"/>
+ <location filename="src/gui/mainwin.cpp" line="105"/>
<source> - Alpine Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="118"/>
+ <location filename="src/gui/mainwin.cpp" line="125"/>
<source>E&xit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="121"/>
+ <location filename="src/gui/mainwin.cpp" line="128"/>
<source>Ctrl+q</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="122"/>
+ <location filename="src/gui/mainwin.cpp" line="130"/>
<source>Quit Virtual Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="131"/>
+ <location filename="src/gui/mainwin.cpp" line="139"/>
<source>&Power</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="132"/>
+ <location filename="src/gui/mainwin.cpp" line="140"/>
<source>Powers Jaguar on/off</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="142"/>
+ <location filename="src/gui/mainwin.cpp" line="150"/>
<source>Pause</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="143"/>
+ <location filename="src/gui/mainwin.cpp" line="151"/>
<source>Toggles the running state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="146"/>
+ <location filename="src/gui/mainwin.cpp" line="154"/>
<source>Esc</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="151"/>
+ <location filename="src/gui/mainwin.cpp" line="160"/>
<source>Zoom 100%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="152"/>
+ <location filename="src/gui/mainwin.cpp" line="161"/>
<source>Set window zoom to 100%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="156"/>
+ <location filename="src/gui/mainwin.cpp" line="165"/>
<source>Zoom 200%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="157"/>
+ <location filename="src/gui/mainwin.cpp" line="166"/>
<source>Set window zoom to 200%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="161"/>
+ <location filename="src/gui/mainwin.cpp" line="170"/>
<source>Zoom 300%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="162"/>
+ <location filename="src/gui/mainwin.cpp" line="171"/>
<source>Set window zoom to 300%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="168"/>
+ <location filename="src/gui/mainwin.cpp" line="177"/>
<source>NTSC</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="169"/>
+ <location filename="src/gui/mainwin.cpp" line="178"/>
<source>Sets Jaguar to NTSC mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="173"/>
+ <location filename="src/gui/mainwin.cpp" line="182"/>
<source>PAL</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="174"/>
+ <location filename="src/gui/mainwin.cpp" line="183"/>
<source>Sets Jaguar to PAL mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="178"/>
+ <location filename="src/gui/mainwin.cpp" line="187"/>
<source>Blur</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="179"/>
+ <location filename="src/gui/mainwin.cpp" line="188"/>
<source>Sets OpenGL rendering to GL_NEAREST</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="183"/>
+ <location filename="src/gui/mainwin.cpp" line="192"/>
<source>&About...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="184"/>
+ <location filename="src/gui/mainwin.cpp" line="193"/>
<source>Blatant self-promotion</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="187"/>
+ <location filename="src/gui/mainwin.cpp" line="196"/>
<source>&Contents...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="188"/>
+ <location filename="src/gui/mainwin.cpp" line="197"/>
<source>Help is available, if you should need it</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="191"/>
+ <location filename="src/gui/mainwin.cpp" line="200"/>
<source>&Insert Cartridge...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="192"/>
+ <location filename="src/gui/mainwin.cpp" line="201"/>
<source>Insert a cartridge into Virtual Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="193"/>
+ <location filename="src/gui/mainwin.cpp" line="202"/>
<source>Ctrl+i</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="196"/>
+ <location filename="src/gui/mainwin.cpp" line="206"/>
<source>&Configure</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="197"/>
+ <location filename="src/gui/mainwin.cpp" line="207"/>
<source>Configure options for Virtual Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="198"/>
+ <location filename="src/gui/mainwin.cpp" line="208"/>
<source>Ctrl+c</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="201"/>
+ <location filename="src/gui/mainwin.cpp" line="212"/>
<source>&Use CD Unit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="202"/>
+ <location filename="src/gui/mainwin.cpp" line="213"/>
<source>Use Jaguar Virtual CD unit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="207"/>
+ <location filename="src/gui/mainwin.cpp" line="218"/>
<source>&Frame Advance</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="208"/>
+ <location filename="src/gui/mainwin.cpp" line="219"/>
<source>F7</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="211"/>
+ <location filename="src/gui/mainwin.cpp" line="224"/>
<source>F&ull Screen</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="212"/>
+ <location filename="src/gui/mainwin.cpp" line="225"/>
<source>F9</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="217"/>
+ <location filename="src/gui/mainwin.cpp" line="231"/>
<source>Memory Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="218"/>
+ <location filename="src/gui/mainwin.cpp" line="232"/>
<source>Shows the Jaguar memory browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="222"/>
+ <location filename="src/gui/mainwin.cpp" line="236"/>
<source>CPU Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="223"/>
+ <location filename="src/gui/mainwin.cpp" line="237"/>
<source>Shows the Jaguar CPU browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="227"/>
+ <location filename="src/gui/mainwin.cpp" line="241"/>
<source>OP Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="228"/>
+ <location filename="src/gui/mainwin.cpp" line="242"/>
<source>Shows the Jaguar OP browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="232"/>
+ <location filename="src/gui/mainwin.cpp" line="246"/>
<source>68K Listing Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="233"/>
+ <location filename="src/gui/mainwin.cpp" line="247"/>
<source>Shows the 68K disassembly browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="237"/>
+ <location filename="src/gui/mainwin.cpp" line="251"/>
<source>RISC Listing Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="238"/>
+ <location filename="src/gui/mainwin.cpp" line="252"/>
<source>Shows the RISC disassembly browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="248"/>
+ <location filename="src/gui/mainwin.cpp" line="262"/>
<source>&Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="259"/>
- <location filename="src/gui/mainwin.cpp" line="289"/>
+ <location filename="src/gui/mainwin.cpp" line="273"/>
+ <location filename="src/gui/mainwin.cpp" line="304"/>
<source>&Debug</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="267"/>
+ <location filename="src/gui/mainwin.cpp" line="281"/>
<source>&Help</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="271"/>
+ <location filename="src/gui/mainwin.cpp" line="285"/>
<source>Stuff</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="298"/>
+ <location filename="src/gui/mainwin.cpp" line="322"/>
<source>Ready</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="575"/>
- <location filename="src/gui/mainwin.cpp" line="588"/>
+ <location filename="src/gui/mainwin.cpp" line="617"/>
+ <location filename="src/gui/mainwin.cpp" line="630"/>
<source>Could not load file "%1"!</source>
<translation type="unfinished"></translation>
</message>
<context>
<name>AboutWindow</name>
<message id="0">
- <location filename="src/gui/about.cpp" line="25"/>
+ <location filename="src/gui/about.cpp" line="26"/>
+ <location filename="src/gui/controllertab.cpp" line="25"/>
<location filename="src/gui/debug/cpubrowser.cpp" line="27"/>
<location filename="src/gui/debug/m68kdasmbrowser.cpp" line="27"/>
<location filename="src/gui/debug/memorybrowser.cpp" line="24"/>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/about.cpp" line="32"/>
+ <location filename="src/gui/about.cpp" line="33"/>
<source><img src=':/res/vj_title_small.png' style='float: right'><table><tr><td align='right'><b>Version: </b></td><td></source>
<translation type="unfinished"></translation>
</message>
<context>
<name>ControllerTab</name>
<message>
- <location filename="src/gui/controllertab.cpp" line="26"/>
- <source>Define All Keys</source>
+ <location filename="src/gui/controllertab.cpp" line="27"/>
+ <source>Define All Inputs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="src/gui/controllertab.cpp" line="47"/>
+ <source>Keyboard</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MainWin</name>
<message>
- <location filename="src/gui/mainwin.cpp" line="95"/>
+ <location filename="src/gui/mainwin.cpp" line="102"/>
<source>Virtual Jaguar </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="98"/>
+ <location filename="src/gui/mainwin.cpp" line="105"/>
<source> - Alpine Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="118"/>
+ <location filename="src/gui/mainwin.cpp" line="125"/>
<source>E&xit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="121"/>
+ <location filename="src/gui/mainwin.cpp" line="128"/>
<source>Ctrl+q</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="122"/>
+ <location filename="src/gui/mainwin.cpp" line="130"/>
<source>Quit Virtual Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="131"/>
+ <location filename="src/gui/mainwin.cpp" line="139"/>
<source>&Power</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="132"/>
+ <location filename="src/gui/mainwin.cpp" line="140"/>
<source>Powers Jaguar on/off</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="142"/>
+ <location filename="src/gui/mainwin.cpp" line="150"/>
<source>Pause</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="143"/>
+ <location filename="src/gui/mainwin.cpp" line="151"/>
<source>Toggles the running state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="146"/>
+ <location filename="src/gui/mainwin.cpp" line="154"/>
<source>Esc</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="151"/>
+ <location filename="src/gui/mainwin.cpp" line="160"/>
<source>Zoom 100%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="152"/>
+ <location filename="src/gui/mainwin.cpp" line="161"/>
<source>Set window zoom to 100%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="156"/>
+ <location filename="src/gui/mainwin.cpp" line="165"/>
<source>Zoom 200%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="157"/>
+ <location filename="src/gui/mainwin.cpp" line="166"/>
<source>Set window zoom to 200%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="161"/>
+ <location filename="src/gui/mainwin.cpp" line="170"/>
<source>Zoom 300%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="162"/>
+ <location filename="src/gui/mainwin.cpp" line="171"/>
<source>Set window zoom to 300%</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="168"/>
+ <location filename="src/gui/mainwin.cpp" line="177"/>
<source>NTSC</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="169"/>
+ <location filename="src/gui/mainwin.cpp" line="178"/>
<source>Sets Jaguar to NTSC mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="173"/>
+ <location filename="src/gui/mainwin.cpp" line="182"/>
<source>PAL</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="174"/>
+ <location filename="src/gui/mainwin.cpp" line="183"/>
<source>Sets Jaguar to PAL mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="178"/>
+ <location filename="src/gui/mainwin.cpp" line="187"/>
<source>Blur</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="179"/>
+ <location filename="src/gui/mainwin.cpp" line="188"/>
<source>Sets OpenGL rendering to GL_NEAREST</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="183"/>
+ <location filename="src/gui/mainwin.cpp" line="192"/>
<source>&About...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="184"/>
+ <location filename="src/gui/mainwin.cpp" line="193"/>
<source>Blatant self-promotion</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="187"/>
+ <location filename="src/gui/mainwin.cpp" line="196"/>
<source>&Contents...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="188"/>
+ <location filename="src/gui/mainwin.cpp" line="197"/>
<source>Help is available, if you should need it</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="191"/>
+ <location filename="src/gui/mainwin.cpp" line="200"/>
<source>&Insert Cartridge...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="192"/>
+ <location filename="src/gui/mainwin.cpp" line="201"/>
<source>Insert a cartridge into Virtual Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="193"/>
+ <location filename="src/gui/mainwin.cpp" line="202"/>
<source>Ctrl+i</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="196"/>
+ <location filename="src/gui/mainwin.cpp" line="206"/>
<source>&Configure</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="197"/>
+ <location filename="src/gui/mainwin.cpp" line="207"/>
<source>Configure options for Virtual Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="198"/>
+ <location filename="src/gui/mainwin.cpp" line="208"/>
<source>Ctrl+c</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="201"/>
+ <location filename="src/gui/mainwin.cpp" line="212"/>
<source>&Use CD Unit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="202"/>
+ <location filename="src/gui/mainwin.cpp" line="213"/>
<source>Use Jaguar Virtual CD unit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="207"/>
+ <location filename="src/gui/mainwin.cpp" line="218"/>
<source>&Frame Advance</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="208"/>
+ <location filename="src/gui/mainwin.cpp" line="219"/>
<source>F7</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="211"/>
+ <location filename="src/gui/mainwin.cpp" line="224"/>
<source>F&ull Screen</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="212"/>
+ <location filename="src/gui/mainwin.cpp" line="225"/>
<source>F9</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="217"/>
+ <location filename="src/gui/mainwin.cpp" line="231"/>
<source>Memory Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="218"/>
+ <location filename="src/gui/mainwin.cpp" line="232"/>
<source>Shows the Jaguar memory browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="222"/>
+ <location filename="src/gui/mainwin.cpp" line="236"/>
<source>CPU Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="223"/>
+ <location filename="src/gui/mainwin.cpp" line="237"/>
<source>Shows the Jaguar CPU browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="227"/>
+ <location filename="src/gui/mainwin.cpp" line="241"/>
<source>OP Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="228"/>
+ <location filename="src/gui/mainwin.cpp" line="242"/>
<source>Shows the Jaguar OP browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="232"/>
+ <location filename="src/gui/mainwin.cpp" line="246"/>
<source>68K Listing Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="233"/>
+ <location filename="src/gui/mainwin.cpp" line="247"/>
<source>Shows the 68K disassembly browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="237"/>
+ <location filename="src/gui/mainwin.cpp" line="251"/>
<source>RISC Listing Browser</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="238"/>
+ <location filename="src/gui/mainwin.cpp" line="252"/>
<source>Shows the RISC disassembly browser window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="248"/>
+ <location filename="src/gui/mainwin.cpp" line="262"/>
<source>&Jaguar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="259"/>
- <location filename="src/gui/mainwin.cpp" line="289"/>
+ <location filename="src/gui/mainwin.cpp" line="273"/>
+ <location filename="src/gui/mainwin.cpp" line="304"/>
<source>&Debug</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="267"/>
+ <location filename="src/gui/mainwin.cpp" line="281"/>
<source>&Help</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="271"/>
+ <location filename="src/gui/mainwin.cpp" line="285"/>
<source>Stuff</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="298"/>
+ <location filename="src/gui/mainwin.cpp" line="322"/>
<source>Ready</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="src/gui/mainwin.cpp" line="575"/>
- <location filename="src/gui/mainwin.cpp" line="588"/>
+ <location filename="src/gui/mainwin.cpp" line="617"/>
+ <location filename="src/gui/mainwin.cpp" line="630"/>
<source>Could not load file "%1"!</source>
<translation type="unfinished"></translation>
</message>