1 /* Copyright 2005 Guillaume Duhamel
2 Copyright 2005-2006, 2013 Theo Berkau
3 Copyright 2008 Filipe Azevedo <pasnox@gmail.com>
4
5 This file is part of Yabause.
6
7 Yabause is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Yabause is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Yabause; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 #include "QtYabause.h"
22 #include "ui/UIYabause.h"
23 #include "Settings.h"
24 #include "VolatileSettings.h"
25
26 #ifdef HAVE_PLAY_JIT
27 extern "C"
28 {
29 #include "../sh2_jit.h"
30 }
31 #endif
32
33 #include <QApplication>
34 #include <QLabel>
35 #include <QGroupBox>
36 #include <QTreeWidget>
37 #include <QPointer>
38 #include <QDir>
39
40 // cores
41
42 #ifdef Q_OS_WIN
43 extern CDInterface SPTICD;
44 #endif
45
46 extern "C" {
47 M68K_struct * M68KCoreList[] = {
48 &M68KDummy,
49 #ifdef HAVE_MUSASHI
50 &M68KMusashi,
51 #endif
52 #ifdef HAVE_C68K
53 &M68KC68K,
54 #endif
55 NULL
56 };
57
58 SH2Interface_struct *SH2CoreList[] = {
59 &SH2Interpreter,
60 &SH2DebugInterpreter,
61 #ifdef SH2_DYNAREC
62 &SH2Dynarec,
63 #endif
64 #ifdef HAVE_PLAY_JIT
65 &SH2Jit,
66 #endif
67 NULL
68 };
69
70 PerInterface_struct *PERCoreList[] = {
71 &PERDummy,
72 &PERQT,
73 #ifdef HAVE_LIBSDL
74 &PERSDLJoy,
75 #endif
76 #ifdef __APPLE__
77 &PERMacJoy,
78 #endif
79 #ifdef HAVE_DIRECTINPUT
80 &PERDIRECTX,
81 #endif
82 #ifdef ARCH_IS_LINUX
83 &PERLinuxJoy,
84 #endif
85 NULL
86 };
87
88 CDInterface *CDCoreList[] = {
89 &DummyCD,
90 &ISOCD,
91 #ifndef UNKNOWN_ARCH
92 &ArchCD,
93 #endif
94 NULL
95 };
96
97 SoundInterface_struct *SNDCoreList[] = {
98 &SNDDummy,
99 #ifdef HAVE_LIBSDL
100 &SNDSDL,
101 #endif
102 #ifdef HAVE_LIBAL
103 &SNDAL,
104 #endif
105 #ifdef HAVE_DIRECTSOUND
106 &SNDDIRECTX,
107 #endif
108 #ifdef ARCH_IS_MACOSX
109 &SNDMac,
110 #endif
111 NULL
112 };
113
114 VideoInterface_struct *VIDCoreList[] = {
115 &VIDDummy,
116 #ifdef HAVE_LIBGL
117 &VIDOGL,
118 #endif
119 &VIDSoft,
120 NULL
121 };
122
123 #ifdef YAB_PORT_OSD
124 OSD_struct *OSDCoreList[] = {
125 &OSDDummy,
126 #ifdef HAVE_LIBGLUT
127 &OSDGlut,
128 #endif
129 &OSDSoft,
130 NULL
131 };
132 #endif
133
134 }
135
136 // main window
137 QPointer<UIYabause> mUIYabause = 0;
138 // settings object
139 QPointer<Settings> mSettings = 0;
140 QPointer<VolatileSettings> mVolatileSettings = 0;
141 // ports padbits
142 QMap<uint, PerPad_struct*> mPort1PadsBits;
143 QMap<uint, PerPad_struct*> mPort2PadsBits;
144 QMap<uint, PerGun_struct*> mPort1GunBits;
145 QMap<uint, PerGun_struct*> mPort2GunBits;
146 QMap<uint, PerMouse_struct*> mPort1MouseBits;
147 QMap<uint, PerMouse_struct*> mPort2MouseBits;
148 QMap<uint, PerAnalog_struct*> mPort1AnalogBits;
149 QMap<uint, PerAnalog_struct*> mPort2AnalogBits;
150
151 extern "C"
152 {
YuiErrorMsg(const char * string)153 void YuiErrorMsg(const char *string)
154 { QtYabause::mainWindow()->appendLog( string ); }
155
YuiSwapBuffers()156 void YuiSwapBuffers()
157 { QtYabause::mainWindow()->swapBuffers(); }
158
159 #if defined(HAVE_DIRECTINPUT) || defined(HAVE_DIRECTSOUND)
DXGetWindow()160 HWND DXGetWindow()
161 {
162 return (HWND)mUIYabause->winId();
163 }
164 #endif
165 }
166
mainWindow(bool create)167 UIYabause* QtYabause::mainWindow( bool create )
168 {
169 if ( !mUIYabause && create )
170 mUIYabause = new UIYabause;
171 return mUIYabause;
172 }
173
settings(bool create)174 Settings* QtYabause::settings( bool create )
175 {
176 if ( !mSettings && create )
177 mSettings = new Settings();
178 return mSettings;
179 }
180
volatileSettings(bool create)181 VolatileSettings* QtYabause::volatileSettings( bool create )
182 {
183 if ( !mVolatileSettings && create )
184 mVolatileSettings = new VolatileSettings();
185 return mVolatileSettings;
186 }
187
getTranslationList()188 QList <translation_struct> QtYabause::getTranslationList()
189 {
190 QList <translation_struct> translations;
191 #ifdef HAVE_LIBMINI18N
192 QDir transDir=QDir(YTSDIR, "*.yts");
193
194 foreach(QString file, transDir.entryList())
195 {
196 if (!file.endsWith(".yts"))
197 continue;
198 translation_struct trans;
199 trans.file = QString(YTSDIR) + QString("/") + file;
200
201 // Let's get it down just to language code
202 QStringList string = file.remove(".yts").split("_");
203 if (file.startsWith("yabause_"))
204 string.removeFirst();
205 QString localeStr = string.join("_");
206 // Find the locale
207 QLocale locale = QLocale(localeStr);
208 // Now we should be good for the language name
209 #if QT_VERSION < 0x040800
210 trans.name = locale.name();
211 #else
212 trans.name = locale.nativeLanguageName();
213 #endif
214 translations.append(trans);
215 }
216 #endif
217 return translations;
218 }
219
setTranslationFile()220 int QtYabause::setTranslationFile()
221 {
222 #ifdef HAVE_LIBMINI18N
223 const QString s = settings()->value( "General/Translation" ).toString();
224 if ( ! s.isEmpty() )
225 {
226 if (s == "#") return 0; // magic value for "no translation" (aka english)
227
228 const char* filePath = qstrdup( s.toLocal8Bit().constData() );
229 if ( mini18n_set_locale( filePath ) == 0 )
230 {
231 QtYabause::retranslateApplication();
232 if ( logTranslation() != 0 )
233 qWarning( "Can't log translation !" );
234 return 0;
235 }
236 }
237
238 if ( mini18n_set_domain( YTSDIR ) == 0 )
239 {
240 QtYabause::retranslateApplication();
241 if ( logTranslation() != 0 )
242 qWarning( "Can't log translation !" );
243 return 0;
244 }
245 #endif
246 return -1;
247 }
248
logTranslation()249 int QtYabause::logTranslation()
250 {
251 #ifdef HAVE_LIBMINI18N
252 if (settings()->value( "General/LogUntranslated", false ).toBool())
253 {
254 const QString s = settings()->value( "General/Translation" ).toString().replace( ".yts", "_log.yts" );
255 if ( s.isEmpty() )
256 return 0;
257 const char* filePath = qstrdup( s.toLocal8Bit().constData() );
258 return mini18n_set_log( filePath );
259 }
260 #endif
261 return 0;
262 }
263
closeTranslation()264 void QtYabause::closeTranslation()
265 {
266 #ifdef HAVE_LIBMINI18N
267 mini18n_close();
268 #endif
269 }
270
translate(const QString & string)271 QString QtYabause::translate( const QString& string )
272 {
273 #ifdef HAVE_LIBMINI18N
274 return QString::fromUtf8( _( string.toUtf8().constData() ) );
275 #else
276 return string;
277 #endif
278 }
279
retranslateWidgetOnly(QWidget * widget)280 void QtYabause::retranslateWidgetOnly( QWidget* widget )
281 {
282 #ifdef HAVE_LIBMINI18N
283 if ( !widget )
284 return;
285 widget->setAccessibleDescription( translate( widget->accessibleDescription() ) );
286 widget->setAccessibleName( translate( widget->accessibleName() ) );
287 widget->setStatusTip( translate( widget->statusTip() ) );
288 widget->setStyleSheet( translate( widget->styleSheet() ) );
289 widget->setToolTip( translate( widget->toolTip() ) );
290 widget->setWhatsThis( translate( widget->whatsThis() ) );
291 widget->setWindowIconText( translate( widget->windowIconText() ) );
292 widget->setWindowTitle( translate( widget->windowTitle() ) );
293 #endif
294 }
295
retranslateWidget(QWidget * widget)296 void QtYabause::retranslateWidget( QWidget* widget )
297 {
298 #ifdef HAVE_LIBMINI18N
299 if ( !widget )
300 return;
301 // translate all widget based members
302 retranslateWidgetOnly( widget );
303 // get class name
304 const QString className = widget->metaObject()->className();
305 if ( className == "QWidget" )
306 return;
307 else if ( className == "QLabel" )
308 {
309 QLabel* l = qobject_cast<QLabel*>( widget );
310 l->setText( translate( l->text() ) );
311 }
312 else if ( className == "QAbstractButton" || widget->inherits( "QAbstractButton" ) )
313 {
314 QAbstractButton* ab = qobject_cast<QAbstractButton*>( widget );
315 ab->setText( translate( ab->text() ) );
316 }
317 else if ( className == "QGroupBox" )
318 {
319 QGroupBox* gb = qobject_cast<QGroupBox*>( widget );
320 gb->setTitle( translate( gb->title() ) );
321 }
322 else if ( className == "QMenu" || className == "QMenuBar" )
323 {
324 QList<QMenu*> menus;
325 if ( className == "QMenuBar" )
326 menus = qobject_cast<QMenuBar*>( widget )->findChildren<QMenu*>();
327 else
328 menus << qobject_cast<QMenu*>( widget );
329 foreach ( QMenu* m, menus )
330 {
331 m->setTitle( translate( m->title() ) );
332 // retranslate menu actions
333 foreach ( QAction* a, m->actions() )
334 {
335 a->setIconText( translate( a->iconText() ) );
336 a->setStatusTip( translate( a->statusTip() ) );
337 a->setText( translate( a->text() ) );
338 a->setToolTip( translate( a->toolTip() ) );
339 a->setWhatsThis( translate( a->whatsThis() ) );
340 }
341 }
342 }
343 else if ( className == "QTreeWidget" )
344 {
345 QTreeWidget* tw = qobject_cast<QTreeWidget*>( widget );
346 QTreeWidgetItem* twi = tw->headerItem();
347 for ( int i = 0; i < twi->columnCount(); i++ )
348 {
349 twi->setStatusTip( i, translate( twi->statusTip( i ) ) );
350 twi->setText( i, translate( twi->text( i ) ) );
351 twi->setToolTip( i, translate( twi->toolTip( i ) ) );
352 twi->setWhatsThis( i, translate( twi->whatsThis( i ) ) );
353 }
354 }
355 else if ( className == "QTabWidget" )
356 {
357 QTabWidget* tw = qobject_cast<QTabWidget*>( widget );
358 for ( int i = 0; i < tw->count(); i++ )
359 tw->setTabText( i, translate( tw->tabText( i ) ) );
360 }
361 // translate children
362 foreach ( QWidget* w, widget->findChildren<QWidget*>() )
363 retranslateWidget( w );
364 #endif
365 }
366
retranslateApplication()367 void QtYabause::retranslateApplication()
368 {
369 #ifdef HAVE_LIBMINI18N
370 foreach ( QWidget* widget, QApplication::allWidgets() )
371 retranslateWidget( widget );
372 #endif
373 }
374
getCurrentCdSerial()375 const char* QtYabause::getCurrentCdSerial()
376 { return cdip ? cdip->itemnum : 0; }
377
getM68KCore(int id)378 M68K_struct* QtYabause::getM68KCore( int id )
379 {
380 for ( int i = 0; M68KCoreList[i] != NULL; i++ )
381 if ( M68KCoreList[i]->id == id )
382 return M68KCoreList[i];
383 return 0;
384 }
385
getSH2Core(int id)386 SH2Interface_struct* QtYabause::getSH2Core( int id )
387 {
388 for ( int i = 0; SH2CoreList[i] != NULL; i++ )
389 if ( SH2CoreList[i]->id == id )
390 return SH2CoreList[i];
391 return 0;
392 }
393
getPERCore(int id)394 PerInterface_struct* QtYabause::getPERCore( int id )
395 {
396 for ( int i = 0; PERCoreList[i] != NULL; i++ )
397 if ( PERCoreList[i]->id == id )
398 return PERCoreList[i];
399 return 0;
400 }
401
getCDCore(int id)402 CDInterface* QtYabause::getCDCore( int id )
403 {
404 for ( int i = 0; CDCoreList[i] != NULL; i++ )
405 if ( CDCoreList[i]->id == id )
406 return CDCoreList[i];
407 return 0;
408 }
409
getSNDCore(int id)410 SoundInterface_struct* QtYabause::getSNDCore( int id )
411 {
412 for ( int i = 0; SNDCoreList[i] != NULL; i++ )
413 if ( SNDCoreList[i]->id == id )
414 return SNDCoreList[i];
415 return 0;
416 }
417
getVDICore(int id)418 VideoInterface_struct* QtYabause::getVDICore( int id )
419 {
420 for ( int i = 0; VIDCoreList[i] != NULL; i++ )
421 if ( VIDCoreList[i]->id == id )
422 return VIDCoreList[i];
423 return 0;
424 }
425
defaultCDCore()426 CDInterface QtYabause::defaultCDCore()
427 {
428 #ifndef UNKNOWN_ARCH
429 return ArchCD;
430 #else
431 return DummyCD;
432 #endif
433 }
434
defaultSNDCore()435 SoundInterface_struct QtYabause::defaultSNDCore()
436 {
437 #ifdef HAVE_LIBSDL
438 return SNDSDL;
439 #else
440 return SNDDummy;
441 #endif
442 }
443
defaultVIDCore()444 VideoInterface_struct QtYabause::defaultVIDCore()
445 {
446 return VIDSoft;
447 }
448
defaultOSDCore()449 OSD_struct QtYabause::defaultOSDCore()
450 {
451 return OSDSoft;
452 }
453
defaultPERCore()454 PerInterface_struct QtYabause::defaultPERCore()
455 {
456 #ifdef HAVE_LIBSDL
457 return PERSDLJoy;
458 #elif defined (HAVE_DIRECTINPUT)
459 return PERDIRECTX;
460 #else
461 return PERQT;
462 #endif
463 }
464
default68kCore()465 M68K_struct QtYabause::default68kCore()
466 {
467 #ifdef HAVE_MUSASHI
468 return M68KMusashi;
469 #elif HAVE_C68K
470 return M68KC68K;
471 #else
472 return M68KDummy;
473 #endif
474 }
475
defaultSH2Core()476 SH2Interface_struct QtYabause::defaultSH2Core()
477 {
478 return SH2Interpreter;
479 }
480
portPadsBits(uint portNumber)481 QMap<uint, PerPad_struct*>* QtYabause::portPadsBits( uint portNumber )
482 {
483 switch ( portNumber )
484 {
485 case 1:
486 return &mPort1PadsBits;
487 break;
488 case 2:
489 return &mPort2PadsBits;
490 break;
491 default:
492 return 0;
493 break;
494 }
495 }
496
clearPadsBits()497 void QtYabause::clearPadsBits()
498 {
499 mPort1PadsBits.clear();
500 mPort2PadsBits.clear();
501 }
502
portAnalogBits(uint portNumber)503 QMap<uint, PerAnalog_struct*>* QtYabause::portAnalogBits( uint portNumber )
504 {
505 switch ( portNumber )
506 {
507 case 1:
508 return &mPort1AnalogBits;
509 break;
510 case 2:
511 return &mPort2AnalogBits;
512 break;
513 default:
514 return 0;
515 break;
516 }
517 }
518
clear3DAnalogBits()519 void QtYabause::clear3DAnalogBits()
520 {
521 mPort1AnalogBits.clear();
522 mPort2AnalogBits.clear();
523 }
524
portGunBits(uint portNumber)525 QMap<uint, PerGun_struct*>* QtYabause::portGunBits( uint portNumber )
526 {
527 switch ( portNumber )
528 {
529 case 1:
530 return &mPort1GunBits;
531 break;
532 case 2:
533 return &mPort2GunBits;
534 break;
535 default:
536 return 0;
537 break;
538 }
539 }
540
clearGunBits()541 void QtYabause::clearGunBits()
542 {
543 mPort1GunBits.clear();
544 mPort2GunBits.clear();
545 }
546
portMouseBits(uint portNumber)547 QMap<uint, PerMouse_struct*>* QtYabause::portMouseBits( uint portNumber )
548 {
549 switch ( portNumber )
550 {
551 case 1:
552 return &mPort1MouseBits;
553 break;
554 case 2:
555 return &mPort2MouseBits;
556 break;
557 default:
558 return 0;
559 break;
560 }
561 }
562
clearMouseBits()563 void QtYabause::clearMouseBits()
564 {
565 mPort1MouseBits.clear();
566 mPort2MouseBits.clear();
567 }
568