diff --git a/game/Android.mk b/game/Android.mk new file mode 100644 index 0000000..4734ddb --- /dev/null +++ b/game/Android.mk @@ -0,0 +1,77 @@ +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +LPATH := $(call my-dir) + +ENGINE_PATH = $(SalmonEnginePathCygwin) + +BOOST_PATH = $(LibsPathCygwin)/boost_1_47_0 + +OGG_PATH = $(LibsPathCygwin)/libogg-1.3.0 + +VORBIS_PATH = $(LibsPathCygwin)/libvorbis-1.3.2 + +SQUIRREL_PATH = $(LibsPathCygwin)/sqplus + +LIBPNG_PATH = $(LibsPathCygwin)/libpng_1.4.1_android + +ZIP_PATH = $(LibsPathCygwin)/julienr-libzip-android/jni + +#====== ENGINE AND LIBS ===================== + +include $(ENGINE_PATH)/Android_Salmon_Engine.mk + +#================= THE GAME ======================= + + +LOCAL_PATH:= $(LPATH) + +include $(CLEAR_VARS) + +LOCAL_CFLAGS := -DTARGET_ANDROID -DNOSOUND -DTARGET_SALMON -std=gnu++11 --std=c++11 +LOCAL_STATIC_LIBRARIES := boost +LOCAL_STATIC_LIBRARIES += squirrel +LOCAL_STATIC_LIBRARIES += png_lib +LOCAL_STATIC_LIBRARIES += zip +LOCAL_SHARED_LIBRARIES := SalmonEngine +LOCAL_SHARED_LIBRARIES += gnustl_shared +LOCAL_C_INCLUDES := $(ENGINE_PATH) +LOCAL_C_INCLUDES += $(BOOST_PATH) +LOCAL_C_INCLUDES += $(VORBIS_PATH)/include +LOCAL_C_INCLUDES += $(VORBIS_PATH)/include/vorbis +LOCAL_C_INCLUDES += $(VORBIS_PATH)/lib +LOCAL_C_INCLUDES += $(VORBIS_PATH)/lib/books +LOCAL_C_INCLUDES += $(VORBIS_PATH)/lib/modes +LOCAL_C_INCLUDES += $(OGG_PATH)/include +LOCAL_C_INCLUDES += $(OGG_PATH)/include/ogg +LOCAL_C_INCLUDES += $(SQUIRREL_PATH)/include +LOCAL_C_INCLUDES += $(SQUIRREL_PATH)/sqplus +LOCAL_C_INCLUDES += $(SQUIRREL_PATH)/squirrel +LOCAL_C_INCLUDES += $(SQUIRREL_PATH)/sqstdlib +LOCAL_C_INCLUDES += $(LIBPNG_PATH) +LOCAL_C_INCLUDES += $(ZIP_PATH) +LOCAL_MODULE := SalmonJniTemplate +LOCAL_SRC_FILES := main_code.cpp +LOCAL_SRC_FILES += android_api.cpp + +LOCAL_LDLIBS := -lGLESv2 +LOCAL_LDLIBS += -llog -Wl + +#debug +#LOCAL_CFLAGS += -g -ggdb -O0 +#LOCAL_LDLIBS += -g -ggdb + +include $(BUILD_SHARED_LIBRARY) diff --git a/game/Application.mk b/game/Application.mk new file mode 100644 index 0000000..9bd01d8 --- /dev/null +++ b/game/Application.mk @@ -0,0 +1,3 @@ +APP_STL := gnustl_shared +APP_CPPFLAGS += -fexceptions +APP_CPPFLAGS += -frtti diff --git a/game/android_api.cpp b/game/android_api.cpp new file mode 100755 index 0000000..45453ec --- /dev/null +++ b/game/android_api.cpp @@ -0,0 +1,11 @@ +#include "android_api.h" + +#include "boost/thread.hpp" + +#include "main_code.h" + +JNIEXPORT void JNICALL Java_fishrungames_tunnel_JniWrapper_Init(JNIEnv * env, jobject obj, jint width, jint height) +{ + JniInitApp(width, height, 320.f, 480.f); +} + diff --git a/game/android_api.h b/game/android_api.h new file mode 100755 index 0000000..03bda67 --- /dev/null +++ b/game/android_api.h @@ -0,0 +1,23 @@ +#ifndef ANDROID_API_H_INCLUDED +#define ANDROID_API_H_INCLUDED + +#include +#include + +#include +#include +#include + +#include "boost/shared_ptr.hpp" + +#include "main_code.h" + +using namespace SE; + + +extern "C" { + JNIEXPORT void JNICALL Java_fishrungames_tunnel_JniWrapper_Init(JNIEnv * env, jobject obj, jint width, jint height); +}; + + +#endif diff --git a/game/main_code.cpp b/game/main_code.cpp new file mode 100755 index 0000000..4c7ffb6 --- /dev/null +++ b/game/main_code.cpp @@ -0,0 +1,436 @@ +#include "main_code.h" + +#ifdef TARGET_ANDROID +#include "android_api.h" +#endif + +#include +#include +#include +#include + +#include "include/Engine.h" + +#include "main_code.h" + +const int CONST_TUBE_COUNT = 6; + +const int CONST_MAX_BOXES = 50; + +const float CONST_VELOCITY = 2.f; + +int countTubes = 0; + +TFlexModel GenerateFlexModel(int i) +{ + countTubes++; + + if (countTubes <= 5) + { + return ResourceManager->FlexModelManager.InstanciateModel("tube1.xml"); + } + else + { + return ResourceManager->FlexModelManager.InstanciateModel("tube"+tostr(i+1)+".xml"); + } +} + +TFlexModel GeneratePhysicsModel(int i) +{ + countTubes++; + + if (countTubes <= 5) + { + return ResourceManager->FlexModelManager.InstanciateModel("tube1_physics.xml"); + } + else + { + return ResourceManager->FlexModelManager.InstanciateModel("tube"+tostr(i+1)+"_physics.xml"); + } +} + + +void TMyApplication::InnerInit() +{ + + *Console<<"Inner init go!\n"; + +#ifdef TARGET_ANDROID + ST::PathToResources = ""; +#endif +#ifdef TARGET_WIN32 +#ifdef NDEBUG + ST::PathToResources = "resources/"; +#else + ST::PathToResources = "../../../assets/"; +#endif +#endif +#ifdef TARGET_IOS + ST::PathToResources = "assets/"; +#endif + + ResourceManager->TexList.AddTexture(CONST_CONSOLE_TEX_NAME); + + ResourceManager->ShaderManager.AddShader("DefaultShader", "gui_transparent.vertex", "gui_transparent.fragment"); + + Renderer->PushShader("DefaultShader"); + + ResourceManager->FontManager.AddFont("droid_sans14", "droid_sans14_font_bitmap.bmp32", "droid_sans14_font_charmap.txt"); + ResourceManager->FontManager.PushFont("droid_sans14"); + + //ResourceManager->SoundManager.LoadMusic("level1ogg.ogg"); + + //ResourceManager->SoundManager.LoadSound("shot.wav"); + + //Renderer->MovePhi(pi/6); + + Renderer->Camera = TPitCamera(); + + ResourceManager->LightManager.SetLightDirection(vec3(-1,0,-1)); + ResourceManager->LightManager.SetLightColor(vec4(1,0,0,1)); + + ResourceManager->TexList.AddTexture("pit.png"); + ResourceManager->TexList.AddTexture("tube.png"); + ResourceManager->TexList.AddTexture("tube_i.png"); + //ResourceManager->FlexModelManager.LoadModelFromXml("model.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("box.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("pit.xml"); + + ResourceManager->FlexModelManager.LoadModelFromXml("tube1.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube2.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube3.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube4.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube5.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube6.xml"); + + ResourceManager->FlexModelManager.LoadModelFromXml("tube1_physics.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube2_physics.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube3_physics.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube4_physics.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube5_physics.xml"); + ResourceManager->FlexModelManager.LoadModelFromXml("tube6_physics.xml"); + + FlexModel = ResourceManager->FlexModelManager.InstanciateModel("pit.xml"); + + + //FlexModel.MoveModel(vec3(0, -36.f, -105.f)); //Landscape screen + FlexModel.MoveModel(vec3(0, -23.f, -50.f)); //Portrait screen + FlexModel.ScaleModel(40.f); + FlexModel.RefreshBuffer(); + + TubeModelArr.resize(6); + TubeBodyArr.resize(6); + + for (size_t i = 0; i < TubeModelArr.size(); ++i) + { + int modelNum = rand() % CONST_TUBE_COUNT; + TubeModelArr[i] = GenerateFlexModel(modelNum); + + TubeModelArr[i].PushModelDataTriangleList(); + TubeModelArr[i].ScaleModel(25.4f); + TubeModelArr[i].MoveModel(vec3(0, 0, -2500.f*i)); + + TubeModelArr[i].RefreshBuffer(); + + + auto model = GeneratePhysicsModel(modelNum); + TubeBodyArr[i].AssignFromFlexModel(model); + TubeBodyArr[i].Scale(25.4f); + TubeBodyArr[i].Move(vec3(0, 0, -2500.f*i)); + + + + } + /* + for (int i=0; i< CONST_MAX_BOXES; i++) + { + BoxList.push_back(GenerateBox(i)); + }*/ + + //Uncomment to start music playing + //ResourceManager->SoundManager.PlayMusic("level1ogg.ogg"); + + Velocity = CONST_VELOCITY; + + PrevCamVec = boost::get(Renderer->Camera).CamVec; + + RotateShift = vec2(0.f, 0.f); + + *Console<<"Inner init end!\n"; +} + +void TMyApplication::InnerDeinit() +{ +} + + +void TMyApplication::InnerDraw() +{ + + glClearColor(0,0,0,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + Renderer->PushPerspectiveProjectionMatrix(pi/6, Renderer->GetMatrixWidth() / Renderer->GetMatrixHeight(), 1.f, 8500.f); + + Renderer->PushMatrix(); + + Renderer->SetGLCamView(); + + for (size_t i = 0; i < TubeModelArr.size(); ++i) + { + TubeModelArr[i].Draw(); + } + + Renderer->PopMatrix(); + + //Renderer->PopProjectionMatrix(); + + glClear(GL_DEPTH_BUFFER_BIT); + + Renderer->PushMatrix(); + + vec4 q; + + vec3 camVec = boost::get(Renderer->Camera).CamVec; + + vec4 camQuat = boost::get(Renderer->Camera).CameraQuat; + + vec3 n = Normalize(CrossProduct(camVec, PrevCamVec)); + + float cos_a = min(DotProduct(camVec, PrevCamVec), 1.f); + + n = InverseQuat(camQuat) * vec4(n) * (camQuat); + + float sin_a = sqrtf(1 - cos_a*cos_a); + + if (sin_a > 0.001f) + { + + q = vec4(n.v[0] * sin_a, n.v[1] * sin_a, n.v[2] * sin_a, cos_a); + + Renderer->RotateMatrix(q); + } + FlexModel.Draw(); + + Renderer->PopMatrix(); + + Renderer->PopProjectionMatrix(); + + +} + + +void TMyApplication::InnerUpdate(cardinal dt) +{ + vec3 camShift = boost::get(Renderer->Camera).CamShift; + + vec3 camVec = boost::get(Renderer->Camera).CamVec; + + camShift += camVec * (static_cast(dt)*Velocity); + + while (camShift.v[2] < -2500.f) + { + camShift.v[2] += 2500.f; + + TubeModelArr.erase(TubeModelArr.begin()); + TFlexModel model; + model = GenerateFlexModel(rand() % CONST_TUBE_COUNT); + model.ScaleModel(25.4f); + TubeModelArr.push_back(model); + + for (size_t i = 0; i < TubeModelArr.size()-1; ++i) + { + TubeModelArr[i].MoveModel(vec3(0, 0, 2500.f)); + TubeModelArr[i].RefreshBuffer(); + } + + TubeModelArr[TubeModelArr.size()-1].MoveModel(vec3(0, 0, -2500.f*(TubeModelArr.size()-1))); + TubeModelArr[TubeModelArr.size()-1].RefreshBuffer(); + + + + TubeBodyArr.erase(TubeBodyArr.begin()); + TVolumeBody body; + auto model1=GeneratePhysicsModel(rand() % CONST_TUBE_COUNT); + body.AssignFromFlexModel(model1); + body.Scale(25.4f); + TubeBodyArr.push_back(body); + + for (size_t i = 0; i < TubeBodyArr.size()-1; ++i) + { + TubeBodyArr[i].Move(vec3(0, 0, 2500.f)); + } + + TubeBodyArr[TubeBodyArr.size()-1].Move(vec3(0, 0, -2500.f*(TubeBodyArr.size()-1))); + + } + + boost::get(Renderer->Camera).CamShift = camShift; + + if (Velocity != 0) + { + + vec3 a = boost::get(Renderer->Camera).CamShift; + vec3 b = a + 100.f * boost::get(Renderer->Camera).CamVec; + + if (a != b) + { + BOOST_FOREACH(TVolumeBody& body, TubeBodyArr) + { + if (body.CheckCollision(a,b)) + { + Velocity = 0.f; + } + } + /* + BOOST_FOREACH(auto& i, BoxList) + { + if (i.second.CheckCollision(a,b)) + { + Velocity = 0.f; + } + }*/ + } + } + + + //const float CONST_ROTATE_SPEED = 0.0004f; + const float CONST_ROTATE_SPEED = 0.001f; + + float rotateShift = Length(RotateShift) * 0.01f / 2.f; + + vec4 quat = vec4(RotateAxis.v[0] * sin(rotateShift*dt*CONST_ROTATE_SPEED), RotateAxis.v[1] * sin(rotateShift*dt*CONST_ROTATE_SPEED), RotateAxis.v[2] * sin(rotateShift*dt*CONST_ROTATE_SPEED), cos(rotateShift*dt*CONST_ROTATE_SPEED)); + + boost::get(Renderer->Camera).RotateByQuat(quat); + + boost::get(Renderer->Camera).CalcCamVec(); + + UpdatePitVector(dt); + + + OnUpdateSignal(); + + OnUpdateSignal.disconnect_all_slots(); + +} + + +void TMyApplication::InnerOnMove(vec2 shift) +{ + + RotateShift += shift; + + //float len = Length(shift); + + vec3 rotation = Normalize(vec3(RotateShift, 0)); //Inverse + + //rotation.v[1] =-rotation.v[1]; //Inverse + + vec3 z = vec3(0,0,-1); + + vec4 startQuat = boost::get(Renderer->Camera).CameraQuat; + + RotateAxis = Normalize(CrossProduct(rotation, z)); + + RotateAxis = startQuat * vec4(RotateAxis) * InverseQuat(startQuat); + + //RotateShift = len * 0.01f / 2.f; + + UpdatePitVector(0); +} + +void TMyApplication::InnerOnTapUp(vec2 p) +{ + RotateShift = vec2(0.f, 0.f); + + RotateAxis = vec3(0,0,0); + + if (p.v[0] < 50 && p.v[1] < 50 && Velocity == 0) + { + OnUpdateSignal.connect(boost::bind(&TMyApplication::RecreateLevel, this)); + } +} + +void TMyApplication::InnerOnTapUpAfterMove(vec2 p) +{ + RotateShift = vec2(0.f, 0.f); + + RotateAxis = vec3(0,0,0); +} + +void TMyApplication::OnMouseWheel(short int delta) +{ + OnUpdateSignal.connect(boost::bind(&TMyApplication::RecreateLevel, this)); +} + +void TMyApplication::UpdatePitVector(cardinal dt) +{ + + //Update pit vector + vec3 camVec = boost::get(Renderer->Camera).CamVec; + + vec4 q; + + vec3 n = -Normalize(CrossProduct(camVec, PrevCamVec)); + + float min_cos_a = min(DotProduct(camVec, PrevCamVec), 1.f); + + const float diff_alpha = pi/96; + + float angle = acos(min_cos_a); + + + if (angle >= diff_alpha) + { + //Correcting PrevCamVec; + + min_cos_a = cosf(diff_alpha); + + vec4 quat(-n.v[0]*sin(diff_alpha/2.f), -n.v[1]*sin(diff_alpha/2.f), -n.v[2]*sin(diff_alpha/2.f), cos(diff_alpha/2.f)); + + PrevCamVec = quat * vec4(camVec) * InverseQuat(quat); + } + + + //Catch up + + const float omega = 0.0002f; + + if (angle < omega*dt) + { + PrevCamVec = camVec; + } + else + { + vec4 delta_quat(n.v[0]*sin(omega * dt / 2.f), n.v[1]*sin(omega * dt / 2.f), n.v[2]*sin(omega * dt / 2.f), cos(omega * dt / 2.f)); + + PrevCamVec = delta_quat * vec4(PrevCamVec) * InverseQuat(delta_quat); + } + + + +} + +void TMyApplication::RecreateLevel() +{ + Velocity = CONST_VELOCITY; + + boost::get(Renderer->Camera).CamShift = ZeroVec3; + + for (size_t i = 0; i < 3; ++i) + { + TubeModelArr[i] = GenerateFlexModel(0); + + TubeModelArr[i].PushModelDataTriangleList(); + TubeModelArr[i].ScaleModel(25.4f); + TubeModelArr[i].MoveModel(vec3(0, 0, -2500.f*i)); + + TubeModelArr[i].RefreshBuffer(); + + auto model2= GeneratePhysicsModel(0); + TubeBodyArr[i].AssignFromFlexModel(model2); + TubeBodyArr[i].Scale(25.4f); + TubeBodyArr[i].Move(vec3(0, 0, -2500.f*i)); + + } +} \ No newline at end of file diff --git a/game/main_code.h b/game/main_code.h new file mode 100644 index 0000000..46e4427 --- /dev/null +++ b/game/main_code.h @@ -0,0 +1,74 @@ +#ifndef MAIN_CODE_H_INCLUDED +#define MAIN_CODE_H_INCLUDED + + +#include +#include +#include + +#ifdef TARGET_ANDROID + +#include +#include +#include +#endif + +#include "boost/shared_ptr.hpp" +#include "boost/thread/thread.hpp" +#include "boost/assign.hpp" +#include "boost/bind.hpp" +#include "boost/asio.hpp" +#include "boost/signal.hpp" + +#include "include/Engine.h" + +using namespace SE; + +class TMyApplication : public TApplication +{ +protected: + +public: + bool Inited; + + float Velocity; + + TFlexModel FlexModel; + + std::vector TubeModelArr; + std::vector TubeBodyArr; + //std::list> BoxList; + + vec3 PrevCamVec; + vec3 RotateAxis; + //float RotateShift; + vec2 RotateShift; + + boost::signal OnUpdateSignal; + + TMyApplication() : TApplication(), Inited(false) { } + + virtual void InnerInit(); + + virtual void InnerDeinit(); + + virtual void InnerDraw(); + + virtual void InnerUpdate(cardinal dt); + + bool IsInited() { return Inited; } + + virtual void InnerOnMove(vec2 shift); + virtual void InnerOnTapUp(vec2 p); + virtual void InnerOnTapUpAfterMove(vec2 p); + + virtual void OnMouseWheel(short int delta); + + void UpdatePitVector(cardinal dt); + + void RecreateLevel(); + +}; + + +#endif diff --git a/proj.android-studio/.gitignore b/proj.android-studio/.gitignore new file mode 100755 index 0000000..cea3ef5 --- /dev/null +++ b/proj.android-studio/.gitignore @@ -0,0 +1,10 @@ +*.iml +.gradle +/local.properties +/.idea +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild