2012-12-16 09:47:51 +00:00
|
|
|
#ifndef QTMAIN_H
|
|
|
|
#define QTMAIN_H
|
2012-12-13 06:38:33 +00:00
|
|
|
|
|
|
|
#include <QTouchEvent>
|
2012-12-23 07:47:52 +00:00
|
|
|
#include <QMouseEvent>
|
|
|
|
#include "gfx_es2/glsl_program.h"
|
2012-12-13 06:38:33 +00:00
|
|
|
#include <QGLWidget>
|
|
|
|
|
2012-12-16 09:47:51 +00:00
|
|
|
#include <QAudioOutput>
|
|
|
|
#include <QAudioFormat>
|
2013-04-06 14:52:09 +00:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 01:51:10 +00:00
|
|
|
#include <QAccelerometer>
|
|
|
|
QTM_USE_NAMESPACE
|
|
|
|
#endif
|
2012-12-13 06:38:33 +00:00
|
|
|
|
|
|
|
#include "base/display.h"
|
|
|
|
#include "base/logging.h"
|
|
|
|
#include "base/timeutil.h"
|
|
|
|
#include "file/zip_read.h"
|
|
|
|
#include "input/input_state.h"
|
|
|
|
#include "base/NativeApp.h"
|
|
|
|
#include "net/resolve.h"
|
|
|
|
#include "display.h"
|
|
|
|
|
2013-01-10 08:06:11 +00:00
|
|
|
// Input
|
|
|
|
const int buttonMappings[18] = {
|
2013-03-12 04:41:26 +00:00
|
|
|
Qt::Key_X + 0x20, //A
|
|
|
|
Qt::Key_S + 0x20, //B
|
|
|
|
Qt::Key_Z + 0x20, //X
|
|
|
|
Qt::Key_A + 0x20, //Y
|
2013-04-07 03:22:29 +00:00
|
|
|
Qt::Key_Q + 0x20, //LBUMPER
|
|
|
|
Qt::Key_W + 0x20, //RBUMPER
|
2013-01-10 08:06:11 +00:00
|
|
|
Qt::Key_1, //START
|
|
|
|
Qt::Key_2, //SELECT
|
|
|
|
Qt::Key_Up, //UP
|
|
|
|
Qt::Key_Down, //DOWN
|
|
|
|
Qt::Key_Left, //LEFT
|
|
|
|
Qt::Key_Right, //RIGHT
|
|
|
|
0, //MENU (event)
|
|
|
|
Qt::Key_Backspace, //BACK
|
2013-03-12 04:41:26 +00:00
|
|
|
Qt::Key_I + 0x20, //JOY UP
|
|
|
|
Qt::Key_K + 0x20, //JOY DOWN
|
|
|
|
Qt::Key_J + 0x20, //JOY LEFT
|
|
|
|
Qt::Key_L + 0x20, //JOY RIGHT
|
2013-01-10 08:06:11 +00:00
|
|
|
};
|
|
|
|
void SimulateGamepad(InputState *input);
|
|
|
|
|
|
|
|
//GUI
|
2012-12-13 06:38:33 +00:00
|
|
|
class MainUI : public QGLWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit MainUI(float scale, QWidget *parent = 0):
|
|
|
|
QGLWidget(parent), dpi_scale(scale)
|
|
|
|
{
|
|
|
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
2013-04-06 14:34:46 +00:00
|
|
|
setAttribute(Qt::WA_LockLandscapeOrientation);
|
|
|
|
pad_buttons = 0;
|
2013-04-06 14:52:09 +00:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 01:51:10 +00:00
|
|
|
acc = new QAccelerometer(this);
|
|
|
|
acc->start();
|
|
|
|
#endif
|
2012-12-13 06:38:33 +00:00
|
|
|
}
|
|
|
|
~MainUI() {
|
2013-04-06 14:52:09 +00:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 01:51:10 +00:00
|
|
|
delete acc;
|
|
|
|
#endif
|
2012-12-13 06:38:33 +00:00
|
|
|
NativeShutdownGraphics();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2013-01-10 08:06:11 +00:00
|
|
|
void resizeEvent(QResizeEvent * e)
|
|
|
|
{
|
|
|
|
pixel_xres = e->size().width();
|
|
|
|
pixel_yres = e->size().height();
|
|
|
|
dp_xres = pixel_xres * dpi_scale;
|
|
|
|
dp_yres = pixel_yres * dpi_scale;
|
|
|
|
}
|
|
|
|
|
2012-12-13 06:38:33 +00:00
|
|
|
bool event(QEvent *e)
|
|
|
|
{
|
|
|
|
QList<QTouchEvent::TouchPoint> touchPoints;
|
|
|
|
switch(e->type())
|
|
|
|
{
|
|
|
|
case QEvent::TouchBegin:
|
|
|
|
case QEvent::TouchUpdate:
|
|
|
|
case QEvent::TouchEnd:
|
|
|
|
touchPoints = static_cast<QTouchEvent *>(e)->touchPoints();
|
|
|
|
foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
|
|
|
|
switch (touchPoint.state()) {
|
|
|
|
case Qt::TouchPointStationary:
|
|
|
|
break;
|
|
|
|
case Qt::TouchPointPressed:
|
|
|
|
case Qt::TouchPointReleased:
|
|
|
|
input_state.pointer_down[touchPoint.id()] = (touchPoint.state() == Qt::TouchPointPressed);
|
|
|
|
case Qt::TouchPointMoved:
|
|
|
|
input_state.pointer_x[touchPoint.id()] = touchPoint.pos().x() * dpi_scale;
|
|
|
|
input_state.pointer_y[touchPoint.id()] = touchPoint.pos().y() * dpi_scale;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-01-14 09:20:28 +00:00
|
|
|
break;
|
2012-12-23 07:47:52 +00:00
|
|
|
case QEvent::MouseButtonPress:
|
|
|
|
case QEvent::MouseButtonRelease:
|
|
|
|
input_state.pointer_down[0] = (e->type() == QEvent::MouseButtonPress);
|
|
|
|
case QEvent::MouseMove:
|
|
|
|
input_state.pointer_x[0] = ((QMouseEvent*)e)->pos().x() * dpi_scale;
|
|
|
|
input_state.pointer_y[0] = ((QMouseEvent*)e)->pos().y() * dpi_scale;
|
|
|
|
break;
|
2013-01-10 08:06:11 +00:00
|
|
|
case QEvent::KeyPress:
|
2013-04-06 14:34:46 +00:00
|
|
|
for (int b = 0; b < 18; b++) {
|
2013-01-10 08:06:11 +00:00
|
|
|
if (((QKeyEvent*)e)->key() == buttonMappings[b])
|
2013-04-06 14:34:46 +00:00
|
|
|
pad_buttons |= (1<<b);
|
2013-01-10 08:06:11 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case QEvent::KeyRelease:
|
2013-04-06 14:34:46 +00:00
|
|
|
for (int b = 0; b < 18; b++) {
|
2013-01-10 08:06:11 +00:00
|
|
|
if (((QKeyEvent*)e)->key() == buttonMappings[b])
|
2013-04-06 14:34:46 +00:00
|
|
|
pad_buttons &= ~(1<<b);
|
2013-01-10 08:06:11 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-12-13 06:38:33 +00:00
|
|
|
default:
|
|
|
|
return QWidget::event(e);
|
|
|
|
}
|
|
|
|
e->accept();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void initializeGL()
|
|
|
|
{
|
2012-12-23 07:47:52 +00:00
|
|
|
#ifndef USING_GLES2
|
|
|
|
glewInit();
|
|
|
|
#endif
|
2012-12-13 06:38:33 +00:00
|
|
|
NativeInitGraphics();
|
|
|
|
}
|
|
|
|
|
|
|
|
void paintGL()
|
|
|
|
{
|
2013-04-06 14:34:46 +00:00
|
|
|
input_state.pad_buttons = pad_buttons;
|
2013-01-10 08:06:11 +00:00
|
|
|
SimulateGamepad(&input_state);
|
2013-03-11 01:51:10 +00:00
|
|
|
updateAccelerometer();
|
2012-12-13 06:38:33 +00:00
|
|
|
UpdateInputState(&input_state);
|
|
|
|
NativeUpdate(input_state);
|
|
|
|
EndInputState(&input_state);
|
|
|
|
NativeRender();
|
2013-02-11 11:35:10 +00:00
|
|
|
time_update();
|
2012-12-13 06:38:33 +00:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2013-03-11 01:51:10 +00:00
|
|
|
void updateAccelerometer()
|
|
|
|
{
|
2013-04-06 14:52:09 +00:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 01:51:10 +00:00
|
|
|
// TODO: Toggle it depending on whether it is enabled
|
|
|
|
QAccelerometerReading *reading = acc->reading();
|
|
|
|
if (reading) {
|
|
|
|
input_state.acc.x = reading->x();
|
|
|
|
input_state.acc.y = reading->y();
|
|
|
|
input_state.acc.z = reading->z();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-12-13 06:38:33 +00:00
|
|
|
private:
|
2013-04-06 14:34:46 +00:00
|
|
|
int pad_buttons;
|
2012-12-13 06:38:33 +00:00
|
|
|
InputState input_state;
|
2013-04-06 14:52:09 +00:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 01:51:10 +00:00
|
|
|
QAccelerometer* acc;
|
|
|
|
#endif
|
2012-12-13 06:38:33 +00:00
|
|
|
float dpi_scale;
|
|
|
|
};
|
|
|
|
|
2013-01-10 08:06:11 +00:00
|
|
|
// Audio
|
2012-12-16 09:47:51 +00:00
|
|
|
#define AUDIO_FREQ 44100
|
|
|
|
#define AUDIO_CHANNELS 2
|
|
|
|
#define AUDIO_SAMPLES 1024
|
|
|
|
#define AUDIO_SAMPLESIZE 16
|
|
|
|
class MainAudio: public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
MainAudio() {
|
|
|
|
QAudioFormat fmt;
|
|
|
|
fmt.setFrequency(AUDIO_FREQ);
|
|
|
|
fmt.setCodec("audio/pcm");
|
|
|
|
fmt.setChannelCount(AUDIO_CHANNELS);
|
|
|
|
fmt.setSampleSize(AUDIO_SAMPLESIZE);
|
|
|
|
fmt.setByteOrder(QAudioFormat::LittleEndian);
|
|
|
|
fmt.setSampleType(QAudioFormat::SignedInt);
|
|
|
|
mixlen = 2*AUDIO_CHANNELS*AUDIO_SAMPLES;
|
|
|
|
mixbuf = (char*)malloc(mixlen);
|
|
|
|
output = new QAudioOutput(fmt);
|
|
|
|
output->setBufferSize(mixlen);
|
|
|
|
feed = output->start();
|
2013-01-31 22:49:37 +00:00
|
|
|
timer = startTimer(1000*AUDIO_SAMPLES / AUDIO_FREQ);
|
2012-12-16 09:47:51 +00:00
|
|
|
}
|
|
|
|
~MainAudio() {
|
2013-01-31 22:49:37 +00:00
|
|
|
killTimer(timer);
|
2013-01-14 09:20:28 +00:00
|
|
|
feed->close();
|
|
|
|
output->stop();
|
2012-12-16 09:47:51 +00:00
|
|
|
delete output;
|
|
|
|
free(mixbuf);
|
|
|
|
}
|
|
|
|
|
2013-01-15 10:45:26 +00:00
|
|
|
protected:
|
|
|
|
void timerEvent(QTimerEvent *) {
|
2012-12-16 09:47:51 +00:00
|
|
|
memset(mixbuf, 0, mixlen);
|
|
|
|
NativeMix((short *)mixbuf, mixlen / 4);
|
|
|
|
feed->write(mixbuf, mixlen);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
QIODevice* feed;
|
|
|
|
QAudioOutput* output;
|
|
|
|
int mixlen;
|
|
|
|
char* mixbuf;
|
2013-01-31 22:49:37 +00:00
|
|
|
int timer;
|
2012-12-16 09:47:51 +00:00
|
|
|
};
|
|
|
|
|
2012-12-13 06:38:33 +00:00
|
|
|
#endif
|
|
|
|
|