diff --git a/src/controller.h b/src/controller.h index 19d6143..aa66cc5 100644 --- a/src/controller.h +++ b/src/controller.h @@ -238,7 +238,7 @@ struct Controller { void *p = &level->soundData[c]; - PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY); + // PlaySound((LPSTR)p, NULL, SND_ASYNC | SND_MEMORY); } break; } diff --git a/src/core.h b/src/core.h index fd6fa6c..497d1b2 100644 --- a/src/core.h +++ b/src/core.h @@ -2,9 +2,17 @@ #define H_CORE #include -#include -#include -#include +#ifdef WIN32 + #include + #include + #include +#elif __EMSCRIPTEN__ + #include + #include + #include + #include + #define MOBILE +#endif #include "utils.h" #include "input.h" @@ -72,6 +80,7 @@ enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen }; namespace Core { void init() { + #ifdef WIN32 GetProcOGL(glActiveTexture); GetProcOGL(glCreateProgram); @@ -99,6 +108,7 @@ namespace Core { GetProcOGL(glDeleteBuffers); GetProcOGL(glBindBuffer); GetProcOGL(glBufferData); + #endif } void free() { diff --git a/src/format.h b/src/format.h index b0664e7..019924c 100644 --- a/src/format.h +++ b/src/format.h @@ -3,7 +3,7 @@ #include "utils.h" -//#define TR1_DEMO +#define TR1_DEMO namespace TR { #define DATA_PORTAL 0x01 diff --git a/src/game.h b/src/game.h index 1550bc3..1b2d76f 100644 --- a/src/game.h +++ b/src/game.h @@ -11,8 +11,8 @@ namespace Game { Level *level; void init() { - Core::init(); - level = new Level("data\\GYM.PHD"); + Core::init(); + level = new Level("data\\LEVEL2_DEMO.PHD"); } void free() { diff --git a/src/input.h b/src/input.h index 41a4b0e..6f63898 100644 --- a/src/input.h +++ b/src/input.h @@ -59,6 +59,7 @@ namespace Input { case ikMouseM : mouse.start.M = mouse.pos; break; case ikTouchA : touch.start.A = touch.A; break; case ikTouchB : touch.start.B = touch.B; break; + default : ; } down[key] = value; @@ -76,6 +77,7 @@ namespace Input { case ikJoyDP : joy.DP = pos.x; break; case ikTouchA : touch.A = pos; break; case ikTouchB : touch.B = pos; break; + default : ; } } } diff --git a/src/level.h b/src/level.h index 7c4ff3f..5f8b816 100644 --- a/src/level.h +++ b/src/level.h @@ -6,7 +6,10 @@ #include "format.h" #include "controller.h" #include "camera.h" -#include "debug.h" + +#ifdef _DEBUG + #include "debug.h" +#endif const char SHADER[] = #include "shader.glsl" @@ -187,7 +190,7 @@ struct Level { vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z }; vertices[vCount].color = { a, a, a, 255 }; 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++; } } @@ -215,7 +218,7 @@ struct Level { vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z }; vertices[vCount].color = { a, a, a, 255 }; 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++; } } @@ -284,7 +287,7 @@ struct Level { vertices[vCount].normal = { 0, 0, 0, 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++; } } @@ -320,7 +323,7 @@ struct Level { vertices[vCount].normal = { 0, 0, 0, 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++; } } @@ -488,6 +491,7 @@ struct Level { p[3] = right * sprite.r + up * sprite.t; // bindTexture(sprite.tile); + /* glBegin(GL_QUADS); glTexCoord2f(u0, v1); glVertex3fv((GLfloat*)&p[0]); @@ -498,11 +502,13 @@ struct Level { glTexCoord2f(u0, v0); glVertex3fv((GLfloat*)&p[3]); glEnd(); + */ } void renderSprite(const TR::Room &room, const TR::Room::Data::Sprite &sprite) { auto &v = room.data.vertices[sprite.vertex]; float a = 1.0f - v.lighting / (float)0x1FFF; + /* glColor3f(a, a, a); glPushMatrix(); @@ -511,6 +517,7 @@ struct Level { renderSprite(level.spriteTextures[sprite.texture]); glPopMatrix(); + */ } vec3 getAngle(TR::AnimFrame *frame, int index) { @@ -702,6 +709,7 @@ struct Level { Core::mModel = m; } + #ifdef _DEBUG void debugPortals() { Core::setBlending(bmAdd); glColor3f(0, 0.25f, 0.25f); @@ -898,7 +906,7 @@ struct Level { } glEnd(); } - + #endif /* void debugEntity() { Core::setCulling(cfNone); @@ -996,11 +1004,8 @@ struct Level { shader->setParam(uViewProj, Core::mViewProj); shader->setParam(uModel, Core::mModel); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.9f); - glEnable(GL_DEPTH_TEST); - Core::setCulling(cfFront); + glEnable(GL_DEPTH_TEST); Core::mModel.identity(); diff --git a/src/shader.glsl b/src/shader.glsl index f877bba..2cd9e98 100644 --- a/src/shader.glsl +++ b/src/shader.glsl @@ -29,7 +29,10 @@ varying vec4 vColor; uniform vec4 uLightColor; 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 color.xyz = pow(color.xyz, vec3(2.2)); float lum = dot(normalize(vNormal.xyz), normalize(vLightVec)); diff --git a/src/utils.h b/src/utils.h index d9478e9..bcceb14 100644 --- a/src/utils.h +++ b/src/utils.h @@ -131,23 +131,23 @@ struct quat { w = cosf(angle); } - quat quat::operator - () const { + quat operator - () const { 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); } - 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); } - quat quat::operator * (const float s) const { + quat operator * (const float s) const { 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, w * q.y + y * q.w + z * q.x - x * q.z, w * q.z + z * q.w + x * q.y - y * q.x, @@ -166,19 +166,19 @@ struct quat { return sqrtf(length2()); } - void quat::normalize() { + void normalize() { *this = normal(); } - quat quat::normal() const { + quat normal() const { return *this * (1.0f / length()); } - quat quat::conjugate() const { + quat conjugate() const { return quat(-x, -y, -z, w); } - quat quat::inverse() const { + quat inverse() const { return conjugate() * (1.0f / length2()); } @@ -382,7 +382,7 @@ struct mat4 { return r; } - quat mat4::getRot() const { + quat getRot() const { float t, s; t = 1.0f + e00 + e11 + e22; 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, sy = rot.y * rot.y, sz = rot.z * rot.z, @@ -430,11 +430,11 @@ struct mat4 { e12 = (t1 - t2) * inv; } - vec3 mat4::getPos() const { + vec3 getPos() const { return offset.xyz; } - void mat4::setPos(const vec3 &pos) { + void setPos(const vec3 &pos) { offset.xyz = pos; } }; diff --git a/src/web/build.bat b/src/web/build.bat new file mode 100644 index 0000000..326d1d6 --- /dev/null +++ b/src/web/build.bat @@ -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..\ \ No newline at end of file diff --git a/src/web/index.html b/src/web/index.html new file mode 100644 index 0000000..0a806ff --- /dev/null +++ b/src/web/index.html @@ -0,0 +1,77 @@ + + OpenLara + + Starting... +

+
+ + + + + + \ No newline at end of file diff --git a/src/web/main.cpp b/src/web/main.cpp new file mode 100644 index 0000000..12e8a16 --- /dev/null +++ b/src/web/main.cpp @@ -0,0 +1,190 @@ +#include +#include + +#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; +} \ No newline at end of file