dsp_in_exec--;
}
+
//
// DSP opcode handlers
//
#endif
}
+
static void dsp_opcode_jr(void)
{
#ifdef DSP_DIS_JR
#endif
}
+
static void dsp_opcode_add(void)
{
#ifdef DSP_DIS_ADD
#endif
}
+
static void dsp_opcode_addc(void)
{
#ifdef DSP_DIS_ADDC
#endif
}
+
static void dsp_opcode_addq(void)
{
#ifdef DSP_DIS_ADDQ
#endif
}
+
static void dsp_opcode_sub(void)
{
#ifdef DSP_DIS_SUB
#endif
}
+
static void dsp_opcode_subc(void)
{
#ifdef DSP_DIS_SUBC
if (doDSPDis)
WriteLog("%06X: SUBC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", dsp_pc-2, IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM, IMM_2, RN);
#endif
- uint32_t res = RN - RM - dsp_flag_c;
- uint32_t borrow = dsp_flag_c;
- SET_ZNC_SUB(RN - borrow, RM, res);
- RN = res;
+ // This is how the DSP ALU does it--Two's complement with inverted carry
+ uint64_t res = (uint64_t)RN + (uint64_t)(RM ^ 0xFFFFFFFF) + (dsp_flag_c ^ 1);
+ // Carry out of the result is inverted too
+ dsp_flag_c = ((res >> 32) & 0x01) ^ 1;
+ RN = (res & 0xFFFFFFFF);
+ SET_ZN(RN);
#ifdef DSP_DIS_SUBC
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM, IMM_2, RN);
#endif
}
+
static void dsp_opcode_subq(void)
{
#ifdef DSP_DIS_SUBQ
#endif
}
+
static void dsp_opcode_cmp(void)
{
#ifdef DSP_DIS_CMP
#endif
}
+
static void dsp_opcode_cmpq(void)
{
static int32_t sqtable[32] =
#endif
}
+
static void dsp_opcode_and(void)
{
#ifdef DSP_DIS_AND
#endif
}
+
static void dsp_opcode_or(void)
{
#ifdef DSP_DIS_OR
#endif
}
+
static void dsp_opcode_xor(void)
{
#ifdef DSP_DIS_XOR
#endif
}
+
static void dsp_opcode_not(void)
{
#ifdef DSP_DIS_NOT
#endif
}
+
static void dsp_opcode_move_pc(void)
{
RN = dsp_pc - 2;
}
+
static void dsp_opcode_store_r14_indexed(void)
{
#ifdef DSP_DIS_STORE14I
#endif
}
+
static void dsp_opcode_store_r15_indexed(void)
{
#ifdef DSP_DIS_STORE15I
#endif
}
+
static void dsp_opcode_load_r14_ri(void)
{
#ifdef DSP_DIS_LOAD14R
#endif
}
+
static void dsp_opcode_load_r15_ri(void)
{
#ifdef DSP_DIS_LOAD15R
#endif
}
+
static void dsp_opcode_store_r14_ri(void)
{
DSPWriteLong(dsp_reg[14] + RM, RN, DSP);
}
+
static void dsp_opcode_store_r15_ri(void)
{
DSPWriteLong(dsp_reg[15] + RM, RN, DSP);
}
+
static void dsp_opcode_nop(void)
{
#ifdef DSP_DIS_NOP
#endif
}
+
static void dsp_opcode_storeb(void)
{
#ifdef DSP_DIS_STOREB
JaguarWriteByte(RM, RN, DSP);
}
+
static void dsp_opcode_storew(void)
{
#ifdef DSP_DIS_STOREW
#endif
}
+
static void dsp_opcode_store(void)
{
#ifdef DSP_DIS_STORE
#endif
}
+
static void dsp_opcode_loadb(void)
{
#ifdef DSP_DIS_LOADB
#endif
}
+
static void dsp_opcode_loadw(void)
{
#ifdef DSP_DIS_LOADW
#endif
}
+
static void dsp_opcode_load(void)
{
#ifdef DSP_DIS_LOAD
#endif
}
+
static void dsp_opcode_load_r14_indexed(void)
{
#ifdef DSP_DIS_LOAD14I
#endif
}
+
static void dsp_opcode_load_r15_indexed(void)
{
#ifdef DSP_DIS_LOAD15I
#endif
}
+
static void dsp_opcode_movei(void)
{
#ifdef DSP_DIS_MOVEI
#endif
}
+
static void dsp_opcode_moveta(void)
{
#ifdef DSP_DIS_MOVETA
#endif
}
+
static void dsp_opcode_movefa(void)
{
#ifdef DSP_DIS_MOVEFA
#endif
}
+
static void dsp_opcode_move(void)
{
#ifdef DSP_DIS_MOVE
#endif
}
+
static void dsp_opcode_moveq(void)
{
#ifdef DSP_DIS_MOVEQ
#endif
}
+
static void dsp_opcode_resmac(void)
{
#ifdef DSP_DIS_RESMAC
#endif
}
+
static void dsp_opcode_imult(void)
{
#ifdef DSP_DIS_IMULT
#endif
}
+
static void dsp_opcode_mult(void)
{
#ifdef DSP_DIS_MULT
#endif
}
+
static void dsp_opcode_bclr(void)
{
#ifdef DSP_DIS_BCLR
#endif
}
+
static void dsp_opcode_btst(void)
{
#ifdef DSP_DIS_BTST
#endif
}
+
static void dsp_opcode_bset(void)
{
#ifdef DSP_DIS_BSET
#endif
}
+
static void dsp_opcode_subqt(void)
{
#ifdef DSP_DIS_SUBQT
#endif
}
+
static void dsp_opcode_addqt(void)
{
#ifdef DSP_DIS_ADDQT
#endif
}
+
static void dsp_opcode_imacn(void)
{
#ifdef DSP_DIS_IMACN
#endif
}
+
static void dsp_opcode_mtoi(void)
{
RN = (((int32_t)RM >> 8) & 0xFF800000) | (RM & 0x007FFFFF);
SET_ZN(RN);
}
+
static void dsp_opcode_normi(void)
{
uint32_t _Rm = RM;
SET_ZN(RN);
}
+
static void dsp_opcode_mmult(void)
{
int count = dsp_matrix_control&0x0f;
SET_ZN(RN);
}
+
static void dsp_opcode_abs(void)
{
#ifdef DSP_DIS_ABS
#endif
}
+
static void dsp_opcode_div(void)
{
#if 0
#endif
}
+
static void dsp_opcode_imultn(void)
{
#ifdef DSP_DIS_IMULTN
#endif
}
+
static void dsp_opcode_neg(void)
{
#ifdef DSP_DIS_NEG
#endif
}
+
static void dsp_opcode_shlq(void)
{
#ifdef DSP_DIS_SHLQ
#endif
}
+
static void dsp_opcode_shrq(void)
{
#ifdef DSP_DIS_SHRQ
#endif
}
+
static void dsp_opcode_ror(void)
{
#ifdef DSP_DIS_ROR
#endif
}
+
static void dsp_opcode_rorq(void)
{
#ifdef DSP_DIS_RORQ
#endif
}
+
static void dsp_opcode_sha(void)
{
int32_t sRm=(int32_t)RM;
SET_ZN(RN);
}
+
static void dsp_opcode_sharq(void)
{
#ifdef DSP_DIS_SHARQ
#endif
}
+
static void dsp_opcode_sh(void)
{
int32_t sRm=(int32_t)RM;
nop 41362
*/
+
static void gpu_opcode_jump(void)
{
#ifdef GPU_DIS_JUMP
#endif
}
+
static void gpu_opcode_jr(void)
{
#ifdef GPU_DIS_JR
#endif
}
+
static void gpu_opcode_add(void)
{
#ifdef GPU_DIS_ADD
#endif
}
+
static void gpu_opcode_addc(void)
{
#ifdef GPU_DIS_ADDC
#endif
}
+
static void gpu_opcode_addq(void)
{
#ifdef GPU_DIS_ADDQ
#endif
}
+
static void gpu_opcode_addqt(void)
{
#ifdef GPU_DIS_ADDQT
#endif
}
+
static void gpu_opcode_sub(void)
{
#ifdef GPU_DIS_SUB
#endif
}
+
static void gpu_opcode_subc(void)
{
#ifdef GPU_DIS_SUBC
if (doGPUDis)
WriteLog("%06X: SUBC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
- uint32_t res = RN - RM - gpu_flag_c;
- uint32_t borrow = gpu_flag_c;
-// SET_ZNC_SUB(RN, RM, res); //???BUG??? YES!!!
-//No matter how you do it, there is a problem. With below, it's 0-0 with carry,
-//and the one below it it's FFFFFFFF - FFFFFFFF with carry... !!! FIX !!!
-// SET_ZNC_SUB(RN - borrow, RM, res);
- SET_ZNC_SUB(RN, RM + borrow, res);
- RN = res;
+ // This is how the GPU ALU does it--Two's complement with inverted carry
+ uint64_t res = (uint64_t)RN + (uint64_t)(RM ^ 0xFFFFFFFF) + (gpu_flag_c ^ 1);
+ // Carry out of the result is inverted too
+ gpu_flag_c = ((res >> 32) & 0x01) ^ 1;
+ RN = (res & 0xFFFFFFFF);
+ SET_ZN(RN);
#ifdef GPU_DIS_SUBC
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
}
-/*
-N = 5, M = 3, 3 - 5 = -2, C = 1... Or, in our case:
-N = 0, M = 1, 0 - 1 = -1, C = 0!
-#define SET_C_SUB(a,b) (gpu_flag_c = ((uint32_t)(b) > (uint32_t)(a)))
-#define SET_ZN(r) SET_N(r); SET_Z(r)
-#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
-#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
-*/
+
static void gpu_opcode_subq(void)
{
#ifdef GPU_DIS_SUBQ
#endif
}
+
static void gpu_opcode_subqt(void)
{
#ifdef GPU_DIS_SUBQT
#endif
}
+
static void gpu_opcode_cmp(void)
{
#ifdef GPU_DIS_CMP
#endif
}
+
static void gpu_opcode_cmpq(void)
{
static int32_t sqtable[32] =
#endif
}
+
static void gpu_opcode_and(void)
{
#ifdef GPU_DIS_AND
#endif
}
+
static void gpu_opcode_or(void)
{
#ifdef GPU_DIS_OR
#endif
}
+
static void gpu_opcode_xor(void)
{
#ifdef GPU_DIS_XOR
#endif
}
+
static void gpu_opcode_not(void)
{
#ifdef GPU_DIS_NOT
#endif
}
+
static void gpu_opcode_move_pc(void)
{
#ifdef GPU_DIS_MOVEPC
#endif
}
+
static void gpu_opcode_sat8(void)
{
#ifdef GPU_DIS_SAT8
#endif
}
+
static void gpu_opcode_sat16(void)
{
RN = ((int32_t)RN < 0 ? 0 : (RN > 0xFFFF ? 0xFFFF : RN));
SET_ZN(RN);
}
+
static void gpu_opcode_store_r14_indexed(void)
{
#ifdef GPU_DIS_STORE14I
#endif
}
+
static void gpu_opcode_store_r15_indexed(void)
{
#ifdef GPU_DIS_STORE15I
#endif
}
+
static void gpu_opcode_load_r14_ri(void)
{
#ifdef GPU_DIS_LOAD14R
#endif
}
+
static void gpu_opcode_load_r15_ri(void)
{
#ifdef GPU_DIS_LOAD15R
#endif
}
+
static void gpu_opcode_store_r14_ri(void)
{
#ifdef GPU_DIS_STORE14R
#endif
}
+
static void gpu_opcode_store_r15_ri(void)
{
#ifdef GPU_DIS_STORE15R
#endif
}
+
static void gpu_opcode_nop(void)
{
#ifdef GPU_DIS_NOP
#endif
}
+
static void gpu_opcode_pack(void)
{
#ifdef GPU_DIS_PACK
#endif
}
+
static void gpu_opcode_storeb(void)
{
#ifdef GPU_DIS_STOREB
JaguarWriteByte(RM, RN, GPU);
}
+
static void gpu_opcode_storew(void)
{
#ifdef GPU_DIS_STOREW
#endif
}
+
static void gpu_opcode_store(void)
{
#ifdef GPU_DIS_STORE
#endif
}
+
static void gpu_opcode_storep(void)
{
#ifdef GPU_CORRECT_ALIGNMENT
#endif
}
+
static void gpu_opcode_loadw(void)
{
#ifdef GPU_DIS_LOADW
#endif
}
+
// According to the docs, & "Do The Same", this address is long aligned...
// So let's try it:
// And it works!!! Need to fix all instances...
#endif
}
+
static void gpu_opcode_loadp(void)
{
#ifdef GPU_CORRECT_ALIGNMENT
#endif
}
+
static void gpu_opcode_load_r14_indexed(void)
{
#ifdef GPU_DIS_LOAD14I
#endif
}
+
static void gpu_opcode_load_r15_indexed(void)
{
#ifdef GPU_DIS_LOAD15I
#endif
}
+
static void gpu_opcode_movei(void)
{
#ifdef GPU_DIS_MOVEI
#endif
}
+
static void gpu_opcode_moveta(void)
{
#ifdef GPU_DIS_MOVETA
#endif
}
+
static void gpu_opcode_movefa(void)
{
#ifdef GPU_DIS_MOVEFA
#endif
}
+
static void gpu_opcode_move(void)
{
#ifdef GPU_DIS_MOVE
#endif
}
+
static void gpu_opcode_moveq(void)
{
#ifdef GPU_DIS_MOVEQ
#endif
}
+
static void gpu_opcode_resmac(void)
{
RN = gpu_acc;
}
+
static void gpu_opcode_imult(void)
{
#ifdef GPU_DIS_IMULT
#endif
}
+
static void gpu_opcode_mult(void)
{
#ifdef GPU_DIS_MULT
#endif
}
+
static void gpu_opcode_bclr(void)
{
#ifdef GPU_DIS_BCLR
#endif
}
+
static void gpu_opcode_btst(void)
{
#ifdef GPU_DIS_BTST
#endif
}
+
static void gpu_opcode_bset(void)
{
#ifdef GPU_DIS_BSET
#endif
}
+
static void gpu_opcode_imacn(void)
{
uint32_t res = (int16_t)RM * (int16_t)(RN);
gpu_acc += res;
}
+
static void gpu_opcode_mtoi(void)
{
uint32_t _RM = RM;
SET_ZN(res);
}
+
static void gpu_opcode_normi(void)
{
uint32_t _RM = RM;
SET_ZN(res);
}
+
static void gpu_opcode_abs(void)
{
#ifdef GPU_DIS_ABS
#endif
}
+
static void gpu_opcode_div(void) // RN / RM
{
#ifdef GPU_DIS_DIV
#endif
}
+
static void gpu_opcode_imultn(void)
{
uint32_t res = (int32_t)((int16_t)RN * (int16_t)RM);
SET_FLAG_N(res);
}
+
static void gpu_opcode_neg(void)
{
#ifdef GPU_DIS_NEG
#endif
}
+
static void gpu_opcode_shlq(void)
{
#ifdef GPU_DIS_SHLQ
#endif
}
+
static void gpu_opcode_shrq(void)
{
#ifdef GPU_DIS_SHRQ
#endif
}
+
static void gpu_opcode_ror(void)
{
#ifdef GPU_DIS_ROR
#endif
}
+
static void gpu_opcode_rorq(void)
{
#ifdef GPU_DIS_RORQ
#endif
}
+
static void gpu_opcode_sha(void)
{
/* int dreg = jaguar.op & 31;
SET_FLAG_N(_RN);*/
}
+
static void gpu_opcode_sharq(void)
{
#ifdef GPU_DIS_SHARQ
#endif
}
+
static void gpu_opcode_sh(void)
{
#ifdef GPU_DIS_SH
#endif
}
+
//Temporary: Testing only!
//#include "gpu2.cpp"
//#include "gpu3.cpp"
#else
+
// New thread-safe GPU core
int GPUCore(void * data)
}
#endif
+
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"))),
+ mapToList(new QComboBox(this)),
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;
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);
+ right->addWidget(mapToList);
layout->addWidget(controllerWidget);
layout->addWidget(redefineAll, 0, Qt::AlignHCenter);
setLayout(layout);
setFixedWidth(sizeHint().width());
connect(redefineAll, SIGNAL(clicked()), this, SLOT(DefineAllKeys()));
- connect(deviceList, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeDevice(int)));
- connect(mapNameList, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeMapName(int)));
+ connect(deviceList, SIGNAL(activaed(int)), this, SLOT(ChangeDevice(int)));
+ connect(mapNameList, SIGNAL(activated(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()));
+ connect(mapToList, SIGNAL(activated(int)), this, SLOT(UpdateProfileConnections(int)));
// Set up the device combobox (Keyboard is the default, and always
// present)
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++)
{
int deviceNum = FindDeviceNumberForName(Gamepad::GetJoystickName(i));
deviceList->addItem(Gamepad::GetJoystickName(i), deviceNum);
}
+
+ // Set up "Map To" combobox
+ mapToList->addItem(tr("None"), 0);
+ mapToList->addItem(tr("Controller #1"), CONTROLLER1);
+ 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
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
*/
void ControllerTab::SetupLastUsedProfile(void)
{
- int deviceNum = deviceList->findData(profile[profileNum].device);
- int mapNum = mapNameList->findText(profile[profileNum].mapName);
+ int deviceNumIndex = deviceList->findData(profile[profileNum].device);
+ int mapNumIndex = mapNameList->findText(profile[profileNum].mapName);
- if (deviceNum == -1 || mapNum == -1)
- return;
+ 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;
+ }
- ChangeDevice(deviceNum);
- ChangeMapName(mapNum);
+ 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);
+ 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);
+ ChangeMapName(mapNumIndex);
}
}
-void ControllerTab::UpdateProfileConnections(void)
+void ControllerTab::UpdateProfileConnections(int selection)
{
- profile[profileNum].preferredController = (controller1->isChecked() ? CONTROLLER1 : 0) | (controller2->isChecked() ? CONTROLLER2 : 0);
+// 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());
}
void ControllerTab::ChangeDevice(int selection)
{
+//printf("ControllerTab::ChangeDevice\n");
int deviceNum = deviceList->itemData(selection).toInt();
mapNameList->clear();
int numberOfMappings = FindMappingsForDevice(deviceNum, mapNameList);
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);
controllerWidget->keys[i] = profile[profileNum].map[i];
controllerWidget->update();
- controller1->setChecked(profile[profileNum].preferredController & CONTROLLER1);
- controller2->setChecked(profile[profileNum].preferredController & CONTROLLER2);
+// controller1->setChecked(profile[profileNum].preferredController & CONTROLLER1);
+// controller2->setChecked(profile[profileNum].preferredController & CONTROLLER2);
+ mapToList->setCurrentIndex(mapToList->findData(profile[profileNum].preferredController));
}
void ControllerTab::AddMapName(void)
{
-printf("Add new mapping (TODO)...\n");
+ int freeProfile = GetFreeProfile();
+
+ 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;
+ }
+
+ QString text = QInputDialog::getText(this, tr("Add Map Name"), tr("Map name:"), QLineEdit::Normal);
+
+ if (text.isEmpty())
+ return;
+
+ // Add mapping...
+ profileNum = freeProfile;
+ 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;
+
+ for(int i=BUTTON_FIRST; i<BUTTON_LAST; i++)
+ profile[profileNum].map[i] = '*';
+
+ mapNameList->addItem(text, profileNum);
+ mapNameList->setCurrentIndex(mapNameList->count() - 1);
}
void ControllerTab::DeleteMapName(void)
{
-printf("Delete current mapping (TODO)...\n");
+//printf("Delete current mapping (TODO)...\n");
+
+ // hmm, don't need to check this... Because presumably, it's already been checked for.
+// if (mapNameList->count() == 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)
+ return;
+
+ int index = mapNameList->currentIndex();
+ int profileToRemove = profileNum;
+ mapNameList->removeItem(index);
+ DeleteProfile(profileToRemove);
}
protected slots:
void DefineAllKeys(void);
void UpdateProfileKeys(int, uint32_t);
- void UpdateProfileConnections(void);
+ void UpdateProfileConnections(int);
void ChangeDevice(int);
void ChangeMapName(int);
void AddMapName(void);
QLabel * label3;
QComboBox * deviceList;
QComboBox * mapNameList;
+ QComboBox * mapToList;
QCheckBox * controller1;
QCheckBox * controller2;
QPushButton * addMapName;
#include "profile.h"
#include <QtGui>
#include "gamepad.h"
+#include "log.h"
#include "settings.h"
'3', 'L', 'K', 'J', 'O', 'P'
};
+// Function Prototypes
+int ConnectProfileToDevice(int deviceNum);
+int FindProfileForDevice(int deviceNum, int preferred, int * found);
+
void ReadProfiles(QSettings * set)
{
}
+int GetFreeProfile(void)
+{
+ // Check for too many, return -1 if so
+ if (numberOfProfiles == MAX_PROFILES)
+ return -1;
+
+ int profileNum = numberOfProfiles;
+ numberOfProfiles++;
+ return profileNum;
+}
+
+
+void DeleteProfile(int profileToDelete)
+{
+ // Sanity check
+ if (profileToDelete >= numberOfProfiles)
+ return;
+
+ // Trivial case: Profile at end of the array
+ if (profileToDelete == (numberOfProfiles - 1))
+ {
+ numberOfProfiles--;
+ return;
+ }
+
+// memmove(dest, src, bytesToMove);
+ memmove(&profile[profileToDelete], &profile[profileToDelete + 1], ((numberOfProfiles - 1) - profileToDelete) * sizeof(Profile));
+ numberOfProfiles--;
+}
+
+
int FindDeviceNumberForName(const char * name)
{
for(int i=0; i<numberOfDevices; i++)
for(int i=0; i<numberOfProfiles; i++)
{
- if (profile[i].device == -1)
- continue;
+//This should *never* be the case--all profiles in list are *good*
+// if (profile[i].device == -1)
+// continue;
if (profile[i].device == deviceNum)
{
}
+int FindUsableProfiles(QComboBox * combo)
+{
+ int found = 0;
+
+ // Check for device #0 (keyboard) profiles first
+ for(int j=0; j<numberOfProfiles; j++)
+ {
+ // Check for device *and* usable configuration
+ if ((profile[j].device == 0) && (profile[j].preferredController))
+ {
+ combo->addItem(QString("Keyboard::%1").arg(profile[j].mapName), j);
+ found++;
+ }
+ }
+
+ // Check for connected host devices next
+ for(int i=0; i<Gamepad::numJoysticks; i++)
+ {
+ int deviceNum = FindDeviceNumberForName(Gamepad::GetJoystickName(i));
+
+ for(int j=0; j<numberOfProfiles; j++)
+ {
+ if ((profile[j].device == deviceNum) && (profile[j].preferredController))
+ {
+ combo->addItem(QString("%1::%2").arg(Gamepad::GetJoystickName(i)).arg(profile[j].mapName), j);
+ found++;
+ }
+ }
+ }
+
+ return found;
+}
+
+
bool ConnectProfileToController(int profileNum, int controllerNum)
{
if (profile[profileNum].device == -1)
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);
+ WriteLog("PROFILE: Successfully mapped device '%s' (%s) to controller #%u...\n", deviceNames[profile[profileNum].device], profile[profileNum].mapName, controllerNum);
return true;
}
// 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
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).
+
*/
void AutoConnectProfiles(void)
{
+ int foundProfiles[MAX_PROFILES];
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 profiles first, if anything else is plugged in
+ // it will default to it instead.
+#if 0
+ for(int i=0; i<numberOfProfiles; i++)
{
-// 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;
+ // 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 & CONTROLLER1)
+ controller1Profile = i;
- if (profile[i].preferredController & CONTROLLER2)
- controller2Profile = i;
- }
+ if (profile[i].preferredController & CONTROLLER2)
+ controller2Profile = i;
}
-// else
+#else
+ // Connect keyboard devices first...
+ ConnectProfileToDevice(0);
+#endif
+
+ // Next, check for the "don't care" condition of both jaguar controllers
+ // checked for connected host devices
+ for(int i=0; i<Gamepad::numJoysticks; i++)
{
-//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);
+ int deviceNum = FindDeviceNumberForName(Gamepad::GetJoystickName(i));
+ int numberProfilesFound = FindProfileForDevice(deviceNum, CONTROLLER1 | CONTROLLER2, foundProfiles);
- for(int j=0; j<numberOfProfiles; j++)
- {
- // Skip profile if it's not discovered device
- if (profile[j].device != deviceNum)
- continue;
+ // We need to grab pairs here, host device # paired up with profiles
+ // so we can then determine if there are any conflicts that can't be
+ // resolved...
+ }
- if (profile[j].preferredController & CONTROLLER1)
- controller1Profile = j;
+ for(int i=0; i<Gamepad::numJoysticks; i++)
+ {
+ int deviceNum = FindDeviceNumberForName(Gamepad::GetJoystickName(i));
- if (profile[j].preferredController & CONTROLLER2)
- controller2Profile = j;
- }
+#if 0
+ 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;
}
+#else
+ ConnectProfileToDevice(deviceNum);
+#endif
}
if (controller1Profile != -1)
ConnectProfileToController(controller2Profile, 1);
}
+
+int ConnectProfileToDevice(int deviceNum)
+{
+// bool found1 = false;
+// bool found2 = false;
+ int numberFoundForController1 = 0;
+ int numberFoundForController2 = 0;
+
+ for(int i=0; i<numberOfProfiles; i++)
+ {
+ // Skip profile if it's not our device
+ if (profile[i].device != deviceNum)
+ continue;
+
+ if (profile[i].preferredController & CONTROLLER1)
+ {
+ controller1Profile = i;
+// found1 = true;
+ numberFoundForController1++;
+ }
+
+ if (profile[i].preferredController & CONTROLLER2)
+ {
+ controller2Profile = i;
+// found2 = true;
+ numberFoundForController2++;
+ }
+ }
+
+// return found;
+ return numberFoundForController1 + numberFoundForController2;
+}
+
+/*
+int FindProfileForDevice(int deviceNum)
+{
+ for(int i=0; i<numberOfProfiles; i++)
+ {
+ // Skip profile if it's not our device
+ if (profile[i].device != deviceNum)
+ continue;
+
+ return i;
+ }
+
+ return -1;
+}
+*/
+
+int FindProfileForDevice(int deviceNum, int preferred, int * found)
+{
+ int numFound = 0;
+
+ for(int i=0; i<numberOfProfiles; i++)
+ {
+ // Return the profile only if it matches the passed in device and
+ // matches the passed in prefence...
+ if ((profile[i].device == deviceNum) && (profile[i].preferredController == preferred))
+ found[numFound++] = i;
+ }
+
+ return numFound;
+}
+
// Function prototypes
void ReadProfiles(QSettings *);
void WriteProfiles(QSettings *);
+int GetFreeProfile(void);
+void DeleteProfile(int);
int FindDeviceNumberForName(const char *);
int FindMappingsForDevice(int, QComboBox *);
+int FindUsableProfiles(QComboBox *);
bool ConnectProfileToController(int, int);
void AutoConnectProfiles(void);
}
-//uint8_t JoystickReadByte(uint32_t offset)
uint16_t JoystickReadWord(uint32_t offset)
{
// E, D, B, 7
if (offset == 0)
{
-#if 0
- uint8_t data = 0x00;
- int pad0Index = joystick_ram[1] & 0x0F;
- int pad1Index = (joystick_ram[1] >> 4) & 0x0F;
-
-// This is bad--we're assuming that a bit is set in the last case. Might not be so!
-// NOTE: values $7, B, D, & E are only legal ones for pad 0, (rows 3 to 0, in both cases)
-// $E, D, B, & 7 are only legal ones for pad 1
-// So the following code is WRONG! (now fixed! ;-)
-// Also: we should explicitly check for those bit patterns, as other patterns
-// are legal and yield other controllers... !!! FIX !!!
-#warning "!!! Need to explicitly check for the proper bit combinations! !!!"
-
- if (!(pad0Index & 0x01))
- pad0Index = 0;
- else if (!(pad0Index & 0x02))
- pad0Index = 1;
- else if (!(pad0Index & 0x04))
- pad0Index = 2;
- else if (!(pad0Index & 0x08))
- pad0Index = 3;
-
- if (!(pad1Index & 0x01))
- pad1Index = 3;
- else if (!(pad1Index & 0x02))
- pad1Index = 2;
- else if (!(pad1Index & 0x04))
- pad1Index = 1;
- else if (!(pad1Index & 0x08))
- pad1Index = 0;
-
- if (joypad0Buttons[(pad0Index << 2) + 0]) data |= 0x01;
- if (joypad0Buttons[(pad0Index << 2) + 1]) data |= 0x02;
- if (joypad0Buttons[(pad0Index << 2) + 2]) data |= 0x04;
- if (joypad0Buttons[(pad0Index << 2) + 3]) data |= 0x08;
- if (joypad1Buttons[(pad1Index << 2) + 0]) data |= 0x10;
- if (joypad1Buttons[(pad1Index << 2) + 1]) data |= 0x20;
- if (joypad1Buttons[(pad1Index << 2) + 2]) data |= 0x40;
- if (joypad1Buttons[(pad1Index << 2) + 3]) data |= 0x80;
-
- return ~data;
-#else
if (!joysticksEnabled)
return 0xFFFF;
if (offset0 != 0xFF)
{
uint16_t mask[4] = { 0xFEFF, 0xFDFF, 0xFBFF, 0xF7FF };
-// uint16_t mask[4] = { 0xFFFE, 0xFFFD, 0xFFFB, 0xFFF7 };
+//No! 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 };
+//No! uint16_t mask[4] = { 0xFFEF, 0xFFDF, 0xFFBF, 0xFF7F };
for(uint8_t i=0; i<4; i++)
data &= (joypad1Buttons[offset1 + i] ? mask[i] : 0xFFFF);
}
return data;
-#endif
}
-// else if (offset == 3)
else if (offset == 2)
{
// Hardware ID returns NTSC/PAL identification bit here
if (!joysticksEnabled)
return data;
-#if 0
- int pad0Index = joystick_ram[1] & 0x0F;
- int pad1Index = (joystick_ram[1] >> 4) & 0x0F;
-
-//This is more stuff to add to the button reading, as the preceeding only
-//yields 16 buttons...
-#warning "!!! This reports TeamTap incorrectly when PAUSE pressed on controller #1 or #2 !!!"
- if (!(pad0Index & 0x01))
- {
- if (joypad0Buttons[BUTTON_PAUSE])
- data ^= 0x01;
- if (joypad0Buttons[BUTTON_A])
- data ^= 0x02;
- }
- else if (!(pad0Index & 0x02))
- {
- if (joypad0Buttons[BUTTON_B])
- data ^= 0x02;
- }
- else if (!(pad0Index & 0x04))
- {
- if (joypad0Buttons[BUTTON_C])
- data ^= 0x02;
- }
- else if (!(pad0Index & 0x08))
- {
- if (joypad0Buttons[BUTTON_OPTION])
- data ^= 0x02;
- }
- if (!(pad1Index & 0x08))
- {
- if (joypad1Buttons[BUTTON_PAUSE])
- data ^= 0x04;
- if (joypad1Buttons[BUTTON_A])
- data ^= 0x08;
- }
- else if (!(pad1Index & 0x04))
- {
- if (joypad1Buttons[BUTTON_B])
- data ^= 0x08;
- }
- else if (!(pad1Index & 0x02))
- {
- if (joypad1Buttons[BUTTON_C])
- data ^= 0x08;
- }
- else if (!(pad1Index & 0x01))
- {
- if (joypad1Buttons[BUTTON_OPTION])
- data ^= 0x08;
- }
-#else
// Joystick data returns active low for buttons pressed, high for non-
// pressed.
uint8_t offset0 = joypad0Offset[joystick_ram[1] & 0x0F] / 4;
if (mask[offset1][1] != -1)
data &= (joypad1Buttons[mask[offset1][1]] ? 0xFFFB : 0xFFFF);
}
-#endif
return data;
}
-// return joystick_ram[offset];
return 0xFFFF;
}
-#if 0
-uint16_t JoystickReadWord(uint32_t offset)
-{
- return ((uint16_t)JoystickReadByte((offset + 0) & 0x03) << 8) | JoystickReadByte((offset + 1) & 0x03);
-}
-#endif
-
-
-#if 0
-void JoystickWriteByte(uint32_t offset, uint8_t data)
-{
- joystick_ram[offset & 0x03] = data;
-}
-#endif
-
-
void JoystickWriteWord(uint32_t offset, uint16_t data)
{
#warning "No bounds checking done for JoystickWriteWord!"