2012-12-16 19:47:51 +10:00
|
|
|
#ifndef QTMAIN_H
|
|
|
|
#define QTMAIN_H
|
2012-12-13 16:38:33 +10:00
|
|
|
|
|
|
|
#include <QTouchEvent>
|
2012-12-23 17:47:52 +10:00
|
|
|
#include <QMouseEvent>
|
|
|
|
#include "gfx_es2/glsl_program.h"
|
2012-12-13 16:38:33 +10:00
|
|
|
#include <QGLWidget>
|
|
|
|
|
2012-12-16 19:47:51 +10:00
|
|
|
#include <QAudioOutput>
|
|
|
|
#include <QAudioFormat>
|
2013-04-07 00:52:09 +10:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 11:51:10 +10:00
|
|
|
#include <QAccelerometer>
|
|
|
|
QTM_USE_NAMESPACE
|
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
|
|
|
|
#include "base/display.h"
|
|
|
|
#include "base/logging.h"
|
|
|
|
#include "base/timeutil.h"
|
|
|
|
#include "file/zip_read.h"
|
|
|
|
#include "input/input_state.h"
|
2013-07-08 10:04:20 +10:00
|
|
|
#include "input/keycodes.h"
|
2012-12-13 16:38:33 +10:00
|
|
|
#include "base/NativeApp.h"
|
|
|
|
#include "net/resolve.h"
|
|
|
|
#include "display.h"
|
2013-08-05 20:08:38 +10:00
|
|
|
#include "base/NKCodeFromQt.h"
|
2012-12-13 16:38:33 +10:00
|
|
|
|
2013-01-10 18:06:11 +10:00
|
|
|
// Input
|
|
|
|
void SimulateGamepad(InputState *input);
|
|
|
|
|
|
|
|
//GUI
|
2012-12-13 16:38:33 +10:00
|
|
|
class MainUI : public QGLWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2013-08-20 20:30:03 +10:00
|
|
|
explicit MainUI(QWidget *parent = 0):
|
|
|
|
QGLWidget(parent)
|
2012-12-13 16:38:33 +10:00
|
|
|
{
|
|
|
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
2013-10-19 05:21:44 +10:00
|
|
|
#if QT_VERSION < 0x50000
|
2013-04-07 00:34:46 +10:00
|
|
|
setAttribute(Qt::WA_LockLandscapeOrientation);
|
2013-10-19 05:21:44 +10:00
|
|
|
#endif
|
2013-04-07 00:52:09 +10:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 11:51:10 +10:00
|
|
|
acc = new QAccelerometer(this);
|
|
|
|
acc->start();
|
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
}
|
|
|
|
~MainUI() {
|
2013-04-07 00:52:09 +10:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 11:51:10 +10:00
|
|
|
delete acc;
|
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
NativeShutdownGraphics();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2013-01-10 18:06:11 +10:00
|
|
|
void resizeEvent(QResizeEvent * e)
|
|
|
|
{
|
|
|
|
pixel_xres = e->size().width();
|
|
|
|
pixel_yres = e->size().height();
|
2013-08-20 20:30:03 +10:00
|
|
|
dp_xres = pixel_xres * g_dpi_scale;
|
|
|
|
dp_yres = pixel_yres * g_dpi_scale;
|
2013-01-10 18:06:11 +10:00
|
|
|
}
|
|
|
|
|
2012-12-13 16:38:33 +10:00
|
|
|
bool event(QEvent *e)
|
|
|
|
{
|
2013-07-25 14:28:18 +10:00
|
|
|
TouchInput input;
|
2012-12-13 16:38:33 +10:00
|
|
|
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);
|
2013-08-20 20:30:03 +10:00
|
|
|
input_state.pointer_x[touchPoint.id()] = touchPoint.pos().x() * g_dpi_scale;
|
|
|
|
input_state.pointer_y[touchPoint.id()] = touchPoint.pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
|
2013-08-20 20:30:03 +10:00
|
|
|
input.x = touchPoint.pos().x() * g_dpi_scale;
|
|
|
|
input.y = touchPoint.pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
input.flags = (touchPoint.state() == Qt::TouchPointPressed) ? TOUCH_DOWN : TOUCH_UP;
|
|
|
|
input.id = touchPoint.id();
|
|
|
|
NativeTouch(input);
|
|
|
|
break;
|
2012-12-13 16:38:33 +10:00
|
|
|
case Qt::TouchPointMoved:
|
2013-08-20 20:30:03 +10:00
|
|
|
input_state.pointer_x[touchPoint.id()] = touchPoint.pos().x() * g_dpi_scale;
|
|
|
|
input_state.pointer_y[touchPoint.id()] = touchPoint.pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
|
2013-08-20 20:30:03 +10:00
|
|
|
input.x = touchPoint.pos().x() * g_dpi_scale;
|
|
|
|
input.y = touchPoint.pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
input.flags = TOUCH_MOVE;
|
|
|
|
input.id = touchPoint.id();
|
|
|
|
NativeTouch(input);
|
2012-12-13 16:38:33 +10:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-01-14 19:20:28 +10:00
|
|
|
break;
|
2012-12-23 17:47:52 +10:00
|
|
|
case QEvent::MouseButtonPress:
|
|
|
|
case QEvent::MouseButtonRelease:
|
|
|
|
input_state.pointer_down[0] = (e->type() == QEvent::MouseButtonPress);
|
2013-08-20 20:30:03 +10:00
|
|
|
input_state.pointer_x[0] = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
|
|
|
input_state.pointer_y[0] = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
|
2013-08-20 20:30:03 +10:00
|
|
|
input.x = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
|
|
|
input.y = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
input.flags = (e->type() == QEvent::MouseButtonPress) ? TOUCH_DOWN : TOUCH_UP;
|
|
|
|
input.id = 0;
|
|
|
|
NativeTouch(input);
|
|
|
|
break;
|
2012-12-23 17:47:52 +10:00
|
|
|
case QEvent::MouseMove:
|
2013-08-20 20:30:03 +10:00
|
|
|
input_state.pointer_x[0] = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
|
|
|
input_state.pointer_y[0] = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
|
2013-08-20 20:30:03 +10:00
|
|
|
input.x = ((QMouseEvent*)e)->pos().x() * g_dpi_scale;
|
|
|
|
input.y = ((QMouseEvent*)e)->pos().y() * g_dpi_scale;
|
2013-07-25 14:28:18 +10:00
|
|
|
input.flags = TOUCH_MOVE;
|
|
|
|
input.id = 0;
|
|
|
|
NativeTouch(input);
|
2012-12-23 17:47:52 +10:00
|
|
|
break;
|
2013-01-10 18:06:11 +10:00
|
|
|
case QEvent::KeyPress:
|
2013-08-05 20:08:38 +10:00
|
|
|
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_DOWN));
|
2013-01-10 18:06:11 +10:00
|
|
|
break;
|
|
|
|
case QEvent::KeyRelease:
|
2013-08-05 20:08:38 +10:00
|
|
|
NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_UP));
|
2013-01-10 18:06:11 +10:00
|
|
|
break;
|
2012-12-13 16:38:33 +10:00
|
|
|
default:
|
|
|
|
return QWidget::event(e);
|
|
|
|
}
|
|
|
|
e->accept();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void initializeGL()
|
|
|
|
{
|
2012-12-23 17:47:52 +10:00
|
|
|
#ifndef USING_GLES2
|
|
|
|
glewInit();
|
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
NativeInitGraphics();
|
|
|
|
}
|
|
|
|
|
|
|
|
void paintGL()
|
|
|
|
{
|
2013-03-11 11:51:10 +10:00
|
|
|
updateAccelerometer();
|
2012-12-13 16:38:33 +10:00
|
|
|
UpdateInputState(&input_state);
|
|
|
|
NativeUpdate(input_state);
|
|
|
|
NativeRender();
|
2013-07-25 14:28:18 +10:00
|
|
|
EndInputState(&input_state);
|
2013-02-11 21:35:10 +10:00
|
|
|
time_update();
|
2012-12-13 16:38:33 +10:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2013-03-11 11:51:10 +10:00
|
|
|
void updateAccelerometer()
|
|
|
|
{
|
2013-04-07 00:52:09 +10:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 11:51:10 +10: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 16:38:33 +10:00
|
|
|
private:
|
|
|
|
InputState input_state;
|
2013-04-07 00:52:09 +10:00
|
|
|
#ifdef USING_GLES2
|
2013-03-11 11:51:10 +10:00
|
|
|
QAccelerometer* acc;
|
|
|
|
#endif
|
2012-12-13 16:38:33 +10:00
|
|
|
};
|
|
|
|
|
2013-01-10 18:06:11 +10:00
|
|
|
// Audio
|
2012-12-16 19:47:51 +10:00
|
|
|
#define AUDIO_FREQ 44100
|
|
|
|
#define AUDIO_CHANNELS 2
|
2013-10-22 03:58:56 +10:00
|
|
|
#define AUDIO_SAMPLES 2048
|
2012-12-16 19:47:51 +10:00
|
|
|
#define AUDIO_SAMPLESIZE 16
|
|
|
|
class MainAudio: public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
MainAudio() {
|
2013-10-26 19:51:29 +10:00
|
|
|
}
|
|
|
|
~MainAudio() {
|
|
|
|
if (feed != NULL) {
|
|
|
|
killTimer(timer);
|
|
|
|
feed->close();
|
|
|
|
}
|
|
|
|
if (output) {
|
|
|
|
output->stop();
|
|
|
|
delete output;
|
|
|
|
}
|
|
|
|
if (mixbuf)
|
|
|
|
free(mixbuf);
|
|
|
|
}
|
|
|
|
public slots:
|
|
|
|
void run() {
|
2012-12-16 19:47:51 +10:00
|
|
|
QAudioFormat fmt;
|
2013-10-19 05:21:44 +10:00
|
|
|
fmt.setSampleRate(AUDIO_FREQ);
|
2012-12-16 19:47:51 +10:00
|
|
|
fmt.setCodec("audio/pcm");
|
|
|
|
fmt.setChannelCount(AUDIO_CHANNELS);
|
|
|
|
fmt.setSampleSize(AUDIO_SAMPLESIZE);
|
|
|
|
fmt.setByteOrder(QAudioFormat::LittleEndian);
|
2013-10-22 03:58:56 +10:00
|
|
|
fmt.setSampleType(QAudioFormat::SignedInt);
|
2013-10-28 15:33:02 +10:00
|
|
|
mixlen = 5*2*AUDIO_CHANNELS*AUDIO_SAMPLES;
|
2012-12-16 19:47:51 +10:00
|
|
|
mixbuf = (char*)malloc(mixlen);
|
|
|
|
output = new QAudioOutput(fmt);
|
|
|
|
output->setBufferSize(mixlen);
|
|
|
|
feed = output->start();
|
2013-10-19 12:37:54 -07:00
|
|
|
if (feed != NULL)
|
|
|
|
timer = startTimer(1000*AUDIO_SAMPLES / AUDIO_FREQ);
|
2012-12-16 19:47:51 +10:00
|
|
|
}
|
|
|
|
|
2013-01-15 20:45:26 +10:00
|
|
|
protected:
|
|
|
|
void timerEvent(QTimerEvent *) {
|
2012-12-16 19:47:51 +10:00
|
|
|
memset(mixbuf, 0, mixlen);
|
2013-10-28 15:33:02 +10:00
|
|
|
size_t frames = NativeMix((short *)mixbuf, 5*AUDIO_SAMPLES);
|
2013-10-22 14:52:14 +10:00
|
|
|
if (frames > 0)
|
|
|
|
feed->write(mixbuf, sizeof(short) * 2 * frames);
|
2012-12-16 19:47:51 +10:00
|
|
|
}
|
|
|
|
private:
|
|
|
|
QIODevice* feed;
|
|
|
|
QAudioOutput* output;
|
|
|
|
int mixlen;
|
|
|
|
char* mixbuf;
|
2013-01-31 23:49:37 +01:00
|
|
|
int timer;
|
2012-12-16 19:47:51 +10:00
|
|
|
};
|
|
|
|
|
2012-12-13 16:38:33 +10:00
|
|
|
#endif
|
|
|
|
|