1 /* Copyright 2012 Theo Berkau <cwx@cyberwarriorx.com>
2
3 This file is part of Yabause.
4
5 Yabause is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 Yabause is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Yabause; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 #include "UICheatSearch.h"
20 #include "UICheatRaw.h"
21 #include "../CommonDialogs.h"
22
UICheatSearch(QWidget * p,QList<cheatsearch_struct> * search,int searchType)23 UICheatSearch::UICheatSearch( QWidget* p, QList <cheatsearch_struct> *search,
24 int searchType) : QDialog( p )
25 {
26 // set up dialog
27 setupUi( this );
28 if ( p && !p->isFullScreen() )
29 setWindowFlags( Qt::Sheet );
30
31 this->search = *search;
32 this->searchType = searchType;
33
34 // If cheat search hasn't been started yet, disable search and add
35 // cheat
36 if (this->search.empty())
37 {
38 pbRestart->setText(QtYabause::translate("Start"));
39 pbSearch->setEnabled( false );
40 pbAddCheat->setEnabled( false );
41 }
42
43 getSearchTypes();
44 listResults();
45
46 // retranslate widgets
47 QtYabause::retranslateWidget( this );
48 }
49
getSearchTypes()50 void UICheatSearch::getSearchTypes()
51 {
52 switch(searchType & 0xC)
53 {
54 case SEARCHEXACT:
55 rbExact->setChecked(true);
56 break;
57 case SEARCHLESSTHAN:
58 rbLessThan->setChecked(true);
59 break;
60 case SEARCHGREATERTHAN:
61 rbGreaterThan->setChecked(true);
62 break;
63 default: break;
64 }
65
66 switch(searchType & 0x70)
67 {
68 case SEARCHUNSIGNED:
69 rbUnsigned->setChecked(true);
70 break;
71 case SEARCHSIGNED:
72 rbSigned->setChecked(true);
73 break;
74 default: break;
75 }
76
77 switch(searchType & 0x3)
78 {
79 case SEARCHBYTE:
80 rb8Bit->setChecked(true);
81 break;
82 case SEARCHWORD:
83 rb16Bit->setChecked(true);
84 break;
85 case SEARCHLONG:
86 rb32Bit->setChecked(true);
87 break;
88 default: break;
89 }
90 }
91
getSearchVariables(int * searchType)92 QList<cheatsearch_struct> * UICheatSearch::getSearchVariables(int *searchType)
93 {
94 *searchType = this->searchType;
95 return &search;
96 }
97
setSearchTypes()98 void UICheatSearch::setSearchTypes()
99 {
100 searchType = 0;
101 if (rbExact->isChecked())
102 searchType |= SEARCHEXACT;
103 else if (rbLessThan->isChecked())
104 searchType |= SEARCHLESSTHAN;
105 else
106 searchType |= SEARCHGREATERTHAN;
107
108 if (rbUnsigned->isChecked())
109 searchType |= SEARCHUNSIGNED;
110 else
111 searchType |= SEARCHSIGNED;
112
113 if (rb8Bit->isChecked())
114 searchType |= SEARCHBYTE;
115 else if (rb16Bit->isChecked())
116 searchType |= SEARCHWORD;
117 else
118 searchType |= SEARCHLONG;
119 }
120
listResults()121 void UICheatSearch::listResults()
122 {
123 u32 i;
124
125 // Clear old info
126 twSearchResults->clear();
127 pbAddCheat->setEnabled(false);
128
129 for (int j = 0; j < search.count(); j++)
130 {
131 if (search[j].results)
132 {
133 // Show results
134 for (i = 0; i < search[j].numResults; i++)
135 {
136 QTreeWidgetItem* it = new QTreeWidgetItem( twSearchResults );
137 QString s;
138 s.sprintf("%08X", search[j].results[i].addr);
139 it->setText( 0, s );
140
141 switch(searchType & 0x3)
142 {
143 case SEARCHBYTE:
144 s.sprintf("%d", MappedMemoryReadByteNocache(MSH2, search[j].results[i].addr));
145 break;
146 case SEARCHWORD:
147 s.sprintf("%d", MappedMemoryReadWordNocache(MSH2, search[j].results[i].addr));
148 break;
149 case SEARCHLONG:
150 s.sprintf("%d", MappedMemoryReadLongNocache(MSH2, search[j].results[i].addr));
151 break;
152 default: break;
153 }
154 it->setText( 1, s );
155 }
156 }
157 }
158 }
159
adjustSearchValueQValidator()160 void UICheatSearch::adjustSearchValueQValidator()
161 {
162 // Figure out range
163 int min, max;
164
165 min = 0;
166
167 if (rb8Bit->isChecked())
168 max = 0xFF;
169 else if (rb16Bit->isChecked())
170 max = 0xFFFF;
171 else
172 max = 0xFFFFFFFF;
173
174 if (rbSigned->isChecked())
175 {
176 min = -(max >> 1) - 1;
177 max >>= 1;
178 }
179 if (rb32Bit->isChecked())
180 {
181 if (rbSigned->isChecked())
182 leSearchValue->setValidator(new QRegExpValidator(QRegExp("-?\\d{1,10}"), leSearchValue));
183 else
184 leSearchValue->setValidator(new QRegExpValidator(QRegExp("\\d{1,10}"), leSearchValue));
185 }
186 else
187 leSearchValue->setValidator(new QIntValidator(min, max, leSearchValue));
188 }
189
on_twSearchResults_itemSelectionChanged()190 void UICheatSearch::on_twSearchResults_itemSelectionChanged()
191 {
192 pbAddCheat->setEnabled( twSearchResults->selectedItems().count() );
193 }
194
on_rbUnsigned_toggled(bool checked)195 void UICheatSearch::on_rbUnsigned_toggled(bool checked)
196 {
197 if (checked)
198 adjustSearchValueQValidator();
199 }
200
on_rbSigned_toggled(bool checked)201 void UICheatSearch::on_rbSigned_toggled(bool checked)
202 {
203 if (checked)
204 adjustSearchValueQValidator();
205 }
206
on_rb8Bit_toggled(bool checked)207 void UICheatSearch::on_rb8Bit_toggled(bool checked)
208 {
209 if (checked)
210 adjustSearchValueQValidator();
211 }
212
on_rb16Bit_toggled(bool checked)213 void UICheatSearch::on_rb16Bit_toggled(bool checked)
214 {
215 if (checked)
216 adjustSearchValueQValidator();
217 }
218
on_rb32Bit_toggled(bool checked)219 void UICheatSearch::on_rb32Bit_toggled(bool checked)
220 {
221 if (checked)
222 adjustSearchValueQValidator();
223 }
224
on_leSearchValue_textChanged(const QString & text)225 void UICheatSearch::on_leSearchValue_textChanged( const QString & text )
226 {
227 pbSearch->setEnabled(!text.isEmpty());
228 }
229
on_pbRestart_clicked()230 void UICheatSearch::on_pbRestart_clicked()
231 {
232 cheatsearch_struct searchTmp;
233
234 // If there were search result, clear them, otherwise adjust GUI
235 if (search.isEmpty())
236 {
237 pbRestart->setText(QtYabause::translate("Restart"));
238 }
239 else
240 {
241 for (int j = 0; j < search.count(); j++)
242 {
243 if (search[j].results)
244 free(search[j].results);
245 }
246 search.clear();
247 }
248
249 // Setup initial values
250 searchTmp.results = NULL;
251
252 searchTmp.startAddr = 0x06000000;
253 searchTmp.endAddr = 0x06100000;
254 searchTmp.numResults = searchTmp.endAddr-searchTmp.startAddr;
255 search.append(searchTmp);
256
257 searchTmp.startAddr = 0x00200000;
258 searchTmp.endAddr = 0x00300000;
259 searchTmp.numResults = searchTmp.endAddr-searchTmp.startAddr;
260 search.append(searchTmp);
261 twSearchResults->clear();
262 }
263
on_pbSearch_clicked()264 void UICheatSearch::on_pbSearch_clicked()
265 {
266 if (LowWram && HighWram)
267 {
268 // Search low wram and high wram areas
269 setSearchTypes();
270
271 for (int i = 0; i < search.count(); i++)
272 {
273 search[i].results = MappedMemorySearch(search[i].startAddr, search[i].endAddr, searchType,
274 leSearchValue->text().toLatin1(), search[i].results, &search[i].numResults);
275 }
276
277 listResults();
278 }
279 }
280
on_pbAddCheat_clicked()281 void UICheatSearch::on_pbAddCheat_clicked()
282 {
283 UICheatRaw d( this );
284 QString s;
285 bool b;
286
287 // Insert current address/values into dialog
288 QTreeWidgetItem *currentItem = twSearchResults->currentItem();
289 d.leAddress->setText(currentItem->text(0));
290 s.sprintf("%X", currentItem->text(1).toUInt());
291 d.leValue->setText(s);
292 d.rbByte->setChecked(rb8Bit->isChecked());
293 d.rbWord->setChecked(rb16Bit->isChecked());
294 d.rbLong->setChecked(rb32Bit->isChecked());
295 if ( d.exec())
296 {
297 if ( CheatAddCode( d.type(), d.leAddress->text().toUInt(&b, 16), d.leValue->text().toUInt(&b, 16) ) != 0 )
298 {
299 CommonDialogs::information( QtYabause::translate( "Unable to add code" ) );
300 return;
301 }
302 else
303 {
304 cheatlist_struct *mCheats;
305 int cheatsCount;
306 mCheats = CheatGetList( &cheatsCount );
307
308 CheatChangeDescriptionByIndex( cheatsCount -1, d.leDescription->text().toLatin1().data() );
309 }
310 }
311 }
312