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