diff --git a/src/core.h b/src/core.h
index 5b10df2..5df244b 100644
--- a/src/core.h
+++ b/src/core.h
@@ -212,6 +212,7 @@ namespace Core {
bool depthTexture;
bool shadowSampler;
bool discardFrame;
+ bool texNPOT;
bool texFloat, texFloatLinear;
bool texHalf, texHalfLinear;
} support;
@@ -296,11 +297,12 @@ namespace Core {
char *ext = (char*)glGetString(GL_EXTENSIONS);
-
+ LOG("%s\n", ext);
support.VAO = extSupport(ext, "_vertex_array_object");
support.depthTexture = extSupport(ext, "_depth_texture");
- support.shadowSampler = false;//extSupport(ext, "_shadow_samplers") || extSupport(ext, "GL_ARB_shadow");
+ support.shadowSampler = extSupport(ext, "_shadow_samplers") || extSupport(ext, "GL_ARB_shadow");
support.discardFrame = extSupport(ext, "_discard_framebuffer");
+ support.texNPOT = extSupport(ext, "_texture_npot") || extSupport(ext, "_texture_non_power_of_two");
support.texFloatLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_float_linear");
support.texFloat = support.texFloatLinear || extSupport(ext, "_texture_float");
support.texHalfLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_half_float_linear");
@@ -316,6 +318,7 @@ namespace Core {
LOG(" depth texture : %s\n", support.depthTexture ? "true" : "false");
LOG(" shadow sampler : %s\n", support.shadowSampler ? "true" : "false");
LOG(" discard frame : %s\n", support.discardFrame ? "true" : "false");
+ LOG(" NPOT textures : %s\n", support.texNPOT ? "true" : "false");
LOG(" float textures : float = %s, half = %s\n",
support.texFloat ? (support.texFloatLinear ? "linear" : "nearest") : "false",
support.texHalf ? (support.texHalfLinear ? "linear" : "nearest") : "false");
@@ -401,7 +404,6 @@ namespace Core {
}
void setBlending(BlendMode mode) {
- mode = bmNone;
switch (mode) {
case bmNone :
glDisable(GL_BLEND);
diff --git a/src/game.h b/src/game.h
index 8123e79..49db3db 100644
--- a/src/game.h
+++ b/src/game.h
@@ -13,10 +13,9 @@ namespace Game {
level = new Level(*lvl, demo, home);
delete lvl;
- #ifndef __EMSCRIPTEN__
- //Sound::play(Sound::openWAD("05_Lara's_Themes.wav"), 1, 1, 0);
- Sound::play(snd, vec3(0.0f), 1, 1, Sound::Flags::LOOP);
- #endif
+
+ //Sound::play(Sound::openWAD("05_Lara's_Themes.wav"), 1, 1, 0);
+ Sound::play(snd, vec3(0.0f), 1, 1, Sound::Flags::LOOP);
}
void init(Stream *lvl, Stream *snd) {
@@ -27,8 +26,10 @@ namespace Game {
void init(char *lvlName = NULL, char *sndName = NULL) {
if (!lvlName) lvlName = (char*)"LEVEL2.PSX";
- if (!sndName) sndName = (char*)"05.ogg";
- init(new Stream(lvlName), new Stream(sndName));
+ #ifndef __EMSCRIPTEN__
+ if (!sndName) sndName = (char*)"05.ogg";
+ #endif
+ init(new Stream(lvlName), sndName ? new Stream(sndName) : NULL);
}
void free() {
diff --git a/src/lara.h b/src/lara.h
index 970de56..f20280d 100644
--- a/src/lara.h
+++ b/src/lara.h
@@ -405,7 +405,7 @@ struct Lara : Character {
if (level->extra.braid > -1)
braid = new Braid(this, vec3(-4.0f, 24.0f, -48.0f));
- //reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
+ reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
#ifdef _DEBUG
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, true); // gym (pool)
diff --git a/src/level.h b/src/level.h
index bd854dd..993e71e 100644
--- a/src/level.h
+++ b/src/level.h
@@ -31,6 +31,7 @@ const char GUI[] =
#define FOG_DIST (18 * 1024)
#define WATER_FOG_DIST (8 * 1024)
+//#define WATER_USE_GRID
struct Level : IGame {
TR::Level level;
@@ -89,6 +90,9 @@ struct Level : IGame {
for (int type = Shader::WATER_DROP; type <= Shader::WATER_COMPOSE; type++) {
sprintf(def, "%s#define WATER_%s\n#define WATER_FOG_DIST (1.0/%d.0)\n", ext, typeNames[type], WATER_FOG_DIST);
+ #ifdef WATER_USE_GRID
+ strcat(def, "#define WATER_USE_GRID %d\n");
+ #endif
shaders[getIndex(Core::passWater, Shader::Type(type), false)] = new Shader(WATER, def);
}
}
@@ -327,7 +331,7 @@ struct Level : IGame {
size = vec3(float((maxX - minX) * 512), 1.0f, float((maxZ - minZ) * 512)); // half size
pos = vec3(r.info.x + minX * 1024 + size.x, float(posY), r.info.z + minZ * 1024 + size.z);
- data[0] = new Texture(nextPow2(w * 64), nextPow2(h * 64), Texture::RGBA_HALF, false);
+ data[0] = new Texture(w * 64, h * 64, Texture::RGBA_HALF, false);
data[1] = new Texture(data[0]->width, data[0]->height, Texture::RGBA_HALF, false);
caustics = new Texture(512, 512, Texture::RGB16, false);
blank = false;
@@ -458,6 +462,8 @@ struct Level : IGame {
if (!dropCount) return;
level->setShader(Core::passWater, Shader::WATER_DROP, false);
+ Core::active.shader->setParam(uTexParam, vec4(1.0f / item.data[0]->width, 1.0f / item.data[0]->height, 1.0f, 1.0f));
+
vec3 rPosScale[2] = { vec3(0.0f), vec3(1.0f) };
Core::active.shader->setParam(uPosScale, rPosScale[0], 2);
@@ -482,6 +488,7 @@ struct Level : IGame {
if (item.timer < SIMULATE_TIMESTEP) return;
level->setShader(Core::passWater, Shader::WATER_STEP, false);
+ Core::active.shader->setParam(uTexParam, vec4(1.0f / item.data[0]->width, 1.0f / item.data[0]->height, 1.0f, 1.0f));
Core::active.shader->setParam(uParam, vec4(0.995f, 1.0f, 0, 0));
while (item.timer >= SIMULATE_TIMESTEP) {
@@ -522,7 +529,6 @@ struct Level : IGame {
level->setShader(Core::passWater, Shader::WATER_MASK, false);
Core::active.shader->setParam(uTexParam, vec4(1.0f));
- Core::setBlending(bmNone);
Core::setCulling(cfNone);
Core::setDepthWrite(false);
Core::setColorWrite(false, false, false, true);
@@ -543,7 +549,7 @@ struct Level : IGame {
// get refraction texture
if (!refract || Core::width > refract->width || Core::height > refract->height) {
delete refract;
- refract = new Texture(nextPow2(Core::width), nextPow2(Core::height), Texture::RGBA, false);
+ refract = new Texture(Core::width, Core::height, Texture::RGB16, false);
}
Core::copyTarget(refract, 0, 0, 0, 0, Core::width, Core::height); // copy framebuffer into refraction texture
@@ -583,7 +589,6 @@ struct Level : IGame {
item.mask->bind(sMask);
if (item.timer >= SIMULATE_TIMESTEP || dropCount) {
- Core::active.shader->setParam(uTexParam, vec4(1.0f / item.data[0]->width, 1.0f / item.data[0]->height, 1.0f, 1.0f));
// add water drops
drop(item);
// simulation step
@@ -603,7 +608,6 @@ struct Level : IGame {
level->setShader(Core::passWater, Shader::WATER_COMPOSE, false);
Core::active.shader->setParam(uViewProj, Core::mViewProj);
- Core::active.shader->setParam(uPosScale, item.pos, 2);
Core::active.shader->setParam(uViewPos, Core::viewPos);
Core::active.shader->setParam(uLightPos, Core::lightPos[0], 1);
Core::active.shader->setParam(uLightColor, Core::lightColor[0], 1);
@@ -613,19 +617,20 @@ struct Level : IGame {
float sx = item.size.x * DETAIL / (item.data[0]->width / 2);
float sz = item.size.z * DETAIL / (item.data[0]->height / 2);
- Core::active.shader->setParam(uTexParam, vec4(1.0f, 1.0f, sx, sz));
+ Core::active.shader->setParam(uTexParam, vec4(1.0f, 1.0f, sx, sz));
refract->bind(sDiffuse);
reflect->bind(sReflect);
item.data[0]->bind(sNormal);
Core::setCulling(cfNone);
- vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 512.0f, 1.0f / PLANE_DETAIL) };
- Core::active.shader->setParam(uPosScale, rPosScale[0], 2);
- // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- //level->mesh->renderQuad();
- level->mesh->renderPlane();
- // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
+ #ifdef WATER_USE_GRID
+ vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 512.0f, 1.0f / PLANE_DETAIL) };
+ Core::active.shader->setParam(uPosScale, rPosScale[0], 2);
+ level->mesh->renderPlane();
+ #else
+ Core::active.shader->setParam(uPosScale, item.pos, 2);
+ level->mesh->renderQuad();
+ #endif
Core::setCulling(cfFront);
}
dropCount = 0;
@@ -1150,6 +1155,7 @@ struct Level : IGame {
Shader::Type type = isModel ? Shader::ENTITY : Shader::SPRITE;
if (entity.type == TR::Entity::CRYSTAL)
type = Shader::MIRROR;
+
setRoomParams(entity.room, isModel ? controller->specular : intensityf(lum), type);
if (isModel) { // model
@@ -1197,9 +1203,6 @@ struct Level : IGame {
waterCache->update();
}
-
-
-
void setup() {
PROFILE_MARKER("SETUP");
@@ -1326,7 +1329,6 @@ struct Level : IGame {
Core::pass = Core::passShadow;
if (!setupLightCamera()) return;
shadow->unbind(sShadow);
- Core::setBlending(bmNone);
bool colorShadow = shadow->format == Texture::Format::RGBA ? true : false;
if (colorShadow)
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
@@ -1343,12 +1345,10 @@ struct Level : IGame {
PROFILE_MARKER("PASS_COMPOSE");
Core::pass = Core::passCompose;
- Core::setBlending(bmAlpha);
Core::setDepthTest(true);
Core::setDepthWrite(true);
shadow->bind(sShadow);
renderScene(roomIndex);
- Core::setBlending(bmNone);
}
void render() {
@@ -1443,7 +1443,7 @@ struct Level : IGame {
Core::setDepthTest(true);
-
+ /*
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
@@ -1452,7 +1452,10 @@ struct Level : IGame {
glLoadIdentity();
glOrtho(0, Core::width, 0, Core::height, 0, 1);
- shadow->bind(sDiffuse);
+ if (waterCache->count)
+ waterCache->refract->bind(sDiffuse);
+ else
+ atlas->bind(sDiffuse);
glEnable(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
@@ -1478,7 +1481,7 @@ struct Level : IGame {
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
-
+ */
Core::setBlending(bmAlpha);
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
diff --git a/src/platform/android/.classpath b/src/platform/android/.classpath
new file mode 100644
index 0000000..5176974
--- /dev/null
+++ b/src/platform/android/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/platform/android/.cproject b/src/platform/android/.cproject
new file mode 100644
index 0000000..ad856f2
--- /dev/null
+++ b/src/platform/android/.cproject
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/platform/android/.project b/src/platform/android/.project
new file mode 100644
index 0000000..e42855c
--- /dev/null
+++ b/src/platform/android/.project
@@ -0,0 +1,49 @@
+
+
+ OpenLara
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/src/platform/android/.settings/org.eclipse.cdt.codan.core.prefs b/src/platform/android/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100644
index 0000000..4cc82b1
--- /dev/null
+++ b/src/platform/android/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,72 @@
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=-Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=-Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.checkers.noreturn=-Error
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=-Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=-Warning
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+useParentScope=false
diff --git a/src/platform/android/.settings/org.eclipse.jdt.core.prefs b/src/platform/android/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b080d2d
--- /dev/null
+++ b/src/platform/android/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/src/platform/android/AndroidManifest.xml b/src/platform/android/AndroidManifest.xml
new file mode 100644
index 0000000..9061603
--- /dev/null
+++ b/src/platform/android/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/platform/android/jni/Android.mk b/src/platform/android/jni/Android.mk
new file mode 100644
index 0000000..2ccfd8e
--- /dev/null
+++ b/src/platform/android/jni/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH := $(call my-dir)
+SRC := ${LOCAL_PATH}/../../../../
+
+include $(CLEAR_VARS)
+
+#-ffunction-sections -fdata-sections #-frtti #-fexceptions #
+
+LOCAL_CFLAGS := -DANDROID -fvisibility=hidden
+LOCAL_LDFLAGS := -Wl,--gc-sections
+LOCAL_MODULE := game
+LOCAL_SRC_FILES := main.cpp\
+ $(SRC)libs/stb_vorbis/stb_vorbis.c\
+ $(SRC)libs/minimp3/minimp3.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../
+LOCAL_LDLIBS := -lGLESv2 -llog
+
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/src/platform/android/jni/Application.mk b/src/platform/android/jni/Application.mk
new file mode 100644
index 0000000..61a1d43
--- /dev/null
+++ b/src/platform/android/jni/Application.mk
@@ -0,0 +1,8 @@
+¹NDK_TOOLCHAIN_VERSION := 4.8
+NDK_TOOLCHAIN_VERSION := clang
+APP_ABI := armeabi-v7a
+# Enable C++11. However, pthread, rtti and exceptions aren’t enabled
+APP_CPPFLAGS += -std=c++11
+# Instruct to use the static GNU STL implementation
+#APP_STL := gnustl_static
+LOCAL_C_INCLUDES += ${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.8/include
\ No newline at end of file
diff --git a/src/platform/android/jni/main.cpp b/src/platform/android/jni/main.cpp
new file mode 100644
index 0000000..ab167fc
--- /dev/null
+++ b/src/platform/android/jni/main.cpp
@@ -0,0 +1,145 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "game.h"
+
+int getTime() {
+ timeval time;
+ gettimeofday(&time, NULL);
+ return (time.tv_sec * 1000) + (time.tv_usec / 1000);
+}
+
+extern "C" {
+
+int lastTime, fpsTime, fps;
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeInit(JNIEnv* env, jobject obj, jstring packName, jint levelOffset, jint musicOffset) {
+ LOG("native init");
+ const char* pack = env->GetStringUTFChars(packName, NULL);
+ Stream *level = new Stream(pack);
+ Stream *music = new Stream(pack);
+ level->seek(levelOffset);
+ music->seek(musicOffset);
+ env->ReleaseStringUTFChars(packName, pack);
+ LOG("game init");
+
+ Game::init(level, music);
+ LOG("done");
+
+ lastTime = getTime();
+ fpsTime = lastTime + 1000;
+ fps = 0;
+ LOG("init");
+}
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeFree(JNIEnv* env) {
+ Game::free();
+}
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeReset(JNIEnv* env) {
+// core->reset();
+}
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeUpdate(JNIEnv* env) {
+ int time = getTime();
+ if (time == lastTime)
+ return;
+
+ float delta = min(1.0f, (time - lastTime) * 0.001f);
+ while (delta > EPS) {
+ Core::deltaTime = min(delta, 1.0f / 30.0f);
+ Game::update();
+ delta -= Core::deltaTime;
+ }
+ lastTime = time;
+}
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeRender(JNIEnv* env) {
+ Core::stats.dips = 0;
+ Core::stats.tris = 0;
+ Game::render();
+ if (fpsTime < getTime()) {
+ LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
+ fps = 0;
+ fpsTime = getTime() + 1000;
+ } else
+ fps++;
+}
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeResize(JNIEnv* env, jobject obj, jint w, jint h) {
+ Core::width = w;
+ Core::height = h;
+}
+
+float DeadZone(float x) {
+ return x = fabsf(x) < 0.2f ? 0.0f : x;
+}
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeTouch(JNIEnv* env, jobject obj, jint id, jint state, jfloat x, jfloat y) {
+ if (id > 1) return;
+/* gamepad
+ if (state < 0) {
+ state = -state;
+ Input::Joystick &joy = Input::joy;
+
+ switch (state) {
+ case 3 :
+ joy.L.x = DeadZone(x);
+ joy.L.y = DeadZone(y);
+ break;
+ case 4 :
+ joy.R.x = DeadZone(x);
+ joy.R.y = DeadZone(y);
+ break;
+ default:
+ joy.down[(int)x] = state != 1;
+ }
+ return;
+ }
+*/
+ if (state == 3 && x < Core::width / 2) {
+ vec2 center(Core::width * 0.25f, Core::height * 0.6f);
+ vec2 pos(x, y);
+ vec2 d = pos - center;
+
+ float angle = atan2(d.x, -d.y) + PI * 0.125f;
+ if (angle < 0.0f) angle += PI2;
+ int pov = int(angle / (PI * 0.25f));
+
+ Input::setPos(ikJoyPOV, vec2(float(1 + pov), 0.0f));
+ };
+
+ if (state == 2 && x > Core::width / 2) {
+ int i = y / (Core::height / 3);
+ InputKey key;
+ if (i == 0)
+ key = ikJoyX;
+ else if (i == 1)
+ key = ikJoyA;
+ else
+ key = ikJoyY;
+ Input::setDown(key, true);
+ }
+
+ if (state == 1) {
+ Input::setPos(ikJoyPOV, vec2(0.0f));
+ Input::setDown(ikJoyA, false);
+ Input::setDown(ikJoyX, false);
+ Input::setDown(ikJoyY, false);
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeSoundFill(JNIEnv* env, jobject obj, jshortArray buffer) {
+ jshort *frames = env->GetShortArrayElements(buffer, NULL);
+ jsize count = env->GetArrayLength(buffer) / 2;
+ Sound::fill((Sound::Frame*)frames, count);
+ env->ReleaseShortArrayElements(buffer, frames, 0);
+}
+
+}
+
+
diff --git a/src/platform/android/lint.xml b/src/platform/android/lint.xml
new file mode 100644
index 0000000..d8916ff
--- /dev/null
+++ b/src/platform/android/lint.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/platform/android/proguard-project.txt b/src/platform/android/proguard-project.txt
new file mode 100644
index 0000000..515bc2d
--- /dev/null
+++ b/src/platform/android/proguard-project.txt
@@ -0,0 +1,144 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+#Use 5 step of optimization
+-optimizationpasses 5
+
+#When not preverifing in a case-insensitive filing system, such as Windows. This tool will unpack your processed jars,(if using windows you should then use):
+-dontusemixedcaseclassnames
+
+#Specifies not to ignore non-public library classes. As of version 4.5, this is the default setting
+-dontskipnonpubliclibraryclasses
+
+# Optimization is turned off by default. Dex does not like code run
+# through the ProGuard optimize and preverify steps (and performs some
+# of these optimizations on its own).
+-dontoptimize
+-dontpreverify
+
+-dontwarn android.support.**
+
+#Specifies to write out some more information during processing. If the program terminates with an exception, this option will print out the entire stack trace, instead of just the exception message.
+-verbose
+
+#The -optimizations option disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle. Note that the Dalvik VM also can't handle aggressive overloading (of static fields).
+#To understand or change this check http://proguard.sourceforge.net/index.html#/manual/optimizations.html
+#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+# Note that if you want to enable optimization, you cannot just
+# include optimization flags in your own project configuration file;
+# instead you will need to point to the
+# "proguard-android-optimize.txt" file instead of this one from your
+# project.properties file.
+
+#To repackage classes on a single package
+#-repackageclasses ''
+
+#Uncomment if using annotations to keep them.
+#-keepattributes *Annotation*
+
+#Keep classes that are referenced on the AndroidManifest
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+#-keep public class * extends android.app.Service
+#-keep public class * extends android.content.BroadcastReceiver
+#-keep public class * extends android.content.ContentProvider
+#-keep public class * extends android.app.backup.BackupAgentHelper
+#-keep public class * extends android.preference.Preference
+#-keep public class com.google.vending.licensing.ILicensingService
+#-keep public class com.android.vending.licensing.ILicensingService
+#Compatibility library
+#-keep public class * extends android.support.v4.app.Fragment
+#-keep public class * extends android.app.Fragment
+
+#To maintain custom components names that are used on layouts XML.
+#Uncomment if having any problem with the approach below
+#-keep public class custom.components.package.and.name.**
+
+# keep setters in Views so that animations can still work.
+# see http://proguard.sourceforge.net/manual/examples.html#beans
+ -keepclassmembers public class * extends android.view.View {
+ void set*(***);
+ *** get*();
+}
+
+#To remove debug logs:
+-assumenosideeffects class android.util.Log {
+ public static *** d(...);
+ public static *** v(...);
+ public static *** w(...);
+}
+
+#To avoid changing names of methods invoked on layout's onClick.
+# Uncomment and add specific method names if using onClick on layouts
+#-keepclassmembers class * {
+# public void onClickButton(android.view.View);
+#}
+
+#Maintain java native methods
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+
+#To maintain custom components names that are used on layouts XML:
+-keep public class * extends android.view.View {
+ public (android.content.Context);
+}
+-keep public class * extends android.view.View {
+ public (android.content.Context, android.util.AttributeSet);
+}
+-keep public class * extends android.view.View {
+ public (android.content.Context, android.util.AttributeSet, int);
+}
+
+#Maintain enums
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+#To keep parcelable classes (to serialize - deserialize objects to sent through Intents)
+#-keep class * implements android.os.Parcelable {
+# public static final android.os.Parcelable$Creator *;
+#}
+
+#Keep the R
+-keepclassmembers class **.R$* {
+ public static ;
+}
+
+###### ADDITIONAL OPTIONS NOT USED NORMALLY
+
+#To keep callback calls. Uncomment if using any
+#http://proguard.sourceforge.net/index.html#/manual/examples.html#callback
+#-keep class mypackage.MyCallbackClass {
+# void myCallbackMethod(java.lang.String);
+#}
+
+#Uncomment if using Serializable
+#-keepclassmembers class * implements java.io.Serializable {
+# private static final java.io.ObjectStreamField[] serialPersistentFields;
+# private void writeObject(java.io.ObjectOutputStream);
+# private void readObject(java.io.ObjectInputStream);
+# java.lang.Object writeReplace();
+# java.lang.Object readResolve();
+#}
\ No newline at end of file
diff --git a/src/platform/android/project.properties b/src/platform/android/project.properties
new file mode 100644
index 0000000..cf667f3
--- /dev/null
+++ b/src/platform/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-14
diff --git a/src/platform/android/res/drawable-hdpi/ic_launcher.png b/src/platform/android/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/src/platform/android/res/drawable-hdpi/ic_launcher.png differ
diff --git a/src/platform/android/res/drawable-mdpi/ic_launcher.png b/src/platform/android/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/src/platform/android/res/drawable-mdpi/ic_launcher.png differ
diff --git a/src/platform/android/res/drawable-xhdpi/ic_launcher.png b/src/platform/android/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/src/platform/android/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/src/platform/android/res/values/strings.xml b/src/platform/android/res/values/strings.xml
new file mode 100644
index 0000000..10621b5
--- /dev/null
+++ b/src/platform/android/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+
+ OpenLara
+
+
diff --git a/src/platform/android/src/org/xproger/openlara/MainActivity.java b/src/platform/android/src/org/xproger/openlara/MainActivity.java
new file mode 100644
index 0000000..438e88e
--- /dev/null
+++ b/src/platform/android/src/org/xproger/openlara/MainActivity.java
@@ -0,0 +1,306 @@
+package org.xproger.openlara;
+
+import java.util.ArrayList;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Bundle;
+import android.app.Activity;
+import android.content.res.AssetFileDescriptor;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnGenericMotionListener;
+import android.view.View.OnKeyListener;
+import android.view.View.OnTouchListener;
+import android.view.Window;
+import android.view.WindowManager;
+
+public class MainActivity extends Activity implements OnTouchListener, OnGenericMotionListener, OnKeyListener {
+ private GLSurfaceView view;
+ private Wrapper wrapper;
+ private SparseIntArray joys = new SparseIntArray();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
+ WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
+ WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
+
+ super.onCreate(savedInstanceState);
+
+ view = new GLSurfaceView(this);
+ view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
+ view.setEGLContextClientVersion(2);
+ view.setRenderer(wrapper = new Wrapper());
+
+ view.setFocusable(true);
+ view.setFocusableInTouchMode(true);
+
+ view.setOnTouchListener(this);
+ view.setOnGenericMotionListener(this);
+ view.setOnKeyListener(this);
+
+ setContentView(view);
+ try {
+ String packName = getPackageManager().getPackageInfo(getPackageName(), 1).applicationInfo.sourceDir;
+ AssetFileDescriptor fLevel = this.getResources().openRawResourceFd(R.raw.level2);
+ AssetFileDescriptor fMusic = this.getResources().openRawResourceFd(R.raw.music);
+
+ wrapper.onCreate(packName, (int)fLevel.getStartOffset(), (int)fMusic.getStartOffset());
+ } catch (Exception e) {
+ e.printStackTrace();
+ finish();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ wrapper.onDestroy();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ wrapper.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ wrapper.onResume();
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ int action = event.getAction();
+ int type = action & MotionEvent.ACTION_MASK;
+ int state;
+
+ switch (type) {
+ case MotionEvent.ACTION_DOWN :
+ case MotionEvent.ACTION_UP :
+ case MotionEvent.ACTION_MOVE :
+ state = type == MotionEvent.ACTION_MOVE ? 3 : (type == MotionEvent.ACTION_DOWN ? 2 : 1);
+ for (int i = 0; i < event.getPointerCount(); i++)
+ wrapper.onTouch(event.getPointerId(i), state, event.getX(i), event.getY(i));
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN :
+ case MotionEvent.ACTION_POINTER_UP :
+ int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ state = type == MotionEvent.ACTION_POINTER_DOWN ? 2 : 1;
+ wrapper.onTouch(event.getPointerId(i), state, event.getX(i), event.getY(i));
+ break;
+ }
+ return true;
+ }
+
+ private int getJoyIndex(InputDevice dev) {
+ int src = dev.getSources();
+ if ((src & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
+ (src & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK) {
+
+ int id = dev.getId();
+ int index = joys.get(id, -1);
+
+ if (index == -1) {
+ index = joys.size();
+ joys.append(id, index);
+ }
+ return index;
+ }
+ return -1;
+ }
+
+ @Override
+ public boolean onGenericMotion(View v, MotionEvent event) {
+ int index = getJoyIndex(event.getDevice());
+ if (index == -1) return false;
+
+ wrapper.onTouch(index, -3, event.getAxisValue(MotionEvent.AXIS_X),
+ event.getAxisValue(MotionEvent.AXIS_Y));
+
+ wrapper.onTouch(index, -4, event.getAxisValue(MotionEvent.AXIS_Z),
+ event.getAxisValue(MotionEvent.AXIS_RZ));
+
+ return true;
+ }
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ int index = getJoyIndex(event.getDevice());
+ if (index == -1) return false;
+
+ int btn;
+
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BUTTON_A : btn = 0; break;
+ case KeyEvent.KEYCODE_BUTTON_B : btn = 1; break;
+ case KeyEvent.KEYCODE_BUTTON_X : btn = 2; break;
+ case KeyEvent.KEYCODE_BUTTON_Y : btn = 3; break;
+ default : btn = -1;
+ }
+
+ if (btn != -1) {
+ wrapper.onTouch(index, event.getAction() == KeyEvent.ACTION_DOWN ? -2 : -1, btn, 0);
+ return true;
+ }
+ return false;
+ }
+
+ static {
+ System.loadLibrary("game");
+ }
+}
+
+class Sound {
+ private short buffer[];
+ private static AudioTrack audioTrack;
+
+ public void start(final Wrapper wrapper) {
+ int bufferSize = AudioTrack.getMinBufferSize(22050, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT);
+ System.out.println(String.format("sound buffer size: %d", bufferSize));
+
+ buffer = new short [bufferSize / 2];
+ audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
+ 44100,
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT,
+ bufferSize,
+ AudioTrack.MODE_STREAM);
+ audioTrack.play();
+
+ new Thread( new Runnable() {
+ public void run() {
+ while ( audioTrack.getPlayState() != AudioTrack.PLAYSTATE_STOPPED ) {
+ if (audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING && wrapper.ready) {
+ synchronized (wrapper) {
+ Wrapper.nativeSoundFill(buffer);
+ }
+ audioTrack.write(buffer, 0, buffer.length);
+ audioTrack.flush();
+ } else
+ try {
+ Thread.sleep(100);
+ } catch(Exception e) {
+ //
+ };
+ }
+ }
+ } ).start();
+ }
+
+ public void stop() {
+ audioTrack.flush();
+ audioTrack.stop();
+ audioTrack.release();
+ }
+
+ public void play() {
+ audioTrack.play();
+ }
+
+ public void pause() {
+ audioTrack.pause();
+ }
+}
+
+class Touch {
+ int id, state;
+ float x, y;
+ public Touch(int _id, int _state, float _x, float _y) {
+ id = _id;
+ state = _state;
+ x = _x;
+ y = _y;
+ };
+}
+
+class Wrapper implements Renderer {
+ public static native void nativeInit(String packName, int levelOffset, int musicOffset);
+ public static native void nativeFree();
+ public static native void nativeReset();
+ public static native void nativeResize(int w, int h);
+ public static native void nativeUpdate();
+ public static native void nativeRender();
+ public static native void nativeTouch(int id, int state, float x, float y);
+ public static native void nativeSoundFill(short buffer[]);
+
+ public Boolean ready = false;
+ private String packName;
+ private int levelOffset;
+ private int musicOffset;
+ private ArrayList touch = new ArrayList();
+ private Sound sound;
+
+ public void onCreate(String packName, int levelOffset, int musicOffset) {
+ this.packName = packName;
+ this.levelOffset = levelOffset;
+ this.musicOffset = musicOffset;
+
+ sound = new Sound();
+ sound.start(this);
+ }
+
+ public void onDestroy() {
+ sound.stop();
+ nativeFree();
+ }
+
+ public void onPause() {
+ sound.pause();
+ }
+
+ public void onResume() {
+ sound.play();
+ if (ready) nativeReset();
+ }
+
+ public void onTouch(int id, int state, float x, float y) {
+ synchronized (this) {
+ touch.add(new Touch(id, state, x, y));
+ }
+ }
+
+ @Override
+ public void onDrawFrame(GL10 gl) {
+ synchronized (this) {
+ for (int i = 0; i < touch.size(); i++) {
+ Touch t = touch.get(i);
+ nativeTouch(t.id, t.state, t.x, t.y);
+ }
+ touch.clear();
+ nativeUpdate();
+ }
+ nativeRender();
+ }
+
+ @Override
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ nativeResize(width, height);
+ }
+
+ @Override
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ if (!ready) {
+ nativeInit(packName, levelOffset, musicOffset);
+ sound.play();
+ ready = true;
+ }
+ }
+}
diff --git a/src/platform/web/build.bat b/src/platform/web/build.bat
index 91ab70e..28c84f5 100644
--- a/src/platform/web/build.bat
+++ b/src/platform/web/build.bat
@@ -6,4 +6,4 @@ set FLAGS=-O3 -Wno-deprecated-register --llvm-opts 2 -fmax-type-align=2 -std=c++
set PRELOAD=./LEVEL2.PSX
echo.
call em++ %SRC% %FLAGS% -o %PROJ%.js --preload-file %PRELOAD%
-gzip.exe -9 -f %PROJ%.data %PROJ%.js %PROJ%.js.mem
\ No newline at end of file
+ggzip.exe -9 -f %PROJ%.data %PROJ%.js %PROJ%.js.mem
\ No newline at end of file
diff --git a/src/shader.glsl b/src/shader.glsl
index 7665e12..7195aa2 100644
--- a/src/shader.glsl
+++ b/src/shader.glsl
@@ -213,7 +213,11 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
vec3 lv = uLightPos[0].xyz - vCoord.xyz;
float fade = clamp(dot(lv, lv) / uLightColor[0].w, 0.0, 1.0);
- return clamp(mix(rShadow, 1.0, fade), -lightProj.w, 1.0);
+ return mix(rShadow, 1.0, fade);
+ }
+
+ float getShadow() {
+ return min(dot(vNormal.xyz, uLightPos[0].xyz - vCoord), vLightProj.w) > 0.0 ? getShadow(vLightProj) : 1.0;
}
vec3 calcLight(vec3 normal, vec3 pos, vec4 color) {
@@ -272,16 +276,19 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
void main() {
#ifndef PASS_SHADOW
#ifndef PASS_AMBIENT
- if (vCoord.y * uParam.z > uParam.w)
- discard;
+ #if defined(TYPE_ENTITY) && defined(CAUSTICS)
+ if (vCoord.y * uParam.z > uParam.w)
+ discard;
+ #endif
#endif
#endif
vec4 color = texture2D(sDiffuse, vTexCoord.xy);
-// if (color.w <= 0.6) {
-// discard;
-// }
+ #ifdef ALPHA_TEST
+ if (color.w <= 0.6)
+ discard;
+ #endif
#ifdef PASS_SHADOW
#ifdef SHADOW_COLOR
@@ -320,26 +327,20 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
#endif
#ifdef TYPE_ROOM
- float rShadow = dot(normal, uLightPos[0].xyz - vCoord) > 0.0 ? getShadow(vLightProj) : 1.0;
- //light += calcLight(normal, uLightPos[0], uLightColor[0]);
- light += mix(min(uColor.w, vColor.w), vColor.w, rShadow);
+ light += mix(min(uColor.w, vColor.w), vColor.w, getShadow());
#ifdef CAUSTICS
light += calcCaustics(normal);
#endif
-//color.xyz = vec3(rShadow);
-//light.xyz = vec3(1.0);
#endif
#ifdef TYPE_ENTITY
vec3 rAmbient = calcAmbient(normal);
- float rShadow = getShadow(vLightProj);
+ float rShadow = getShadow();
light += calcLight(normal, uLightPos[0], uLightColor[0]) * rShadow + rAmbient;
color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], uColor.w * rShadow + 0.03);
#ifdef CAUSTICS
light += calcCaustics(normal);
#endif
-//color.xyz = vec3(rShadow);
-//light.xyz = vec3(1.0);
#endif
#ifdef TYPE_MIRROR
diff --git a/src/texture.h b/src/texture.h
index 0028132..769dfb2 100644
--- a/src/texture.h
+++ b/src/texture.h
@@ -11,7 +11,14 @@ struct Texture {
Format format;
bool cube;
- Texture(int width, int height, Format format, bool cube, void *data = NULL, bool filter = true) : width(width), height(height), cube(cube) {
+ Texture(int width, int height, Format format, bool cube, void *data = NULL, bool filter = true) : cube(cube) {
+ if (!Core::support.texNPOT) {
+ width = nextPow2(width);
+ height = nextPow2(height);
+ }
+ this->width = width;
+ this->height = height;
+
glGenTextures(1, &ID);
bind(0);
diff --git a/src/utils.h b/src/utils.h
index 9942961..e78b62f 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -733,7 +733,7 @@ struct Stream {
#else
f = fopen(name, "rb");
#endif
- if (!f) LOG("error loading file\n");
+ if (!f) LOG("error loading file \"%s\"\n", name);
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
diff --git a/src/water.glsl b/src/water.glsl
index 48d2d55..db0d347 100644
--- a/src/water.glsl
+++ b/src/water.glsl
@@ -11,13 +11,7 @@ varying vec4 vOldPos;
varying vec4 vNewPos;
varying vec3 vViewVec;
varying vec3 vLightVec;
-/*
-#define WATER_DROP 0
-#define WATER_STEP 1
-#define WATER_CAUSTICS 2
-#define WATER_MASK 3
-#define WATER_COMPOSE 4
-*/
+
uniform vec3 uViewPos;
uniform mat4 uViewProj;
uniform vec3 uLightPos;
@@ -43,8 +37,10 @@ uniform sampler2D sNormal;
float height = 0.0;
#ifdef WATER_COMPOSE
- vTexCoord = (aCoord.xy * (1.0 / 48.0) * 0.5 + 0.5) * uTexParam.zw;
- height = texture2D(sNormal, vTexCoord).x;
+ #ifdef WATER_USE_GRID
+ vTexCoord = (aCoord.xy * (1.0 / 48.0) * 0.5 + 0.5) * uTexParam.zw;
+ height = texture2D(sNormal, vTexCoord).x;
+ #endif
#endif
vCoord = vec3(aCoord.x, height, aCoord.y) * uPosScale[1] + uPosScale[0];
@@ -177,29 +173,28 @@ uniform sampler2D sNormal;
return color;
}
- vec4 pass() {
- return
+ vec4 pass() {
#ifdef WATER_DROP
- drop();
+ return drop();
#endif
#ifdef WATER_STEP
- calc();
+ return calc();
#endif
#ifdef WATER_CAUSTICS
- caustics();
+ return caustics();
#endif
#ifdef WATER_MASK
- mask();
+ return mask();
#endif
#ifdef WATER_COMPOSE
- compose();
+ return compose();
#endif
- vec4(1.0, 0.0, 0.0, 1.0);
+ return vec4(1.0, 0.0, 1.0, 1.0);
}
void main() {