moved from h4570/tyra
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
EE_BIN = floors.elf
|
||||
|
||||
EE_OBJS = \
|
||||
../../engine/models/math/matrix.o \
|
||||
../../engine/models/math/plane.o \
|
||||
../../engine/models/math/point.o \
|
||||
../../engine/models/math/vector3.o \
|
||||
../../engine/models/dff_model.o \
|
||||
../../engine/models/md2_model.o \
|
||||
../../engine/models/mesh.o \
|
||||
../../engine/models/mesh_spec.o \
|
||||
../../engine/models/obj_model.o \
|
||||
../../engine/modules/audio.o \
|
||||
../../engine/modules/camera_base.o \
|
||||
../../engine/modules/gif_sender.o \
|
||||
../../engine/modules/light.o \
|
||||
../../engine/modules/pad.o \
|
||||
../../engine/modules/renderer.o \
|
||||
../../engine/modules/timer.o \
|
||||
../../engine/modules/vif_sender.o \
|
||||
../../engine/modules/vu1.o \
|
||||
../../engine/utils/math.o \
|
||||
../../engine/utils/string.o \
|
||||
../../engine/loaders/bmp_loader.o \
|
||||
../../engine/loaders/dff_loader.o \
|
||||
../../engine/loaders/md2_loader.o \
|
||||
../../engine/loaders/obj_loader.o \
|
||||
../../engine/vu1_progs/draw3D.o \
|
||||
../../engine/engine.o \
|
||||
managers/light_manager.o \
|
||||
managers/floor_manager.o \
|
||||
camera.o \
|
||||
objects/floor.o \
|
||||
objects/player.o \
|
||||
utils.o \
|
||||
floors.o \
|
||||
main.o
|
||||
|
||||
EE_LIBS = -ldraw -lgraph -lmath3d -lpacket -ldma -lpad -laudsrv -lc -lstdc++
|
||||
EE_INCS := -I./../../engine/include $(EE_INCS)
|
||||
EE_DVP = dvp-as
|
||||
EE_VCL = openvcl
|
||||
|
||||
all: $(EE_BIN)
|
||||
$(EE_STRIP) --strip-all $(EE_BIN)
|
||||
mv $(EE_BIN) bin/$(EE_BIN)
|
||||
rm $(EE_OBJS)
|
||||
|
||||
%.vsm: %.vcl
|
||||
$(EE_VCL) $< >> $@
|
||||
|
||||
%.o: %.vsm
|
||||
$(EE_DVP) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(EE_BIN) $(EE_OBJS)
|
||||
|
||||
include $(PS2SDK)/samples/Makefile.pref
|
||||
include $(PS2SDK)/samples/Makefile.eeglobal
|
||||
@@ -0,0 +1,14 @@
|
||||
## Floors sample
|
||||
|
||||
### Description
|
||||
|
||||
Simple demo which shows lighting using PATH3, and player movement and animation.
|
||||
|
||||
### Assets
|
||||
[Download](http://apgcglz.cluster028.hosting.ovh.net/tyra/1.0.0/samples/floors/assets.zip)
|
||||
|
||||
### Screenshot
|
||||
|
||||
[![Floors screenshot][floors-screenshot]](#)
|
||||
|
||||
[floors-screenshot]: http://apgcglz.cluster028.hosting.ovh.net/tyra/1.0.0/samples/floors/floors.gif
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "camera.hpp"
|
||||
|
||||
#include <utils/debug.hpp>
|
||||
#include <fastmath.h>
|
||||
|
||||
const float CAMERA_Y = 30.0F;
|
||||
|
||||
// ----
|
||||
// Constructors/Destructors
|
||||
// ----
|
||||
|
||||
Camera::Camera(ScreenSettings *t_screen) : CameraBase(t_screen, &position, &up, &unitCirclePosition)
|
||||
{
|
||||
PRINT_LOG("Initializing camera");
|
||||
verticalLevel = 80.0F;
|
||||
up.x = 0.0F;
|
||||
up.y = 1.0F;
|
||||
up.z = 0.0F;
|
||||
PRINT_LOG("Camera initialized!");
|
||||
}
|
||||
|
||||
Camera::~Camera() {}
|
||||
|
||||
// ----
|
||||
// Methods
|
||||
// ----
|
||||
|
||||
void Camera::update(Pad &t_pad, Mesh &t_mesh)
|
||||
{
|
||||
rotate(t_pad);
|
||||
followBy(t_mesh);
|
||||
updatePlanes(t_mesh.position);
|
||||
worldView.lookAt(up, position, t_mesh.position);
|
||||
}
|
||||
|
||||
/** Set camera rotation by pad right joy and update unit circle
|
||||
* https://en.wikipedia.org/wiki/Unit_circle
|
||||
* https://www.desmos.com/calculator/3e7iypw4ow
|
||||
*/
|
||||
void Camera::rotate(Pad &t_pad)
|
||||
{
|
||||
if (t_pad.rJoyH <= 50)
|
||||
horizontalLevel -= 0.08;
|
||||
else if (t_pad.rJoyH >= 200)
|
||||
horizontalLevel += 0.04;
|
||||
if (t_pad.rJoyV <= 50 && verticalLevel > 25.0F)
|
||||
verticalLevel -= 0.9F;
|
||||
else if (t_pad.rJoyV >= 200 && verticalLevel < 80.0F)
|
||||
verticalLevel += 0.9F;
|
||||
unitCirclePosition.x = (sin(horizontalLevel) * verticalLevel);
|
||||
unitCirclePosition.y = CAMERA_Y;
|
||||
unitCirclePosition.z = (cos(horizontalLevel) * verticalLevel);
|
||||
}
|
||||
|
||||
/** Rotate camera around 3D object */
|
||||
void Camera::followBy(Mesh &t_mesh)
|
||||
{
|
||||
position.x = unitCirclePosition.x + t_mesh.position.x;
|
||||
position.y = unitCirclePosition.y + t_mesh.position.y;
|
||||
position.z = unitCirclePosition.z + t_mesh.position.z;
|
||||
|
||||
if (position.x > (-0.04F * verticalLevel) &&
|
||||
position.x < 0.0F &&
|
||||
position.z > (0.998F * verticalLevel))
|
||||
{
|
||||
// TODO
|
||||
// position.x = 0.0F;
|
||||
// position.y = 0.0F;
|
||||
// position.z = 0.0F;
|
||||
// horizontalLevel = 0.0F;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _CAMERA_
|
||||
#define _CAMERA_
|
||||
|
||||
#include <modules/pad.hpp>
|
||||
#include <models/mesh.hpp>
|
||||
#include <models/math/vector3.hpp>
|
||||
#include <models/screen_settings.hpp>
|
||||
#include <modules/camera_base.hpp>
|
||||
#include <tamtypes.h>
|
||||
|
||||
/** 3D camera which follow by 3D object. Can be rotated via pad */
|
||||
class Camera : public CameraBase
|
||||
{
|
||||
|
||||
public:
|
||||
Vector3 up, position, unitCirclePosition;
|
||||
float horizontalLevel, verticalLevel;
|
||||
|
||||
Camera(ScreenSettings *t_screen);
|
||||
~Camera();
|
||||
|
||||
void update(Pad &t_pad, Mesh &t_mesh);
|
||||
void rotate(Pad &t_pad);
|
||||
void followBy(Mesh &t_mesh);
|
||||
|
||||
protected:
|
||||
Vector3 *getPosition() { return &position; };
|
||||
Vector3 *getUp() { return &up; };
|
||||
ScreenSettings screen;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "floors.hpp"
|
||||
|
||||
// ----
|
||||
// Constructors/Destructors
|
||||
// ----
|
||||
|
||||
Floors::Floors() {}
|
||||
|
||||
Floors::~Floors() {}
|
||||
|
||||
// ----
|
||||
// Methods
|
||||
// ----
|
||||
|
||||
void Floors::onInit()
|
||||
{
|
||||
player = new Player();
|
||||
camera = new Camera(&engine.screen);
|
||||
engine.renderer->setCameraDefinitions(&camera->worldView, &camera->unitCirclePosition, camera->planes);
|
||||
floorManager = new FloorManager(64); // Temp change it also in floor_manager.hpp
|
||||
engine.audio.init(2);
|
||||
engine.audio.addListener(floorManager);
|
||||
engine.audio.addListener(&lightManager);
|
||||
engine.audio.loadSong("NF-CHILL.WAV");
|
||||
engine.audio.play();
|
||||
}
|
||||
|
||||
void Floors::onUpdate()
|
||||
{
|
||||
if (engine.pad.isCrossClicked)
|
||||
printf("FPS:%f\n", engine.fps);
|
||||
lightManager.update();
|
||||
camera->update(engine.pad, player->mesh);
|
||||
floorManager->update(*player);
|
||||
player->update(engine.pad, *camera, *floorManager);
|
||||
engine.renderer->draw(&player->mesh);
|
||||
engine.renderer->drawByPath3(floorManager->meshes, floorManager->floorAmount, lightManager.bulbs, lightManager.bulbsCount);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _FLOORS_
|
||||
#define _FLOORS_
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <game.hpp>
|
||||
#include <engine.hpp>
|
||||
#include "managers/floor_manager.hpp"
|
||||
#include "managers/light_manager.hpp"
|
||||
#include "objects/player.hpp"
|
||||
#include "./camera.hpp"
|
||||
|
||||
class Floors : public Game
|
||||
{
|
||||
|
||||
public:
|
||||
Floors();
|
||||
~Floors();
|
||||
|
||||
void onInit();
|
||||
void onUpdate();
|
||||
|
||||
Engine engine;
|
||||
|
||||
private:
|
||||
LightManager lightManager;
|
||||
FloorManager *floorManager;
|
||||
Player *player;
|
||||
Camera *camera;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "floors.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
Floors game = Floors();
|
||||
game.engine.setDefaultScreen();
|
||||
game.engine.init(&game, 40000);
|
||||
SleepThread();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "floor_manager.hpp"
|
||||
|
||||
#include <utils/math.hpp>
|
||||
#include <utils/debug.hpp>
|
||||
#include <loaders/obj_loader.hpp>
|
||||
|
||||
// ----
|
||||
// Constructors/Destructors
|
||||
// ----
|
||||
|
||||
/** Calculate square spiral offsets and initialize floors
|
||||
* @param floorAmount must be a number from square root table
|
||||
*/
|
||||
FloorManager::FloorManager(int t_floorAmount)
|
||||
{
|
||||
floorAmount = t_floorAmount;
|
||||
spirals = new Point[t_floorAmount];
|
||||
int floorSpiralMaxOffset = (int)Math::sqrt(t_floorAmount);
|
||||
calcSpiral(floorSpiralMaxOffset, floorSpiralMaxOffset);
|
||||
initFloors();
|
||||
audioOffset = audioMode = audioTick = 0;
|
||||
}
|
||||
|
||||
FloorManager::~FloorManager()
|
||||
{
|
||||
delete[] spirals;
|
||||
delete[] spec;
|
||||
delete[] obj;
|
||||
delete[] meshes;
|
||||
}
|
||||
|
||||
// ----
|
||||
// Methods
|
||||
// ----
|
||||
|
||||
/** Calculates square spiral offsets by specyfying max X and Y, fills "spirals" variable
|
||||
* @param X Max X offset off spiral
|
||||
* @param Y Max Y offset off spiral
|
||||
*/
|
||||
void FloorManager::calcSpiral(int X, int Y)
|
||||
{
|
||||
PRINT_LOG("Calculating square spiral for floors");
|
||||
int x, y, dx;
|
||||
x = y = dx = 0;
|
||||
int dy = -1;
|
||||
int t = X > Y ? X : Y;
|
||||
int maxI = t * t;
|
||||
for (int i = 0; i < maxI; i++)
|
||||
{
|
||||
if ((-X / 2 <= x) && (x <= X / 2) && (-Y / 2 <= y) && (y <= Y / 2))
|
||||
{
|
||||
spirals[i].x = x;
|
||||
spirals[i].y = y;
|
||||
}
|
||||
if ((x == y) || ((x < 0) && (x == -y)) || ((x > 0) && (x == 1 - y)))
|
||||
{
|
||||
t = dx;
|
||||
dx = -dy;
|
||||
dy = t;
|
||||
}
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
PRINT_LOG("Square spiral calculated!");
|
||||
}
|
||||
|
||||
/** Initialize all floors by:
|
||||
* - Setting position (with spirals offset)
|
||||
* - Anim timer position
|
||||
*/
|
||||
void FloorManager::initFloors()
|
||||
{
|
||||
PRINT_LOG("Initializing floors");
|
||||
meshes = new Mesh *[floorAmount];
|
||||
|
||||
Vector3 initPos = Vector3(0.0F, 0.0F, 0.0F);
|
||||
meshes[0] = new Mesh();
|
||||
meshes[0]->loadObj("floor/", "floor.obj", initPos, 2.0F);
|
||||
meshes[0]->shouldBeFrustumCulled = true;
|
||||
obj = meshes[0]->obj;
|
||||
spec = meshes[0]->spec;
|
||||
for (u8 i = 0; i < floorAmount; i++)
|
||||
{
|
||||
floors[i].init(obj, spec, spirals[i], i);
|
||||
meshes[i] = &floors[i].mesh;
|
||||
}
|
||||
PRINT_LOG("Floors initialized!");
|
||||
}
|
||||
|
||||
/** Main floor loop.
|
||||
* - Checks if floor should be rendered (isVisible, frustum culling)
|
||||
* - Maintain floor animation
|
||||
* - Fix player position after floor position change
|
||||
*/
|
||||
void FloorManager::update(Player &t_player)
|
||||
{
|
||||
for (u8 i = 0; i < floorAmount; i++)
|
||||
{
|
||||
floors[i].animate(t_player);
|
||||
|
||||
if (floors[i].isByAudioTriggered == true)
|
||||
floors[i].mesh.color.a = 0x20;
|
||||
else
|
||||
floors[i].mesh.color.a = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
/** Called by audio thread */
|
||||
void FloorManager::onAudioTick()
|
||||
{
|
||||
if (audioTick++ > 16)
|
||||
{
|
||||
if (audioMode == 0)
|
||||
{
|
||||
for (u8 i = 0; i < floorAmount; i++)
|
||||
{
|
||||
if ((i + audioOffset) % 2 == 0)
|
||||
floors[i].isByAudioTriggered = true;
|
||||
else
|
||||
floors[i].isByAudioTriggered = false;
|
||||
}
|
||||
if (++audioOffset > 3)
|
||||
{
|
||||
audioOffset = 0;
|
||||
audioMode = 1;
|
||||
}
|
||||
}
|
||||
else if (audioMode == 1)
|
||||
{
|
||||
for (u8 i = 0; i < floorAmount; i++)
|
||||
{
|
||||
if (i < floorAmount / (audioOffset + 1))
|
||||
floors[i].isByAudioTriggered = true;
|
||||
else
|
||||
floors[i].isByAudioTriggered = false;
|
||||
}
|
||||
if (++audioOffset > 3)
|
||||
{
|
||||
audioOffset = 0;
|
||||
audioMode = 2;
|
||||
}
|
||||
}
|
||||
else if (audioMode == 2)
|
||||
{
|
||||
for (u8 i = 0; i < floorAmount; i++)
|
||||
{
|
||||
if ((i + audioOffset) % 4 == 0)
|
||||
floors[i].isByAudioTriggered = true;
|
||||
else
|
||||
floors[i].isByAudioTriggered = false;
|
||||
}
|
||||
if (++audioOffset > 3)
|
||||
{
|
||||
audioOffset = 0;
|
||||
audioMode = 3;
|
||||
}
|
||||
}
|
||||
else if (audioMode == 3)
|
||||
{
|
||||
for (u8 i = 0; i < floorAmount; i++)
|
||||
{
|
||||
if (i + 1 > floorAmount / (audioOffset + 1))
|
||||
floors[i].isByAudioTriggered = true;
|
||||
else
|
||||
floors[i].isByAudioTriggered = false;
|
||||
}
|
||||
if (++audioOffset > 3)
|
||||
{
|
||||
audioOffset = 0;
|
||||
audioMode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _FLOOR_MANAGER_
|
||||
#define _FLOOR_MANAGER_
|
||||
|
||||
class Player; // Forward definition
|
||||
|
||||
#include <models/math/point.hpp>
|
||||
#include <models/obj_model.hpp>
|
||||
#include <models/mesh_spec.hpp>
|
||||
#include <modules/camera_base.hpp>
|
||||
#include <models/audio_listener.hpp>
|
||||
|
||||
#include "../objects/floor.hpp"
|
||||
|
||||
/** Class which is maintaining floors objects */
|
||||
class FloorManager : public AudioListener
|
||||
{
|
||||
|
||||
public:
|
||||
FloorManager(int t_floorAmount);
|
||||
~FloorManager();
|
||||
Floor floors[64]; // Temp change it also in floors.cpp
|
||||
int floorAmount;
|
||||
void update(Player &t_player);
|
||||
Mesh **meshes;
|
||||
void onAudioTick();
|
||||
MeshSpec *spec;
|
||||
|
||||
private:
|
||||
u8 audioOffset, audioMode;
|
||||
u32 audioTick;
|
||||
ObjModel *obj;
|
||||
Point *spirals;
|
||||
void calcSpiral(int X, int Y);
|
||||
void initFloors();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "light_manager.hpp"
|
||||
#include <utils/debug.hpp>
|
||||
|
||||
// ----
|
||||
// Constructors/Destructors
|
||||
// ----
|
||||
|
||||
LightManager::LightManager()
|
||||
{
|
||||
PRINT_LOG("Creating light manager!");
|
||||
bulbsCount = 2;
|
||||
|
||||
bulbs = new LightBulb[2];
|
||||
bulb1Dir = 0;
|
||||
bulbs[0].intensity = 1;
|
||||
bulbs[0].position.set(30.00F, 30.00F, -30.00F);
|
||||
|
||||
bulb2Dir = 1;
|
||||
bulbs[1].intensity = 1;
|
||||
bulbs[1].position.set(-30.00F, 30.00F, 30.00F);
|
||||
|
||||
audioOffset = audioTick = 0;
|
||||
|
||||
PRINT_LOG("Light manager created!");
|
||||
}
|
||||
|
||||
LightManager::~LightManager()
|
||||
{
|
||||
delete[] bulbs;
|
||||
}
|
||||
|
||||
// ----
|
||||
// Methods
|
||||
// ----
|
||||
|
||||
/** Light bulb moving test */
|
||||
void LightManager::update()
|
||||
{
|
||||
updateBulb1();
|
||||
updateBulb2();
|
||||
}
|
||||
|
||||
void LightManager::updateBulb1()
|
||||
{
|
||||
if (bulb1Dir == 1)
|
||||
{
|
||||
if (areLightsInverted)
|
||||
{
|
||||
bulbs[0].position.x += 0.6F;
|
||||
bulbs[0].position.z -= 0.6F;
|
||||
}
|
||||
else
|
||||
{
|
||||
bulbs[0].position.x += 0.6F;
|
||||
bulbs[0].position.z += 0.6F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (areLightsInverted)
|
||||
{
|
||||
bulbs[0].position.x -= 0.6F;
|
||||
bulbs[0].position.z += 0.6F;
|
||||
}
|
||||
else
|
||||
{
|
||||
bulbs[0].position.x -= 0.6F;
|
||||
bulbs[0].position.z -= 0.6F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LightManager::updateBulb2()
|
||||
{
|
||||
if (bulb2Dir == 1)
|
||||
{
|
||||
if (areLightsInverted)
|
||||
{
|
||||
bulbs[1].position.x -= 0.6F;
|
||||
bulbs[1].position.z += 0.6F;
|
||||
}
|
||||
else
|
||||
{
|
||||
bulbs[1].position.x += 0.6F;
|
||||
bulbs[1].position.z += 0.6F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (areLightsInverted)
|
||||
{
|
||||
bulbs[1].position.x += 0.6F;
|
||||
bulbs[1].position.z -= 0.6F;
|
||||
}
|
||||
else
|
||||
{
|
||||
bulbs[1].position.x -= 0.6F;
|
||||
bulbs[1].position.z -= 0.6F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Called by audio thread */
|
||||
void LightManager::onAudioTick()
|
||||
{
|
||||
bulb1Dir = bulb1Dir == 1 ? 0 : 1;
|
||||
bulb2Dir = bulb2Dir == 1 ? 0 : 1;
|
||||
if (audioTick++ > 17)
|
||||
{
|
||||
if (++audioOffset > 3)
|
||||
{
|
||||
audioOffset = 0;
|
||||
if (areLightsInverted)
|
||||
{
|
||||
areLightsInverted = false;
|
||||
bulbs[0].position.x = 20.0F;
|
||||
bulbs[0].position.z = -20.0F;
|
||||
|
||||
bulbs[1].position.x = -20.0F;
|
||||
bulbs[1].position.z = 20.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
areLightsInverted = true;
|
||||
bulbs[0].position.x = 20.0F;
|
||||
bulbs[0].position.z = 20.0F;
|
||||
|
||||
bulbs[1].position.x = -20.0F;
|
||||
bulbs[1].position.z = -20.0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bulbs[0].intensity += 6;
|
||||
bulbs[1].intensity += 6;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _LIGHT_MANAGER_
|
||||
#define _LIGHT_MANAGER_
|
||||
|
||||
#include <models/light_bulb.hpp>
|
||||
#include <models/audio_listener.hpp>
|
||||
|
||||
/** Class which is maintaining floors objects */
|
||||
class LightManager : public AudioListener
|
||||
{
|
||||
|
||||
public:
|
||||
LightManager();
|
||||
~LightManager();
|
||||
|
||||
LightBulb *bulbs;
|
||||
u8 bulbsCount;
|
||||
void update();
|
||||
void onAudioTick();
|
||||
|
||||
private:
|
||||
u8 bulb1Dir, bulb2Dir;
|
||||
void updateBulb1();
|
||||
void updateBulb2();
|
||||
u8 audioOffset, areLightsInverted;
|
||||
u32 audioTick;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "floor.hpp"
|
||||
|
||||
#include "../utils.hpp"
|
||||
#include "./player.hpp"
|
||||
#include <cstdlib>
|
||||
#include <time.h>
|
||||
|
||||
const int FLOOR_ANIMATION_LENGTH = 100;
|
||||
const float FLOOR_ANIMATION_Y_MIN = 0.0F;
|
||||
const float FLOOR_ANIMATION_Y_MAX = 10.0F;
|
||||
|
||||
// ----
|
||||
// Constructors/Destructors
|
||||
// ----
|
||||
|
||||
Floor::Floor() {}
|
||||
|
||||
Floor::~Floor() {}
|
||||
|
||||
// ----
|
||||
// Methods
|
||||
// ----
|
||||
|
||||
/** Init floor position and animation timer position
|
||||
* @param spec pointer to 3D object specification
|
||||
* @param spiral Spiral position
|
||||
* @param initOffset Number of floor (index)
|
||||
*/
|
||||
void Floor::init(ObjModel *obj, MeshSpec *spec, Point &spiral, u8 &initOffset)
|
||||
{
|
||||
Vector3 initPos = Vector3(0.00F, -10.00F, 0.00F);
|
||||
this->mesh.setObj(initPos, obj, spec);
|
||||
this->initOffset = initOffset;
|
||||
this->animTimer = rand() % FLOOR_ANIMATION_LENGTH;
|
||||
this->mesh.shouldBeLighted = true;
|
||||
this->mesh.shouldBeFrustumCulled = true;
|
||||
this->animDirection = 0;
|
||||
this->mesh.position.x = spiral.x * 40.0F;
|
||||
this->mesh.position.z = spiral.y * 40.0F;
|
||||
}
|
||||
|
||||
/** Check and update animation direction and position
|
||||
* Runs Player::onBeforePlayerFloorMove() method
|
||||
*/
|
||||
void Floor::animate(Player &player)
|
||||
{
|
||||
if (this->animDirection == 0)
|
||||
this->animTimer++;
|
||||
else
|
||||
this->animTimer--;
|
||||
|
||||
if (this->animDirection == 0 && this->animTimer >= FLOOR_ANIMATION_LENGTH)
|
||||
this->animDirection = 1;
|
||||
else if (this->animDirection == 1 && this->animTimer <= 0)
|
||||
this->animDirection = 0;
|
||||
float newY = Utils::expoEaseInOut(this->animTimer, FLOOR_ANIMATION_Y_MIN, FLOOR_ANIMATION_Y_MAX, FLOOR_ANIMATION_LENGTH);
|
||||
float yDiff = newY - this->mesh.position.y;
|
||||
if (this->initOffset == player.indexOfCurrentFloor)
|
||||
player.onBeforePlayerFloorMove(this, yDiff);
|
||||
this->mesh.position.y = newY;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _FLOOR_
|
||||
#define _FLOOR_
|
||||
|
||||
class Player; // Forward definition
|
||||
|
||||
#include <models/mesh.hpp>
|
||||
#include <models/obj_model.hpp>
|
||||
#include <models/math/point.hpp>
|
||||
#include <tamtypes.h>
|
||||
|
||||
/** Floor 3D object class */
|
||||
class Floor
|
||||
{
|
||||
|
||||
public:
|
||||
u16 animTimer;
|
||||
u8 animDirection, initOffset, isByAudioTriggered;
|
||||
Mesh mesh;
|
||||
|
||||
Floor();
|
||||
~Floor();
|
||||
|
||||
void init(ObjModel *obj, MeshSpec *spec, Point &spiral, u8 &initOffset);
|
||||
void animate(Player &player);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "player.hpp"
|
||||
|
||||
#include <loaders/obj_loader.hpp>
|
||||
#include <loaders/bmp_loader.hpp>
|
||||
#include <modules/gif_sender.hpp>
|
||||
#include <utils/debug.hpp>
|
||||
#include <utils/math.hpp>
|
||||
|
||||
// ----
|
||||
// Constructors/Destructors
|
||||
// ----
|
||||
|
||||
Player::Player()
|
||||
{
|
||||
PRINT_LOG("Creating player object");
|
||||
this->gravity = 0.1F;
|
||||
this->lift = -1.0F;
|
||||
|
||||
Vector3 initPos = Vector3(0.00F, 20.00F, 0.00F);
|
||||
this->mesh.loadMD2("warrior/", "warrior.md2", initPos, 0.2F);
|
||||
this->mesh.rotation.x = -1.6F;
|
||||
this->mesh.shouldBeBackfaceCulled = false;
|
||||
this->mesh.shouldBeFrustumCulled = false;
|
||||
|
||||
this->mesh.setAnimSpeed(0.2F);
|
||||
this->mesh.playAnimation(0, 24);
|
||||
PRINT_LOG("Player object created!");
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
{
|
||||
delete[] this->spec;
|
||||
}
|
||||
|
||||
// ----
|
||||
// Methods
|
||||
// ----
|
||||
|
||||
/** Update player position and control gravity */
|
||||
void Player::update(Pad &pad, Camera &camera, FloorManager &floorManager)
|
||||
{
|
||||
this->updatePosition(pad, camera, floorManager);
|
||||
this->updateGravity(pad, floorManager);
|
||||
}
|
||||
|
||||
/** Move player when pad move buttons are pressed and is not blocked by any floor side */
|
||||
void Player::updatePosition(Pad &pad, Camera &camera, FloorManager &floorManager)
|
||||
{
|
||||
|
||||
if (pad.isDpadUpPressed == 1)
|
||||
{
|
||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * -camera.unitCirclePosition.x;
|
||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * -camera.unitCirclePosition.z;
|
||||
}
|
||||
if (pad.isDpadDownPressed == 1)
|
||||
{
|
||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * camera.unitCirclePosition.x;
|
||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * camera.unitCirclePosition.z;
|
||||
}
|
||||
if (pad.isDpadLeftPressed == 1)
|
||||
{
|
||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * -camera.unitCirclePosition.z;
|
||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * camera.unitCirclePosition.x;
|
||||
}
|
||||
if (pad.isDpadRightPressed == 1)
|
||||
{
|
||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * camera.unitCirclePosition.z;
|
||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * -camera.unitCirclePosition.x;
|
||||
}
|
||||
this->playerNextPosition.y = this->mesh.position.y;
|
||||
this->isCollideFloor = 0;
|
||||
Vector3 min = Vector3();
|
||||
Vector3 max = Vector3();
|
||||
for (int i = 0; i < floorManager.floorAmount; i++)
|
||||
{
|
||||
floorManager.floors[i].mesh.getMinMax(&min, &max);
|
||||
this->isCollideFloor = this->playerNextPosition.collidesSquare(min, max);
|
||||
if (this->isCollideFloor == 1)
|
||||
break;
|
||||
}
|
||||
if (this->isCollideFloor == 0)
|
||||
{
|
||||
this->mesh.position.x = this->playerNextPosition.x;
|
||||
this->mesh.position.z = this->playerNextPosition.z;
|
||||
}
|
||||
}
|
||||
|
||||
/** Do not call this.
|
||||
* This is called by Floor::animate() on player's floor move in Y direction
|
||||
*/
|
||||
void Player::onBeforePlayerFloorMove(Floor *floor, float &newY)
|
||||
{
|
||||
if (floor->animDirection == 0 && newY > 0.0F)
|
||||
this->mesh.position.y += newY * 1.05F;
|
||||
else if ((floor->animDirection == 1 && -newY < 0.0F))
|
||||
this->mesh.position.y -= -newY * 1.05F;
|
||||
}
|
||||
|
||||
/** Update player position by gravity and update index of current floor */
|
||||
void Player::updateGravity(Pad &pad, FloorManager &floorManager)
|
||||
{
|
||||
Vector3 min = Vector3();
|
||||
Vector3 max = Vector3();
|
||||
|
||||
if (pad.isCrossClicked == 1)
|
||||
this->velocity = this->lift;
|
||||
|
||||
this->isOnFloor = 0;
|
||||
for (int i = 0; i < floorManager.floorAmount; i++)
|
||||
{
|
||||
floorManager.floors[i].mesh.getMinMax(&min, &max);
|
||||
this->isOnFloor = this->mesh.position.isOnSquare(min, max);
|
||||
if (this->isOnFloor == 1)
|
||||
{
|
||||
this->indexOfCurrentFloor = floorManager.floors[i].initOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->velocity += this->gravity;
|
||||
this->mesh.position.y -= this->velocity;
|
||||
|
||||
if (this->mesh.position.y >= 60.0F)
|
||||
{
|
||||
this->mesh.position.y = 60.0F;
|
||||
this->velocity = 0;
|
||||
}
|
||||
else if ((this->mesh.position.y) < max.y && this->isOnFloor)
|
||||
{
|
||||
this->mesh.position.y = max.y;
|
||||
this->velocity = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _PLAYER_
|
||||
#define _PLAYER_
|
||||
|
||||
#include "../managers/floor_manager.hpp"
|
||||
#include "../camera.hpp"
|
||||
#include <modules/pad.hpp>
|
||||
#include <models/mesh_spec.hpp>
|
||||
#include <tamtypes.h>
|
||||
|
||||
/** Player 3D object class */
|
||||
class Player
|
||||
{
|
||||
|
||||
public:
|
||||
float gravity, velocity, lift;
|
||||
u8 isOnFloor, isCollideFloor, indexOfCurrentFloor;
|
||||
Mesh mesh;
|
||||
MeshSpec *spec;
|
||||
Player();
|
||||
~Player();
|
||||
|
||||
void update(Pad &pad, Camera &camera, FloorManager &floorManager);
|
||||
void onBeforePlayerFloorMove(Floor *floor, float &newY);
|
||||
|
||||
private:
|
||||
Vector3 playerNextPosition;
|
||||
void updatePosition(Pad &pad, Camera &camera, FloorManager &floorManager);
|
||||
void updateGravity(Pad &pad, FloorManager &floorManager);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "./utils.hpp"
|
||||
|
||||
#include <fastmath.h>
|
||||
|
||||
/** Exponential ease-in-out animation
|
||||
* @param t Time
|
||||
* @param b Start value
|
||||
* @param c Change
|
||||
* @param d Duration
|
||||
* @returns Current animation position
|
||||
*/
|
||||
float Utils::expoEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if (t == 0)
|
||||
return b;
|
||||
|
||||
if (t == d)
|
||||
return b + c;
|
||||
|
||||
if ((t /= d / 2) < 1)
|
||||
return c / 2 * powf(2, 10 * (t - 1)) + b;
|
||||
|
||||
return c / 2 * (-powf(2, -10 * --t) + 2) + b;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _TYRA_UTILS_
|
||||
#define _TYRA_UTILS_
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
class Utils
|
||||
{
|
||||
|
||||
public:
|
||||
static float expoEaseInOut(float t, float b, float c, float d);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user