- Reworked Qt frontend to be fully based on QML (Qtmain.cpp still contains most of the old code as I need to perform additional tests on Maemo/Meego and Linux)

- Modified the download of resources to happen on every platform
- Resources are now stored based on the home directory
This commit is contained in:
Xawotihs
2012-01-06 21:45:08 +00:00
parent 6d5342c02b
commit 1f3aedcd3f
7 changed files with 516 additions and 151 deletions

View File

@@ -0,0 +1,89 @@
#ifndef COREWRAPPER_H
#define COREWRAPPER_H
#include <QObject>
#include <QtDeclarative>
#include <QGraphicsItem>
#include "../include/JGE.h"
#include "../include/JTypes.h"
#include "../include/JApp.h"
#include "../include/JFileSystem.h"
#include "../include/JRenderer.h"
#include "../include/JGameLauncher.h"
class WagicCore : public QDeclarativeItem
{
Q_OBJECT
Q_PROPERTY(int nominalWidth READ getNominalWidth CONSTANT)
Q_PROPERTY(int nominalHeight READ getNominalHeight CONSTANT)
Q_PROPERTY(float nominalRatio READ getNominalRatio CONSTANT)
Q_PROPERTY(bool active READ getActive WRITE setActive NOTIFY activeChanged)
public:
explicit WagicCore(QDeclarativeItem *parent = 0);
virtual ~WagicCore();
void initApp();
void render(){
if(m_engine)
m_engine->Render();
};
Q_INVOKABLE void doOK() {
doAndEnqueue(JGE_BTN_OK);
};
Q_INVOKABLE void doNext() {
doAndEnqueue(JGE_BTN_PREV);
};
Q_INVOKABLE void doCancel() {
doAndEnqueue(JGE_BTN_SEC);
};
Q_INVOKABLE void doMenu() {
doAndEnqueue(JGE_BTN_MENU);
};
Q_INVOKABLE void done() {
while(m_buttonQueue.size())
{
m_engine->ReleaseKey(m_buttonQueue.front());
m_buttonQueue.pop();
}
};
Q_INVOKABLE void pixelInput(int x, int y);
int getNominalHeight(){ return SCREEN_HEIGHT;};
int getNominalWidth(){ return SCREEN_WIDTH;};
float getNominalRatio() { return ((float)SCREEN_WIDTH / (float)SCREEN_HEIGHT);};
bool getActive() { return m_active; };
void setActive(bool active);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void resize ( const QRectF &rect);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
signals:
void activeChanged();
private slots:
private:
void timerEvent( QTimerEvent* );
void doAndEnqueue(JButton action) {
m_engine->HoldKey_NoRepeat(action);
m_buttonQueue.push(action);
}
public:
// used mainly to mesure the delta between 2 updates
static QElapsedTimer g_startTimer;
private:
JGE* m_engine;
JApp* m_app;
JGameLauncher* m_launcher;
qint64 m_lastTickCount;
std::queue<JButton> m_buttonQueue;
int m_timerId;
bool m_active;
QRect m_viewPort;
};
QML_DECLARE_TYPE(WagicCore)
#endif // COREWRAPPER_H

View File

@@ -13,6 +13,7 @@
class FileDownloader : public QObject
{
Q_OBJECT
Q_PROPERTY(bool done READ isDone NOTIFY downloaded)
Q_PROPERTY(qint64 received READ received NOTIFY receivedChanged)
public:
explicit FileDownloader(QUrl url, QString localPath, QObject *parent = 0);
@@ -32,6 +33,7 @@ private slots:
m_tmp.setAutoRemove(false);
m_done = true;
//emit a signal
emit downloaded();
};

View File

@@ -116,8 +116,10 @@ JFileSystem::JFileSystem(const string & _userPath, const string & _systemPath)
userPath = "/sdcard/Wagic/Res/";
systemPath = "";
#elif defined (QT_CONFIG)
userPath = USERDIR;
systemPath = RESDIR;
// userPath = USERDIR;
// systemPath = RESDIR;
userPath = QDir::toNativeSeparators(QDir::homePath()).toStdString() + "/.wagic/";
systemPath = "";
#else
//Find the Res.txt file and matching Res folders for backwards compatibility
ifstream mfile("Res.txt");

View File

@@ -40,12 +40,7 @@
#define glClearDepthf glClearDepth
#endif
#include "../include/JGE.h"
#include "../include/JTypes.h"
#include "../include/JApp.h"
#include "../include/JFileSystem.h"
#include "../include/JRenderer.h"
#include "../include/JGameLauncher.h"
#include "corewrapper.h"
#define ACTUAL_SCREEN_WIDTH (SCREEN_WIDTH)
#define ACTUAL_SCREEN_HEIGHT (SCREEN_HEIGHT)
@@ -92,8 +87,6 @@ protected:
void keyReleaseEvent(QKeyEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
@@ -186,7 +179,7 @@ qint64 lastTickCount;
JGE* g_engine = NULL;
JApp* g_app = NULL;
JGameLauncher* g_launcher = NULL;
JGEQtRenderer *g_glwidget = NULL;
QWidget *g_glwidget = NULL;
static const struct { LocalKeySym keysym; JButton keycode; } gDefaultBindings[] =
{
@@ -208,18 +201,12 @@ static const struct { LocalKeySym keysym; JButton keycode; } gDefaultBindings[]
// { Qt::Key_F, JGE_BTN_FULLSCREEN },
};
void JGECreateDefaultBindings()
{
for (signed int i = sizeof(gDefaultBindings)/sizeof(gDefaultBindings[0]) - 1; i >= 0; --i)
g_engine->BindKey(gDefaultBindings[i].keysym, gDefaultBindings[i].keycode);
}
int JGEGetTime()
{
return (int)g_startTimer.elapsed();
}
bool JGEToggleFullscreen()
{
if(g_glwidget->isFullScreen())
@@ -388,7 +375,6 @@ void JGEQtRenderer::resizeGL(int width, int height)
glLoadIdentity (); // Reset The Modelview Matrix
glDisable (GL_DEPTH_TEST);
#endif
}
@@ -552,26 +538,6 @@ void JGEQtRenderer::mouseMoveEvent(QMouseEvent *event)
}
}
void JGEQtRenderer::mouseDoubleClickEvent(QMouseEvent *event)
{
/*
QEvent SIPevent(QEvent::RequestSoftwareInputPanel);
QApplication::sendEvent(this, &SIPevent);
#if (defined Q_WS_MAEMO_5) || (defined MEEGO_EDITION_HARMATTAN)
if(event->button() == Qt::LeftButton)
{
g_engine->HoldKey_NoRepeat(JGE_BTN_OK);
event->accept();
}
else
#endif
*/
{
QGLWidget::mouseDoubleClickEvent(event);
}
}
void JGEQtRenderer::wheelEvent(QWheelEvent *event)
{
if(event->orientation() == Qt::Vertical)
@@ -658,67 +624,25 @@ void JGEQtRenderer::hideEvent ( QHideEvent * event )
int main(int argc, char* argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QDir::setCurrent(QCoreApplication::applicationDirPath () );
qDebug() << "Current path : " << QCoreApplication::applicationDirPath ();
qmlRegisterType<WagicCore>("CustomComponents", 1, 0, "WagicCore");
QScopedPointer<QApplication> app(createApplication(argc, argv));
app->setApplicationName(g_launcher->GetName());
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
FileDownloader fileDownloader(QUrl("http://wagic.googlecode.com/files/core_017.zip"),
QDir::toNativeSeparators(QDir::homePath()) + "/.wagic/core_017.zip", 0);
if(!fileDownloader.isDone()){
app->connect(&fileDownloader, SIGNAL(downloaded()), SLOT(quit()));
viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer->setMainQmlFile(QLatin1String("qml/QmlWagic/main.qml"));
viewer->rootContext()->setContextProperty("fileDownloader", &fileDownloader);
viewer->showExpanded();
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
g_glwidget = viewer.data();
viewer->setMainQmlFile(QLatin1String("qml/QmlWagic/main.qml"));
app->exec();
viewer->rootContext()->setContextProperty("fileDownloader", &fileDownloader);
viewer->close();
}
viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
QGLWidget *glWidget = new QGLWidget;
viewer->setViewport(glWidget);
g_launcher = new JGameLauncher();
u32 flags = g_launcher->GetInitFlags();
if ((flags&JINIT_FLAG_ENABLE3D)!=0)
{
JRenderer::Set3DFlag(true);
}
g_glwidget = new JGEQtRenderer(NULL);
g_glwidget->resize(ACTUAL_SCREEN_WIDTH, ACTUAL_SCREEN_HEIGHT);
app->setApplicationName(g_launcher->GetName());
//a.setAutoSipEnabled(true);
#if (defined Q_WS_MAEMO_5) || (defined MEEGO_EDITION_HARMATTAN) || (defined Q_WS_ANDROID)
// We start in fullscreen on mobile
g_glwidget->showFullScreen();
#else
// not on desktop
g_glwidget->show();
#endif
JGECreateDefaultBindings();
if (!InitGame())
{
qCritical("Could not init the game\n");
return 1;
}
app->exec();
if (g_launcher)
delete g_launcher;
if(g_glwidget)
delete g_glwidget;
// Shutdown
DestroyGame();
return 0;
viewer->showExpanded();
viewer->setResizeMode(QDeclarativeView::SizeRootObjectToView);
return app->exec();
}

291
JGE/src/qt/corewrapper.cpp Normal file
View File

@@ -0,0 +1,291 @@
#include "corewrapper.h"
#define ACTUAL_SCREEN_WIDTH (SCREEN_WIDTH)
#define ACTUAL_SCREEN_HEIGHT (SCREEN_HEIGHT)
#define ACTUAL_RATIO ((GLfloat)ACTUAL_SCREEN_WIDTH / (GLfloat)ACTUAL_SCREEN_HEIGHT)
static const struct { LocalKeySym keysym; JButton keycode; } gDefaultBindings[] =
{
{ Qt::Key_Enter, JGE_BTN_MENU },
{ Qt::Key_Return, JGE_BTN_MENU },
{ Qt::Key_Escape, JGE_BTN_MENU },
{ Qt::Key_Backspace, JGE_BTN_CTRL },
{ Qt::Key_Up, JGE_BTN_UP },
{ Qt::Key_Down, JGE_BTN_DOWN },
{ Qt::Key_Left, JGE_BTN_LEFT },
{ Qt::Key_Right, JGE_BTN_RIGHT },
{ Qt::Key_Space, JGE_BTN_OK },
{ Qt::Key_Tab, JGE_BTN_CANCEL },
{ Qt::Key_J, JGE_BTN_PRI },
{ Qt::Key_K, JGE_BTN_SEC },
{ Qt::Key_Q, JGE_BTN_PREV },
{ Qt::Key_A, JGE_BTN_NEXT },
// fullscreen management seems somehow broken in JGE, it works fine with Qt directly
// { Qt::Key_F, JGE_BTN_FULLSCREEN },
};
int JGEGetTime()
{
return (int)WagicCore::g_startTimer.elapsed();
}
QElapsedTimer WagicCore::g_startTimer;
WagicCore::WagicCore(QDeclarativeItem *parent) :
QDeclarativeItem(parent), m_engine(0), m_app(0), m_launcher(0), m_active(false)
{
setFlag(QGraphicsItem::ItemHasNoContents, false);
setWidth(480);
setHeight(272);
// BindKey is a static method, m_engine is not even initialized
for (signed int i = sizeof(gDefaultBindings)/sizeof(gDefaultBindings[0]) - 1; i >= 0; --i)
m_engine->BindKey(gDefaultBindings[i].keysym, gDefaultBindings[i].keycode);
g_startTimer.restart();
m_lastTickCount = g_startTimer.elapsed();
}
void WagicCore::initApp()
{
if(!m_engine)
{
m_launcher = new JGameLauncher();
u32 flags = m_launcher->GetInitFlags();
if ((flags&JINIT_FLAG_ENABLE3D)!=0)
{
JRenderer::Set3DFlag(true);
}
// BindKey is a static method, m_engine is not even initialized
for (signed int i = sizeof(gDefaultBindings)/sizeof(gDefaultBindings[0]) - 1; i >= 0; --i)
m_engine->BindKey(gDefaultBindings[i].keysym, gDefaultBindings[i].keycode);
m_engine = JGE::GetInstance();
m_app = m_launcher->GetGameApp();
m_app->Create();
m_engine->SetApp(m_app);
JRenderer::GetInstance()->Enable2D();
setActive(true);
}
}
WagicCore::~WagicCore()
{
if(m_launcher)
{
delete m_launcher;
m_launcher = NULL;
}
m_engine->SetApp(NULL);
if (m_app)
{
m_app->Destroy();
delete m_app;
m_app = NULL;
}
JGE::Destroy();
m_engine = NULL;
}
void WagicCore::pixelInput(int x, int y)
{
if(m_engine)
m_engine->LeftClicked(x, y);
}
void WagicCore::timerEvent( QTimerEvent* )
{
qint64 tickCount;
quint32 dt;
tickCount = g_startTimer.elapsed();
dt = (tickCount - m_lastTickCount);
m_lastTickCount = tickCount;
if(!m_engine)
return;
if(m_engine->IsDone())
QApplication::instance()->quit();
m_engine->SetDelta((float)dt / 1000.0f);
m_engine->Update((float)dt / 1000.0f);
update();
}
void WagicCore::setActive(bool active)
{
if(!m_engine) return;
if(!m_active && active)
{
m_engine->Resume();
#if (defined Q_WS_MAEMO_5) || (defined MEEGO_EDITION_HARMATTAN) || (defined Q_WS_ANDROID)
// 30 fps max on mobile
m_timerId = startTimer(33);
#else
// 200 fps max on desktop
m_timerId = startTimer(5);
#endif //Q_WS_MAEMO_5
m_active = active;
emit activeChanged();
}
else if(m_active && !active)
{
m_engine->Pause();
#if (defined Q_WS_MAEMO_5) || (defined MEEGO_EDITION_HARMATTAN) || (defined Q_WS_ANDROID)
killTimer(timerId);
#endif
m_active = active;
emit activeChanged();
}
}
void WagicCore::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->beginNativePainting();
initApp();
QRectF rectf = boundingRect();
resize ( rectf);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background (yes that's the way fuckers)
#if (defined GL_ES_VERSION_2_0) || (defined GL_VERSION_2_0)
#if (defined GL_ES_VERSION_2_0)
glClearDepthf(1.0f); // Depth Buffer Setup
#else
glClearDepth(1.0f); // Depth Buffer Setup
#endif// (defined GL_ES_VERSION_2_0)
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
glEnable(GL_DEPTH_TEST); // Enable Depth Testing
#else
#if (defined GL_VERSION_ES_CM_1_1 || defined GL_OES_VERSION_1_1)
glClearDepthf(1.0f); // Depth Buffer Setup
#else
glClearDepth(1.0f); // Depth Buffer Setup
#endif
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
glEnable(GL_DEPTH_TEST); // Enable Depth Testing
glShadeModel(GL_SMOOTH); // Select Smooth Shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Set Line Antialiasing
glEnable(GL_LINE_SMOOTH); // Enable it!
glEnable(GL_TEXTURE_2D);
#endif
glEnable(GL_CULL_FACE); // do not calculate inside of poly's
glFrontFace(GL_CCW); // counter clock-wise polygons are out
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_SCISSOR_TEST); // Enable Clipping
render();
painter->endNativePainting();
}
void WagicCore::resize ( const QRectF &rect)
{
int width = rect.size().width();
int height= rect.size().height();
if(width && height)
{
if ((GLfloat)width / (GLfloat)height <= ACTUAL_RATIO)
{
m_viewPort.setLeft(0);
m_viewPort.setTop(-((width/ACTUAL_RATIO)-height)/2);
m_viewPort.setRight(width);
m_viewPort.setBottom(-((width/ACTUAL_RATIO)-height)/2 + width / ACTUAL_RATIO);
}
else
{
m_viewPort.setLeft(-(height*ACTUAL_RATIO-width)/2);
m_viewPort.setTop(0);
m_viewPort.setRight(-(height*ACTUAL_RATIO-width)/2 + height * ACTUAL_RATIO);
m_viewPort.setBottom(height);
}
glViewport(m_viewPort.left(), m_viewPort.top(), m_viewPort.right()-m_viewPort.left(), m_viewPort.bottom()-m_viewPort.top());
JRenderer::GetInstance()->SetActualWidth(m_viewPort.right()-m_viewPort.left());
JRenderer::GetInstance()->SetActualHeight(m_viewPort.bottom()-m_viewPort.top());
glScissor(0, 0, width, height);
#if (!defined GL_ES_VERSION_2_0) && (!defined GL_VERSION_2_0)
glMatrixMode (GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity (); // Reset The Projection Matrix
#if (defined GL_VERSION_ES_CM_1_1 || defined GL_OES_VERSION_1_1)
glOrthof(0.0f, (float) (m_viewPort.right()-m_viewPort.left())-1.0f, 0.0f, (float) (m_viewPort.bottom()-m_viewPort.top())-1.0f, -1.0f, 1.0f);
#else
gluOrtho2D(0.0f, (float) (m_viewPort.right()-m_viewPort.left())-1.0f, 0.0f, (float) (m_viewPort.bottom()-m_viewPort.top())-1.0f);
#endif
glMatrixMode (GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity (); // Reset The Modelview Matrix
glDisable (GL_DEPTH_TEST);
#endif
}
}
void WagicCore::keyPressEvent(QKeyEvent *event)
{
switch(event->key())
{
#if (defined Q_WS_MAEMO_5)
case Qt::Key_F7:
/* interrupt please */
g_engine->HoldKey_NoRepeat(JGE_BTN_SEC);
break;
case Qt::Key_F8:
/* next phase please */
g_engine->HoldKey_NoRepeat(JGE_BTN_PREV);
break;
#endif // Q_WS_MAEMO_5
case Qt::Key_F:
JGEToggleFullscreen();
break;
default:
m_engine->HoldKey_NoRepeat((LocalKeySym)event->key());
}
event->accept();
QGraphicsItem::keyPressEvent(event);
return;
}
void WagicCore::keyReleaseEvent(QKeyEvent *event)
{
switch(event->key())
{
#if (defined Q_WS_MAEMO_5)
case Qt::Key_F7:
/* interrupt please */
m_engine->ReleaseKey(JGE_BTN_SEC);
break;
case Qt::Key_F8:
/* next phase please */
m_engine->ReleaseKey(JGE_BTN_PREV);
break;
#endif // Q_WS_MAEMO_5
default:
m_engine->ReleaseKey((LocalKeySym)event->key());
}
event->accept();
QGraphicsItem::keyReleaseEvent(event);
return;
}