/* Copyright 2012 Theo Berkau This file is part of Yabause. Yabause is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Yabause is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Yabause; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "UICheatSearch.h" #include "UICheatRaw.h" #include "../CommonDialogs.h" UICheatSearch::UICheatSearch( QWidget* p, QList *search, int searchType) : QDialog( p ) { // set up dialog setupUi( this ); if ( p && !p->isFullScreen() ) setWindowFlags( Qt::Sheet ); this->search = *search; this->searchType = searchType; // If cheat search hasn't been started yet, disable search and add // cheat if (this->search.empty()) { pbRestart->setText(QtYabause::translate("Start")); pbSearch->setEnabled( false ); pbAddCheat->setEnabled( false ); } getSearchTypes(); listResults(); // retranslate widgets QtYabause::retranslateWidget( this ); } void UICheatSearch::getSearchTypes() { switch(searchType & 0xC) { case SEARCHEXACT: rbExact->setChecked(true); break; case SEARCHLESSTHAN: rbLessThan->setChecked(true); break; case SEARCHGREATERTHAN: rbGreaterThan->setChecked(true); break; default: break; } switch(searchType & 0x70) { case SEARCHUNSIGNED: rbUnsigned->setChecked(true); break; case SEARCHSIGNED: rbSigned->setChecked(true); break; default: break; } switch(searchType & 0x3) { case SEARCHBYTE: rb8Bit->setChecked(true); break; case SEARCHWORD: rb16Bit->setChecked(true); break; case SEARCHLONG: rb32Bit->setChecked(true); break; default: break; } } QList * UICheatSearch::getSearchVariables(int *searchType) { *searchType = this->searchType; return &search; } void UICheatSearch::setSearchTypes() { searchType = 0; if (rbExact->isChecked()) searchType |= SEARCHEXACT; else if (rbLessThan->isChecked()) searchType |= SEARCHLESSTHAN; else searchType |= SEARCHGREATERTHAN; if (rbUnsigned->isChecked()) searchType |= SEARCHUNSIGNED; else searchType |= SEARCHSIGNED; if (rb8Bit->isChecked()) searchType |= SEARCHBYTE; else if (rb16Bit->isChecked()) searchType |= SEARCHWORD; else searchType |= SEARCHLONG; } void UICheatSearch::listResults() { u32 i; // Clear old info twSearchResults->clear(); pbAddCheat->setEnabled(false); for (int j = 0; j < search.count(); j++) { if (search[j].results) { // Show results for (i = 0; i < search[j].numResults; i++) { QTreeWidgetItem* it = new QTreeWidgetItem( twSearchResults ); QString s; s.sprintf("%08X", search[j].results[i].addr); it->setText( 0, s ); switch(searchType & 0x3) { case SEARCHBYTE: s.sprintf("%d", MappedMemoryReadByteNocache(MSH2, search[j].results[i].addr)); break; case SEARCHWORD: s.sprintf("%d", MappedMemoryReadWordNocache(MSH2, search[j].results[i].addr)); break; case SEARCHLONG: s.sprintf("%d", MappedMemoryReadLongNocache(MSH2, search[j].results[i].addr)); break; default: break; } it->setText( 1, s ); } } } } void UICheatSearch::adjustSearchValueQValidator() { // Figure out range int min, max; min = 0; if (rb8Bit->isChecked()) max = 0xFF; else if (rb16Bit->isChecked()) max = 0xFFFF; else max = 0xFFFFFFFF; if (rbSigned->isChecked()) { min = -(max >> 1) - 1; max >>= 1; } if (rb32Bit->isChecked()) { if (rbSigned->isChecked()) leSearchValue->setValidator(new QRegExpValidator(QRegExp("-?\\d{1,10}"), leSearchValue)); else leSearchValue->setValidator(new QRegExpValidator(QRegExp("\\d{1,10}"), leSearchValue)); } else leSearchValue->setValidator(new QIntValidator(min, max, leSearchValue)); } void UICheatSearch::on_twSearchResults_itemSelectionChanged() { pbAddCheat->setEnabled( twSearchResults->selectedItems().count() ); } void UICheatSearch::on_rbUnsigned_toggled(bool checked) { if (checked) adjustSearchValueQValidator(); } void UICheatSearch::on_rbSigned_toggled(bool checked) { if (checked) adjustSearchValueQValidator(); } void UICheatSearch::on_rb8Bit_toggled(bool checked) { if (checked) adjustSearchValueQValidator(); } void UICheatSearch::on_rb16Bit_toggled(bool checked) { if (checked) adjustSearchValueQValidator(); } void UICheatSearch::on_rb32Bit_toggled(bool checked) { if (checked) adjustSearchValueQValidator(); } void UICheatSearch::on_leSearchValue_textChanged( const QString & text ) { pbSearch->setEnabled(!text.isEmpty()); } void UICheatSearch::on_pbRestart_clicked() { cheatsearch_struct searchTmp; // If there were search result, clear them, otherwise adjust GUI if (search.isEmpty()) { pbRestart->setText(QtYabause::translate("Restart")); } else { for (int j = 0; j < search.count(); j++) { if (search[j].results) free(search[j].results); } search.clear(); } // Setup initial values searchTmp.results = NULL; searchTmp.startAddr = 0x06000000; searchTmp.endAddr = 0x06100000; searchTmp.numResults = searchTmp.endAddr-searchTmp.startAddr; search.append(searchTmp); searchTmp.startAddr = 0x00200000; searchTmp.endAddr = 0x00300000; searchTmp.numResults = searchTmp.endAddr-searchTmp.startAddr; search.append(searchTmp); twSearchResults->clear(); } void UICheatSearch::on_pbSearch_clicked() { if (LowWram && HighWram) { // Search low wram and high wram areas setSearchTypes(); for (int i = 0; i < search.count(); i++) { search[i].results = MappedMemorySearch(search[i].startAddr, search[i].endAddr, searchType, leSearchValue->text().toLatin1(), search[i].results, &search[i].numResults); } listResults(); } } void UICheatSearch::on_pbAddCheat_clicked() { UICheatRaw d( this ); QString s; bool b; // Insert current address/values into dialog QTreeWidgetItem *currentItem = twSearchResults->currentItem(); d.leAddress->setText(currentItem->text(0)); s.sprintf("%X", currentItem->text(1).toUInt()); d.leValue->setText(s); d.rbByte->setChecked(rb8Bit->isChecked()); d.rbWord->setChecked(rb16Bit->isChecked()); d.rbLong->setChecked(rb32Bit->isChecked()); if ( d.exec()) { if ( CheatAddCode( d.type(), d.leAddress->text().toUInt(&b, 16), d.leValue->text().toUInt(&b, 16) ) != 0 ) { CommonDialogs::information( QtYabause::translate( "Unable to add code" ) ); return; } else { cheatlist_struct *mCheats; int cheatsCount; mCheats = CheatGetList( &cheatsCount ); CheatChangeDescriptionByIndex( cheatsCount -1, d.leDescription->text().toLatin1().data() ); } } }