mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-09 14:47:02 +02:00
WebGL platform
This commit is contained in:
@@ -238,7 +238,7 @@ struct Controller {
|
|||||||
|
|
||||||
void *p = &level->soundData[c];
|
void *p = &level->soundData[c];
|
||||||
|
|
||||||
PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY);
|
// PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
16
src/core.h
16
src/core.h
@@ -2,9 +2,17 @@
|
|||||||
#define H_CORE
|
#define H_CORE
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#ifdef WIN32
|
||||||
#include <gl/GL.h>
|
#include <windows.h>
|
||||||
#include <gl/glext.h>
|
#include <gl/GL.h>
|
||||||
|
#include <gl/glext.h>
|
||||||
|
#elif __EMSCRIPTEN__
|
||||||
|
#include <emscripten.h>
|
||||||
|
#include <html5.h>
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#include <GLES3/gl2ext.h>
|
||||||
|
#define MOBILE
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
@@ -72,6 +80,7 @@ enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen };
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
|
#ifdef WIN32
|
||||||
GetProcOGL(glActiveTexture);
|
GetProcOGL(glActiveTexture);
|
||||||
|
|
||||||
GetProcOGL(glCreateProgram);
|
GetProcOGL(glCreateProgram);
|
||||||
@@ -99,6 +108,7 @@ namespace Core {
|
|||||||
GetProcOGL(glDeleteBuffers);
|
GetProcOGL(glDeleteBuffers);
|
||||||
GetProcOGL(glBindBuffer);
|
GetProcOGL(glBindBuffer);
|
||||||
GetProcOGL(glBufferData);
|
GetProcOGL(glBufferData);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void free() {
|
void free() {
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
//#define TR1_DEMO
|
#define TR1_DEMO
|
||||||
|
|
||||||
namespace TR {
|
namespace TR {
|
||||||
#define DATA_PORTAL 0x01
|
#define DATA_PORTAL 0x01
|
||||||
|
@@ -11,8 +11,8 @@ namespace Game {
|
|||||||
Level *level;
|
Level *level;
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
Core::init();
|
Core::init();
|
||||||
level = new Level("data\\GYM.PHD");
|
level = new Level("data\\LEVEL2_DEMO.PHD");
|
||||||
}
|
}
|
||||||
|
|
||||||
void free() {
|
void free() {
|
||||||
|
@@ -59,6 +59,7 @@ namespace Input {
|
|||||||
case ikMouseM : mouse.start.M = mouse.pos; break;
|
case ikMouseM : mouse.start.M = mouse.pos; break;
|
||||||
case ikTouchA : touch.start.A = touch.A; break;
|
case ikTouchA : touch.start.A = touch.A; break;
|
||||||
case ikTouchB : touch.start.B = touch.B; break;
|
case ikTouchB : touch.start.B = touch.B; break;
|
||||||
|
default : ;
|
||||||
}
|
}
|
||||||
|
|
||||||
down[key] = value;
|
down[key] = value;
|
||||||
@@ -76,6 +77,7 @@ namespace Input {
|
|||||||
case ikJoyDP : joy.DP = pos.x; break;
|
case ikJoyDP : joy.DP = pos.x; break;
|
||||||
case ikTouchA : touch.A = pos; break;
|
case ikTouchA : touch.A = pos; break;
|
||||||
case ikTouchB : touch.B = pos; break;
|
case ikTouchB : touch.B = pos; break;
|
||||||
|
default : ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
src/level.h
25
src/level.h
@@ -6,7 +6,10 @@
|
|||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "debug.h"
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#include "debug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
const char SHADER[] =
|
const char SHADER[] =
|
||||||
#include "shader.glsl"
|
#include "shader.glsl"
|
||||||
@@ -187,7 +190,7 @@ struct Level {
|
|||||||
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z };
|
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z };
|
||||||
vertices[vCount].color = { a, a, a, 255 };
|
vertices[vCount].color = { a, a, a, 255 };
|
||||||
vertices[vCount].normal = { 0, 0, 0, 0x7FFF };
|
vertices[vCount].normal = { 0, 0, 0, 0x7FFF };
|
||||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
vertices[vCount].texCoord = { (int16)((tx + (int)t.vertices[k].Xpixel) << 5) + 16, (int16)((ty + (int)t.vertices[k].Ypixel) << 5) + 16};
|
||||||
vCount++;
|
vCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,7 +218,7 @@ struct Level {
|
|||||||
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z };
|
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z };
|
||||||
vertices[vCount].color = { a, a, a, 255 };
|
vertices[vCount].color = { a, a, a, 255 };
|
||||||
vertices[vCount].normal = { 0, 0, 0, 0x7FFF };
|
vertices[vCount].normal = { 0, 0, 0, 0x7FFF };
|
||||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
vertices[vCount].texCoord = { (int16)((tx + (int)t.vertices[k].Xpixel) << 5) + 16, (int16)((ty + (int)t.vertices[k].Ypixel) << 5) + 16};
|
||||||
vCount++;
|
vCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,7 +287,7 @@ struct Level {
|
|||||||
vertices[vCount].normal = { 0, 0, 0, 255 };
|
vertices[vCount].normal = { 0, 0, 0, 255 };
|
||||||
vertices[vCount].color = { a, a, a, 255 };
|
vertices[vCount].color = { a, a, a, 255 };
|
||||||
}
|
}
|
||||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
vertices[vCount].texCoord = { (int16)((tx + (int)t.vertices[k].Xpixel) << 5) + 16, (int16)((ty + (int)t.vertices[k].Ypixel) << 5) + 16};
|
||||||
vCount++;
|
vCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +323,7 @@ struct Level {
|
|||||||
vertices[vCount].normal = { 0, 0, 0, 255 };
|
vertices[vCount].normal = { 0, 0, 0, 255 };
|
||||||
vertices[vCount].color = { a, a, a, 255 };
|
vertices[vCount].color = { a, a, a, 255 };
|
||||||
}
|
}
|
||||||
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16};
|
vertices[vCount].texCoord = { ((tx + t.vertices[k].Xpixel) << 5) + 16, ((ty + t.vertices[k].Ypixel) << 5) + 16 };
|
||||||
vCount++;
|
vCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -488,6 +491,7 @@ struct Level {
|
|||||||
p[3] = right * sprite.r + up * sprite.t;
|
p[3] = right * sprite.r + up * sprite.t;
|
||||||
|
|
||||||
// bindTexture(sprite.tile);
|
// bindTexture(sprite.tile);
|
||||||
|
/*
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(u0, v1);
|
glTexCoord2f(u0, v1);
|
||||||
glVertex3fv((GLfloat*)&p[0]);
|
glVertex3fv((GLfloat*)&p[0]);
|
||||||
@@ -498,11 +502,13 @@ struct Level {
|
|||||||
glTexCoord2f(u0, v0);
|
glTexCoord2f(u0, v0);
|
||||||
glVertex3fv((GLfloat*)&p[3]);
|
glVertex3fv((GLfloat*)&p[3]);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSprite(const TR::Room &room, const TR::Room::Data::Sprite &sprite) {
|
void renderSprite(const TR::Room &room, const TR::Room::Data::Sprite &sprite) {
|
||||||
auto &v = room.data.vertices[sprite.vertex];
|
auto &v = room.data.vertices[sprite.vertex];
|
||||||
float a = 1.0f - v.lighting / (float)0x1FFF;
|
float a = 1.0f - v.lighting / (float)0x1FFF;
|
||||||
|
/*
|
||||||
glColor3f(a, a, a);
|
glColor3f(a, a, a);
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
@@ -511,6 +517,7 @@ struct Level {
|
|||||||
renderSprite(level.spriteTextures[sprite.texture]);
|
renderSprite(level.spriteTextures[sprite.texture]);
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 getAngle(TR::AnimFrame *frame, int index) {
|
vec3 getAngle(TR::AnimFrame *frame, int index) {
|
||||||
@@ -702,6 +709,7 @@ struct Level {
|
|||||||
Core::mModel = m;
|
Core::mModel = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
void debugPortals() {
|
void debugPortals() {
|
||||||
Core::setBlending(bmAdd);
|
Core::setBlending(bmAdd);
|
||||||
glColor3f(0, 0.25f, 0.25f);
|
glColor3f(0, 0.25f, 0.25f);
|
||||||
@@ -898,7 +906,7 @@ struct Level {
|
|||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
void debugEntity() {
|
void debugEntity() {
|
||||||
Core::setCulling(cfNone);
|
Core::setCulling(cfNone);
|
||||||
@@ -996,11 +1004,8 @@ struct Level {
|
|||||||
shader->setParam(uViewProj, Core::mViewProj);
|
shader->setParam(uViewProj, Core::mViewProj);
|
||||||
shader->setParam(uModel, Core::mModel);
|
shader->setParam(uModel, Core::mModel);
|
||||||
|
|
||||||
glEnable(GL_ALPHA_TEST);
|
|
||||||
glAlphaFunc(GL_GREATER, 0.9f);
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
Core::setCulling(cfFront);
|
Core::setCulling(cfFront);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
Core::mModel.identity();
|
Core::mModel.identity();
|
||||||
|
|
||||||
|
@@ -29,7 +29,10 @@ varying vec4 vColor;
|
|||||||
uniform vec4 uLightColor;
|
uniform vec4 uLightColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 color = texture2D(sDiffuse, vTexCoord) * vColor * uColor;
|
vec4 color = texture2D(sDiffuse, vTexCoord);
|
||||||
|
if (color.w < 0.9)
|
||||||
|
discard;
|
||||||
|
color *= vColor * uColor;
|
||||||
// #ifdef LIGHTING
|
// #ifdef LIGHTING
|
||||||
color.xyz = pow(color.xyz, vec3(2.2));
|
color.xyz = pow(color.xyz, vec3(2.2));
|
||||||
float lum = dot(normalize(vNormal.xyz), normalize(vLightVec));
|
float lum = dot(normalize(vNormal.xyz), normalize(vLightVec));
|
||||||
|
26
src/utils.h
26
src/utils.h
@@ -131,23 +131,23 @@ struct quat {
|
|||||||
w = cosf(angle);
|
w = cosf(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::operator - () const {
|
quat operator - () const {
|
||||||
return quat(-x, -y, -z, -w);
|
return quat(-x, -y, -z, -w);
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::operator + (const quat &q) const {
|
quat operator + (const quat &q) const {
|
||||||
return quat(x + q.x, y + q.y, z + q.z, w + q.w);
|
return quat(x + q.x, y + q.y, z + q.z, w + q.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::operator - (const quat &q) const {
|
quat operator - (const quat &q) const {
|
||||||
return quat(x - q.x, y - q.y, z - q.z, w - q.w);
|
return quat(x - q.x, y - q.y, z - q.z, w - q.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::operator * (const float s) const {
|
quat operator * (const float s) const {
|
||||||
return quat(x * s, y * s, z * s, w * s);
|
return quat(x * s, y * s, z * s, w * s);
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::operator * (const quat &q) const {
|
quat operator * (const quat &q) const {
|
||||||
return quat(w * q.x + x * q.w + y * q.z - z * q.y,
|
return quat(w * q.x + x * q.w + y * q.z - z * q.y,
|
||||||
w * q.y + y * q.w + z * q.x - x * q.z,
|
w * q.y + y * q.w + z * q.x - x * q.z,
|
||||||
w * q.z + z * q.w + x * q.y - y * q.x,
|
w * q.z + z * q.w + x * q.y - y * q.x,
|
||||||
@@ -166,19 +166,19 @@ struct quat {
|
|||||||
return sqrtf(length2());
|
return sqrtf(length2());
|
||||||
}
|
}
|
||||||
|
|
||||||
void quat::normalize() {
|
void normalize() {
|
||||||
*this = normal();
|
*this = normal();
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::normal() const {
|
quat normal() const {
|
||||||
return *this * (1.0f / length());
|
return *this * (1.0f / length());
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::conjugate() const {
|
quat conjugate() const {
|
||||||
return quat(-x, -y, -z, w);
|
return quat(-x, -y, -z, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
quat quat::inverse() const {
|
quat inverse() const {
|
||||||
return conjugate() * (1.0f / length2());
|
return conjugate() * (1.0f / length2());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +382,7 @@ struct mat4 {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
quat mat4::getRot() const {
|
quat getRot() const {
|
||||||
float t, s;
|
float t, s;
|
||||||
t = 1.0f + e00 + e11 + e22;
|
t = 1.0f + e00 + e11 + e22;
|
||||||
if (t > EPS) {
|
if (t > EPS) {
|
||||||
@@ -402,7 +402,7 @@ struct mat4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mat4::setRot(const quat &rot) {
|
void setRot(const quat &rot) {
|
||||||
float sx = rot.x * rot.x,
|
float sx = rot.x * rot.x,
|
||||||
sy = rot.y * rot.y,
|
sy = rot.y * rot.y,
|
||||||
sz = rot.z * rot.z,
|
sz = rot.z * rot.z,
|
||||||
@@ -430,11 +430,11 @@ struct mat4 {
|
|||||||
e12 = (t1 - t2) * inv;
|
e12 = (t1 - t2) * inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 mat4::getPos() const {
|
vec3 getPos() const {
|
||||||
return offset.xyz;
|
return offset.xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mat4::setPos(const vec3 &pos) {
|
void setPos(const vec3 &pos) {
|
||||||
offset.xyz = pos;
|
offset.xyz = pos;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
2
src/web/build.bat
Normal file
2
src/web/build.bat
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
set SRC=main.cpp
|
||||||
|
em++ %SRC% -O2 --llvm-opts 2 --closure 1 -std=c++11 -o OpenLara.js --preload-file ./../../bin/data/LEVEL2_DEMO.PHD -I..\
|
77
src/web/index.html
Normal file
77
src/web/index.html
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<html>
|
||||||
|
<head><title>OpenLara</title><head>
|
||||||
|
<body>
|
||||||
|
<span id="status">Starting...</span>
|
||||||
|
<span><input type="button" value="fullscreen" onclick="Module.requestFullScreen(false, true)"><br><br>
|
||||||
|
<canvas id="canvas" width="160" height="120" oncontextmenu="event.preventDefault()"></canvas><br>
|
||||||
|
<span id="info"></span>
|
||||||
|
|
||||||
|
<script type='text/javascript'>
|
||||||
|
var statusElement = document.getElementById('status');
|
||||||
|
var canvasElement = document.getElementById('canvas');
|
||||||
|
|
||||||
|
var Module = {
|
||||||
|
preRun: [],
|
||||||
|
postRun: [],
|
||||||
|
print: (function() {
|
||||||
|
return function(text) {
|
||||||
|
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||||
|
console.log(text);
|
||||||
|
};
|
||||||
|
})(),
|
||||||
|
printErr: function(text) {
|
||||||
|
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||||
|
if (0) {
|
||||||
|
dump(text + '\n');
|
||||||
|
} else {
|
||||||
|
console.error(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canvas: (function() {
|
||||||
|
canvasElement.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||||
|
return canvasElement;
|
||||||
|
})(),
|
||||||
|
setStatus: function(text) {
|
||||||
|
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
|
||||||
|
if (text === Module.setStatus.text) return;
|
||||||
|
statusElement.innerHTML = text;
|
||||||
|
},
|
||||||
|
totalDependencies: 0,
|
||||||
|
monitorRunDependencies: function(left) {
|
||||||
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||||
|
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var gl = canvasElement.getContext("webgl") || canvasElement.getContext("experimental-webgl");
|
||||||
|
|
||||||
|
Module.setStatus('Downloading...');
|
||||||
|
window.onerror = function(event) {
|
||||||
|
Module.setStatus('Exception thrown, see JavaScript console');
|
||||||
|
//spinnerElement.style.display = 'none';
|
||||||
|
document.getElementById('info').innerHTML = event;
|
||||||
|
Module.setStatus = function(text) {
|
||||||
|
if (text) Module.printErr('[post-exception status] ' + text);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var memoryInitializer = 'OpenLara.js.mem';
|
||||||
|
if (typeof Module['locateFile'] === 'function') {
|
||||||
|
memoryInitializer = Module['locateFile'](memoryInitializer);
|
||||||
|
} else if (Module['memoryInitializerPrefixURL']) {
|
||||||
|
memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer;
|
||||||
|
}
|
||||||
|
var xhr = Module['memoryInitializerRequest'] = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', memoryInitializer, true);
|
||||||
|
xhr.responseType = 'arraybuffer';
|
||||||
|
xhr.send(null);
|
||||||
|
})();
|
||||||
|
|
||||||
|
var script = document.createElement('script');
|
||||||
|
script.src = "OpenLara.js";
|
||||||
|
document.body.appendChild(script);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
190
src/web/main.cpp
Normal file
190
src/web/main.cpp
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
int lastTime, fpsTime, FPS;
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLSurface surface;
|
||||||
|
EGLContext context;
|
||||||
|
|
||||||
|
int getTime() {
|
||||||
|
return (int)emscripten_get_now();
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_loop() {
|
||||||
|
int time = getTime();
|
||||||
|
|
||||||
|
if (time - lastTime <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Core::deltaTime = (time - lastTime) * 0.001f;
|
||||||
|
lastTime = time;
|
||||||
|
|
||||||
|
if (time > fpsTime) {
|
||||||
|
fpsTime = time + 1000;
|
||||||
|
LOG("FPS: %d\n", FPS);
|
||||||
|
FPS = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::update();
|
||||||
|
Game::render();
|
||||||
|
eglSwapBuffers(display, surface);
|
||||||
|
|
||||||
|
FPS++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initGL() {
|
||||||
|
EGLint vMajor, vMinor, cfgCount;
|
||||||
|
EGLConfig cfg;
|
||||||
|
|
||||||
|
EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
|
||||||
|
EGLint attribList[] = {
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
EGL_DEPTH_SIZE, 8,
|
||||||
|
EGL_STENCIL_SIZE, EGL_DONT_CARE,
|
||||||
|
EGL_SAMPLE_BUFFERS, EGL_DONT_CARE,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
display = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
|
||||||
|
eglInitialize(display, &vMajor, &vMinor);
|
||||||
|
eglGetConfigs(display, NULL, 0, &cfgCount);
|
||||||
|
eglChooseConfig(display, attribList, &cfg, 1, &cfgCount);
|
||||||
|
surface = eglCreateWindowSurface(display, cfg, NULL, NULL);
|
||||||
|
context = eglCreateContext(display, cfg, EGL_NO_CONTEXT, contextAttribs);
|
||||||
|
eglMakeCurrent(display, surface, surface, context);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeGL() {
|
||||||
|
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
eglDestroyContext(display, context);
|
||||||
|
eglDestroySurface(display, surface);
|
||||||
|
eglTerminate(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputKey keyToInputKey(int code) {
|
||||||
|
int codes[] = {
|
||||||
|
0x25, 0x27, 0x26, 0x28, 0x20, 0x0D, 0x1B, 0x10, 0x11, 0x12,
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(codes) / sizeof(codes[0]); i++)
|
||||||
|
if (codes[i] == code)
|
||||||
|
return (InputKey)(ikLeft + i);
|
||||||
|
return ikNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
EM_BOOL keyCallback(int eventType, const EmscriptenKeyboardEvent *e, void *userData) {
|
||||||
|
switch(eventType) {
|
||||||
|
case EMSCRIPTEN_EVENT_KEYDOWN:
|
||||||
|
case EMSCRIPTEN_EVENT_KEYUP:
|
||||||
|
Input::setDown(keyToInputKey(e->keyCode), eventType == EMSCRIPTEN_EVENT_KEYDOWN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EM_BOOL resizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData) {
|
||||||
|
// Core::width = e->documentBodyClientWidth;
|
||||||
|
// Core::height = e->documentBodyClientHeight;
|
||||||
|
int f;
|
||||||
|
emscripten_get_canvas_size(&Core::width, &Core::height, &f);
|
||||||
|
LOG("resize %d x %d\n", Core::width, Core::height);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EM_BOOL touchCallback(int eventType, const EmscriptenTouchEvent *e, void *userData) {
|
||||||
|
bool flag = false;
|
||||||
|
/*
|
||||||
|
for (int i = 0; i < e->numTouches; i++) {
|
||||||
|
long x = e->touches[i].canvasX;
|
||||||
|
long y = e->touches[i].canvasY;
|
||||||
|
if (x < 0 || y < 0 || x >= Core::width || y >= Core::height) continue;
|
||||||
|
flag = true;
|
||||||
|
|
||||||
|
switch (eventType) {
|
||||||
|
case EMSCRIPTEN_EVENT_TOUCHSTART :
|
||||||
|
if (x > Core::width / 2)
|
||||||
|
Input::joy.down[(y > Core::height / 2) ? 1 : 4] = true;
|
||||||
|
break;
|
||||||
|
case EMSCRIPTEN_EVENT_TOUCHMOVE :
|
||||||
|
if (x < Core::width / 2) {
|
||||||
|
vec2 center(Core::width * 0.25f, Core::height * 0.6f);
|
||||||
|
vec2 pos(x, y);
|
||||||
|
vec2 d = pos - center;
|
||||||
|
|
||||||
|
Input::Joystick &joy = Input::joy;
|
||||||
|
|
||||||
|
joy.L.x = d.x;
|
||||||
|
joy.L.y = d.y;
|
||||||
|
if (joy.L != vec2(0.0f))
|
||||||
|
joy.L.normalize();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EMSCRIPTEN_EVENT_TOUCHEND :
|
||||||
|
case EMSCRIPTEN_EVENT_TOUCHCANCEL : {
|
||||||
|
Input::joy.L = vec2(0.0f);
|
||||||
|
Input::joy.down[1] = false;
|
||||||
|
Input::joy.down[4] = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
EM_BOOL mouseCallback(int eventType, const EmscriptenMouseEvent *e, void *userData) {
|
||||||
|
switch (eventType) {
|
||||||
|
case EMSCRIPTEN_EVENT_MOUSEDOWN :
|
||||||
|
case EMSCRIPTEN_EVENT_MOUSEUP : {
|
||||||
|
InputKey key = e->button == 0 ? ikMouseL : (e->button == 2 ? ikMouseR : ikMouseM);
|
||||||
|
Input::setPos(key, vec2((float)e->clientX, (float)e->clientY));
|
||||||
|
Input::setDown(key, eventType != EMSCRIPTEN_EVENT_MOUSEUP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EMSCRIPTEN_EVENT_MOUSEMOVE :
|
||||||
|
Input::setPos(ikMouseL, vec2((float)e->clientX, (float)e->clientY));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
initGL();
|
||||||
|
|
||||||
|
emscripten_set_canvas_size(Core::width = 1280, Core::height = 720);
|
||||||
|
|
||||||
|
emscripten_set_keydown_callback(0, 0, 1, keyCallback);
|
||||||
|
emscripten_set_keyup_callback(0, 0, 1, keyCallback);
|
||||||
|
emscripten_set_resize_callback(0, 0, 1, resizeCallback);
|
||||||
|
|
||||||
|
emscripten_set_touchstart_callback(0, 0, 1, touchCallback);
|
||||||
|
emscripten_set_touchend_callback(0, 0, 1, touchCallback);
|
||||||
|
emscripten_set_touchmove_callback(0, 0, 1, touchCallback);
|
||||||
|
emscripten_set_touchcancel_callback(0, 0, 1, touchCallback);
|
||||||
|
|
||||||
|
emscripten_set_mousedown_callback(0, 0, 1, mouseCallback);
|
||||||
|
emscripten_set_mouseup_callback(0, 0, 1, mouseCallback);
|
||||||
|
emscripten_set_mousemove_callback(0, 0, 1, mouseCallback);
|
||||||
|
|
||||||
|
Game::init();
|
||||||
|
|
||||||
|
lastTime = getTime();
|
||||||
|
fpsTime = lastTime + 1000;
|
||||||
|
FPS = 0;
|
||||||
|
|
||||||
|
emscripten_set_main_loop(main_loop, 0, true);
|
||||||
|
|
||||||
|
Game::free();
|
||||||
|
freeGL();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user