@@ -15,6 +15,12 @@
|
|||||||
#include <draw_types.h>
|
#include <draw_types.h>
|
||||||
#include <draw_buffers.h>
|
#include <draw_buffers.h>
|
||||||
|
|
||||||
|
enum SpriteMode
|
||||||
|
{
|
||||||
|
MODE_STRETCH,
|
||||||
|
MODE_REPEAT
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which have contain 2D image data.
|
* Class which have contain 2D image data.
|
||||||
*/
|
*/
|
||||||
@@ -37,10 +43,16 @@ public:
|
|||||||
/** Auto generated unique Id. */
|
/** Auto generated unique Id. */
|
||||||
inline const u32 &getId() const { return id; };
|
inline const u32 &getId() const { return id; };
|
||||||
|
|
||||||
|
/** Get sprite drawing mode. */
|
||||||
|
inline const SpriteMode &getMode() const { return mode; };
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// Setters
|
// Setters
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
|
/** Set sprite drawing mode. */
|
||||||
|
void setMode(const SpriteMode &t_val) { mode = t_val; }
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// Other
|
// Other
|
||||||
// ----
|
// ----
|
||||||
@@ -59,6 +71,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
u32 id;
|
u32 id;
|
||||||
|
SpriteMode mode;
|
||||||
u8 _isSizeSet, _flipH, _flipV;
|
u8 _isSizeSet, _flipH, _flipV;
|
||||||
void setDefaultColor();
|
void setDefaultColor();
|
||||||
void setDefaultLODAndClut();
|
void setDefaultLODAndClut();
|
||||||
|
|||||||
@@ -47,38 +47,38 @@ public:
|
|||||||
* again texture in renderer, when last sent texture id
|
* again texture in renderer, when last sent texture id
|
||||||
* by renderer will be equal to this id.
|
* by renderer will be equal to this id.
|
||||||
*/
|
*/
|
||||||
const u32 &getId() const { return id; };
|
inline const u32 getId() const { return id; };
|
||||||
|
|
||||||
const u8 &getWidth() const { return width; };
|
inline const u16 getWidth() const { return width; };
|
||||||
|
|
||||||
const u8 &getHeight() const { return height; };
|
inline const u16 getHeight() const { return height; };
|
||||||
|
|
||||||
const TextureType &getType() const { return _type; };
|
inline const TextureType getType() const { return _type; };
|
||||||
|
|
||||||
u32 getTextureLinksCount() const { return static_cast<u32>(texLinks.size()); };
|
inline u32 getTextureLinksCount() const { return static_cast<u32>(texLinks.size()); };
|
||||||
|
|
||||||
texwrap_t *getWrapSettings() { return &wrapSettings; };
|
inline texwrap_t *getWrapSettings() { return &wrapSettings; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns always width * width * 3/4.
|
* Returns always width * width * 3/4.
|
||||||
* 3 for RGB, 4 for RGBA.
|
* 3 for RGB, 4 for RGBA.
|
||||||
*/
|
*/
|
||||||
u32 getDataSize() const { return _type == TEX_TYPE_RGB ? width * height * 3 : width * height * 4; };
|
inline u32 getDataSize() const { return _type == TEX_TYPE_RGB ? width * height * 3 : width * height * 4; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Texture data, used by renderer.
|
* Texture data, used by renderer.
|
||||||
* Array of size getDataSize().
|
* Array of size getDataSize().
|
||||||
*/
|
*/
|
||||||
unsigned char *getData() const { return data; };
|
inline unsigned char *getData() const { return data; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get texture name.
|
* Get texture name.
|
||||||
* For "textures/abc.bmp" result will be: "abc"
|
* For "textures/abc.bmp" result will be: "abc"
|
||||||
*/
|
*/
|
||||||
char *getName() const { return name; };
|
inline char *getName() const { return name; };
|
||||||
|
|
||||||
/** Array of texture links. Size of getTextureLinksCount() */
|
/** Array of texture links. Size of getTextureLinksCount() */
|
||||||
const std::vector<TextureLink> &getTextureLinks() const { return texLinks; };
|
inline const std::vector<TextureLink> &getTextureLinks() const { return texLinks; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns index of link.
|
* Returns index of link.
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ public:
|
|||||||
// ADPCM
|
// ADPCM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load ADPCM sample.
|
* Load ADPCM sample. ADPCM sample is an output from
|
||||||
|
* "adpenc" tool, shipped with PS2SDK.
|
||||||
* @param t_path Example: "hit.adpcm" or "folder/jump.adpcm"
|
* @param t_path Example: "hit.adpcm" or "folder/jump.adpcm"
|
||||||
*/
|
*/
|
||||||
audsrv_adpcm_t *loadADPCM(char *t_path);
|
audsrv_adpcm_t *loadADPCM(char *t_path);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <draw_primitives.h>
|
#include <draw_primitives.h>
|
||||||
#include <math3d.h>
|
#include <math3d.h>
|
||||||
#include <packet2.h>
|
#include <packet2.h>
|
||||||
|
#include "./light.hpp"
|
||||||
#include "../models/mesh.hpp"
|
#include "../models/mesh.hpp"
|
||||||
#include "../models/math/matrix.hpp"
|
#include "../models/math/matrix.hpp"
|
||||||
#include "../models/screen_settings.hpp"
|
#include "../models/screen_settings.hpp"
|
||||||
@@ -29,17 +30,18 @@ class GifSender
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GifSender(u32 t_packetSize, ScreenSettings *t_screen);
|
GifSender(u32 t_packetSize, ScreenSettings *t_screen, Light *t_light);
|
||||||
~GifSender();
|
~GifSender();
|
||||||
|
|
||||||
void initPacket(u8 context);
|
void initPacket(u8 context);
|
||||||
void addObject(RenderData *t_renderData, Mesh &t_mesh, u32 vertexCount, VECTOR *vertices, VECTOR *normals, VECTOR *coordinates, LightBulb *t_bulbs, u16 t_bulbsCount, texbuffer_t *textureBuffer);
|
void addObject(RenderData *t_renderData, Mesh &t_mesh, u32 vertexCount, VECTOR *vertices, VECTOR *normals, VECTOR *coordinates, LightBulb *t_bulbs, u16 t_bulbsCount, texbuffer_t *textureBuffer);
|
||||||
void addClear(zbuffer_t *t_zBuffer);
|
void addClear(zbuffer_t *t_zBuffer, color_t *t_rgb);
|
||||||
void sendPacket();
|
void sendPacket();
|
||||||
void sendClear(zbuffer_t *t_zBuffer);
|
void sendClear(zbuffer_t *t_zBuffer, color_t *t_rgb);
|
||||||
static void sendTexture(Texture &texture, texbuffer_t *t_texBuffer);
|
static void sendTexture(Texture &texture, texbuffer_t *t_texBuffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Light *light;
|
||||||
xyz_t *xyz;
|
xyz_t *xyz;
|
||||||
color_t *rgbaq;
|
color_t *rgbaq;
|
||||||
texel_t *st;
|
texel_t *st;
|
||||||
|
|||||||
@@ -23,10 +23,14 @@ public:
|
|||||||
Light();
|
Light();
|
||||||
~Light();
|
~Light();
|
||||||
|
|
||||||
static u16 getLightsCount(u32 t_bulbsCount);
|
u16 getLightsCount(u32 t_bulbsCount);
|
||||||
static void calculateLight(VECTOR *t_lightDirections, VECTOR *t_lightColors, int *t_lightTypes, LightBulb *t_bulbs, u32 t_lightsCount, Vector3 t_objPosition);
|
|
||||||
|
/** Values from 0.0000F to 1.0000F */
|
||||||
|
void setAmbientLight(const Vector3 &t_rgb);
|
||||||
|
void calculateLight(VECTOR *t_lightDirections, VECTOR *t_lightColors, int *t_lightTypes, LightBulb *t_bulbs, u32 t_lightsCount, Vector3 t_objPosition);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Vector3 ambientLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <packet2.h>
|
#include <packet2.h>
|
||||||
#include "gif_sender.hpp"
|
#include "gif_sender.hpp"
|
||||||
#include "vif_sender.hpp"
|
#include "vif_sender.hpp"
|
||||||
|
#include "light.hpp"
|
||||||
#include "../models/math/plane.hpp"
|
#include "../models/math/plane.hpp"
|
||||||
#include "../models/sprite.hpp"
|
#include "../models/sprite.hpp"
|
||||||
#include "../models/screen_settings.hpp"
|
#include "../models/screen_settings.hpp"
|
||||||
@@ -102,11 +103,19 @@ public:
|
|||||||
|
|
||||||
void setCameraDefinitions(Matrix *t_worldView, Vector3 *t_cameraPos, Plane *t_planes);
|
void setCameraDefinitions(Matrix *t_worldView, Vector3 *t_cameraPos, Plane *t_planes);
|
||||||
|
|
||||||
|
void setWorldColor(const color_t &t_rgb);
|
||||||
|
|
||||||
void endFrame(float fps);
|
void endFrame(float fps);
|
||||||
|
|
||||||
TextureRepository *getTextureRepository() { return &textureRepo; };
|
void setAmbientLight(const Vector3 &t_rgb) { light.setAmbientLight(t_rgb); }
|
||||||
|
|
||||||
|
TextureRepository *getTextureRepository()
|
||||||
|
{
|
||||||
|
return &textureRepo;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// We have some GCC bug here. Just try to reorder declarations. For example move worldColor up - game will crash.
|
||||||
void changeTexture(Texture *t_tex);
|
void changeTexture(Texture *t_tex);
|
||||||
u32 lastTextureId;
|
u32 lastTextureId;
|
||||||
texbuffer_t textureBuffer;
|
texbuffer_t textureBuffer;
|
||||||
@@ -117,12 +126,14 @@ private:
|
|||||||
void beginFrameIfNeeded();
|
void beginFrameIfNeeded();
|
||||||
u8 isFrameEmpty;
|
u8 isFrameEmpty;
|
||||||
Matrix perspective;
|
Matrix perspective;
|
||||||
|
Light light;
|
||||||
RenderData renderData;
|
RenderData renderData;
|
||||||
TextureRepository textureRepo;
|
TextureRepository textureRepo;
|
||||||
ScreenSettings *screen;
|
ScreenSettings *screen;
|
||||||
GifSender *gifSender;
|
GifSender *gifSender;
|
||||||
VifSender *vifSender;
|
VifSender *vifSender;
|
||||||
packet2_t *flipPacket;
|
packet2_t *flipPacket;
|
||||||
|
color_t worldColor;
|
||||||
void allocateBuffers(float t_screenW, float t_screenH);
|
void allocateBuffers(float t_screenW, float t_screenH);
|
||||||
void initDrawingEnv(float t_screenW, float t_screenH);
|
void initDrawingEnv(float t_screenW, float t_screenH);
|
||||||
void setPrim();
|
void setPrim();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <tamtypes.h>
|
#include <tamtypes.h>
|
||||||
#include <packet2_utils.h>
|
#include <packet2_utils.h>
|
||||||
#include "../models/render_data.hpp"
|
#include "../models/render_data.hpp"
|
||||||
|
#include "./light.hpp"
|
||||||
#include "../models/light_bulb.hpp"
|
#include "../models/light_bulb.hpp"
|
||||||
#include "../models/mesh.hpp"
|
#include "../models/mesh.hpp"
|
||||||
#include "../models/math/matrix.hpp"
|
#include "../models/math/matrix.hpp"
|
||||||
@@ -24,7 +25,7 @@ class VifSender
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VifSender();
|
VifSender(Light *t_light);
|
||||||
~VifSender();
|
~VifSender();
|
||||||
|
|
||||||
// TODO refactor
|
// TODO refactor
|
||||||
@@ -32,6 +33,7 @@ public:
|
|||||||
void sendMatrices(const RenderData &t_renderData, const Vector3 &t_position, const Vector3 &t_rotation);
|
void sendMatrices(const RenderData &t_renderData, const Vector3 &t_position, const Vector3 &t_rotation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Light *light;
|
||||||
void uploadMicroProgram();
|
void uploadMicroProgram();
|
||||||
void setDoubleBuffer();
|
void setDoubleBuffer();
|
||||||
void drawVertices(Mesh &t_mesh, u32 t_start, u32 t_end, VECTOR *t_vertices, VECTOR *t_coordinates, prim_t *t_prim, texbuffer_t *textureBuffer);
|
void drawVertices(Mesh &t_mesh, u32 t_start, u32 t_end, VECTOR *t_vertices, VECTOR *t_coordinates, prim_t *t_prim, texbuffer_t *textureBuffer);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ Sprite::Sprite()
|
|||||||
_flipH = false;
|
_flipH = false;
|
||||||
_flipV = false;
|
_flipV = false;
|
||||||
scale = 1.0F;
|
scale = 1.0F;
|
||||||
|
mode = MODE_REPEAT;
|
||||||
setDefaultColor();
|
setDefaultColor();
|
||||||
setDefaultLODAndClut();
|
setDefaultLODAndClut();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "../include/utils/math.hpp"
|
#include "../include/utils/math.hpp"
|
||||||
#include "../include/utils/debug.hpp"
|
#include "../include/utils/debug.hpp"
|
||||||
#include "../include/modules/light.hpp"
|
|
||||||
#include <packet2_chain.h>
|
#include <packet2_chain.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <dma.h>
|
#include <dma.h>
|
||||||
@@ -29,9 +28,10 @@
|
|||||||
/** Initializes vars and creates data transfer packets
|
/** Initializes vars and creates data transfer packets
|
||||||
* @param packetSize Size of data packet, should be increased when more data will be rendered
|
* @param packetSize Size of data packet, should be increased when more data will be rendered
|
||||||
*/
|
*/
|
||||||
GifSender::GifSender(u32 t_packetSize, ScreenSettings *t_screen) : screen(t_screen)
|
GifSender::GifSender(u32 t_packetSize, ScreenSettings *t_screen, Light *t_light) : screen(t_screen)
|
||||||
{
|
{
|
||||||
PRINT_LOG("Initializing GifSender");
|
PRINT_LOG("Initializing GifSender");
|
||||||
|
light = t_light;
|
||||||
packetSize = t_packetSize;
|
packetSize = t_packetSize;
|
||||||
packets[0] = packet2_create(t_packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
packets[0] = packet2_create(t_packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
||||||
packets[1] = packet2_create(t_packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
packets[1] = packet2_create(t_packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
||||||
@@ -76,7 +76,7 @@ void GifSender::sendTexture(Texture &texture, texbuffer_t *t_texBuffer)
|
|||||||
packet2_free(packet2);
|
packet2_free(packet2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GifSender::sendClear(zbuffer_t *t_zBuffer)
|
void GifSender::sendClear(zbuffer_t *t_zBuffer, color_t *t_rgb)
|
||||||
{
|
{
|
||||||
packet2_t *packet2 = packet2_create(36, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
packet2_t *packet2 = packet2_create(36, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
||||||
packet2_chain_open_end(packet2, 0, 0);
|
packet2_chain_open_end(packet2, 0, 0);
|
||||||
@@ -84,7 +84,7 @@ void GifSender::sendClear(zbuffer_t *t_zBuffer)
|
|||||||
packet2_update(packet2, draw_clear(packet2->next, 0,
|
packet2_update(packet2, draw_clear(packet2->next, 0,
|
||||||
2048.0F - (screen->width / 2), 2048.0F - (screen->height / 2),
|
2048.0F - (screen->width / 2), 2048.0F - (screen->height / 2),
|
||||||
screen->width, screen->height,
|
screen->width, screen->height,
|
||||||
0x10, 0x10, 0x10));
|
t_rgb->r, t_rgb->g, t_rgb->b));
|
||||||
packet2_update(packet2, draw_enable_tests(packet2->next, 0, t_zBuffer));
|
packet2_update(packet2, draw_enable_tests(packet2->next, 0, t_zBuffer));
|
||||||
packet2_update(packet2, draw_finish(packet2->next));
|
packet2_update(packet2, draw_finish(packet2->next));
|
||||||
packet2_chain_close_tag(packet2);
|
packet2_chain_close_tag(packet2);
|
||||||
@@ -118,14 +118,14 @@ void GifSender::sendPacket()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Adds clear screen to current packet */
|
/** Adds clear screen to current packet */
|
||||||
void GifSender::addClear(zbuffer_t *t_zBuffer)
|
void GifSender::addClear(zbuffer_t *t_zBuffer, color_t *t_rgb)
|
||||||
{
|
{
|
||||||
packet2_chain_open_cnt(currentPacket, 0, 0, 0);
|
packet2_chain_open_cnt(currentPacket, 0, 0, 0);
|
||||||
packet2_update(currentPacket, draw_disable_tests(currentPacket->next, 0, t_zBuffer));
|
packet2_update(currentPacket, draw_disable_tests(currentPacket->next, 0, t_zBuffer));
|
||||||
packet2_update(currentPacket, draw_clear(currentPacket->next, 0,
|
packet2_update(currentPacket, draw_clear(currentPacket->next, 0,
|
||||||
2048.0F - (screen->width / 2), 2048.0F - (screen->height / 2),
|
2048.0F - (screen->width / 2), 2048.0F - (screen->height / 2),
|
||||||
screen->width, screen->height,
|
screen->width, screen->height,
|
||||||
0x10, 0x10, 0x10));
|
t_rgb->r, t_rgb->g, t_rgb->b));
|
||||||
packet2_update(currentPacket, draw_enable_tests(currentPacket->next, 0, t_zBuffer));
|
packet2_update(currentPacket, draw_enable_tests(currentPacket->next, 0, t_zBuffer));
|
||||||
packet2_chain_close_tag(currentPacket);
|
packet2_chain_close_tag(currentPacket);
|
||||||
}
|
}
|
||||||
@@ -180,7 +180,7 @@ void GifSender::calc3DObject(Matrix t_perspective, Mesh &t_mesh, u32 vertexCount
|
|||||||
|
|
||||||
if (SHOULD_BE_LIGHTED)
|
if (SHOULD_BE_LIGHTED)
|
||||||
{
|
{
|
||||||
const u16 lightsCount = Light::getLightsCount(t_bulbsCount);
|
const u16 lightsCount = light->getLightsCount(t_bulbsCount);
|
||||||
VECTOR *lightDirections = new VECTOR[lightsCount];
|
VECTOR *lightDirections = new VECTOR[lightsCount];
|
||||||
VECTOR *lightColors = new VECTOR[lightsCount];
|
VECTOR *lightColors = new VECTOR[lightsCount];
|
||||||
int *lightTypes = new int[lightsCount];
|
int *lightTypes = new int[lightsCount];
|
||||||
@@ -188,7 +188,7 @@ void GifSender::calc3DObject(Matrix t_perspective, Mesh &t_mesh, u32 vertexCount
|
|||||||
VECTOR *lights = new VECTOR[vertexCount];
|
VECTOR *lights = new VECTOR[vertexCount];
|
||||||
calculate_normals(normals, vertexCount, normals, localLight);
|
calculate_normals(normals, vertexCount, normals, localLight);
|
||||||
|
|
||||||
Light::calculateLight(lightDirections, lightColors, lightTypes, t_bulbs, lightsCount, t_mesh.position);
|
light->calculateLight(lightDirections, lightColors, lightTypes, t_bulbs, lightsCount, t_mesh.position);
|
||||||
|
|
||||||
calculate_lights(lights, vertexCount, normals, lightDirections, lightColors, lightTypes, lightsCount);
|
calculate_lights(lights, vertexCount, normals, lightDirections, lightColors, lightTypes, lightsCount);
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ const u8 ADDITIONAL_LIGHTS = 1; // Ambient
|
|||||||
const float LIGHT_MAX = 255.0F;
|
const float LIGHT_MAX = 255.0F;
|
||||||
const float LIGHT_DIS_MOD = 4.0F;
|
const float LIGHT_DIS_MOD = 4.0F;
|
||||||
|
|
||||||
|
void Light::setAmbientLight(const Vector3 &t_rgb) { ambientLight.set(t_rgb); }
|
||||||
|
|
||||||
u16 Light::getLightsCount(u32 t_bulbsCount) { return t_bulbsCount + ADDITIONAL_LIGHTS; }
|
u16 Light::getLightsCount(u32 t_bulbsCount) { return t_bulbsCount + ADDITIONAL_LIGHTS; }
|
||||||
|
|
||||||
/** Calculates lighting. Used in gifSender in object 3D calculations */
|
/** Calculates lighting. Used in gifSender in object 3D calculations */
|
||||||
@@ -40,9 +42,9 @@ void Light::calculateLight(VECTOR *t_lightDirections, VECTOR *t_lightColors, int
|
|||||||
t_lightDirections[0][2] = 0.0F;
|
t_lightDirections[0][2] = 0.0F;
|
||||||
t_lightDirections[0][3] = 1.0F;
|
t_lightDirections[0][3] = 1.0F;
|
||||||
|
|
||||||
t_lightColors[0][0] = 0.0F;
|
t_lightColors[0][0] = ambientLight.x;
|
||||||
t_lightColors[0][1] = 0.0F;
|
t_lightColors[0][1] = ambientLight.y;
|
||||||
t_lightColors[0][2] = 0.0F;
|
t_lightColors[0][2] = ambientLight.z;
|
||||||
t_lightColors[0][3] = 1.0F;
|
t_lightColors[0][3] = 1.0F;
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|||||||
@@ -44,9 +44,12 @@ Renderer::Renderer(u32 t_packetSize, ScreenSettings *t_screen)
|
|||||||
allocateBuffers(t_screen->width, t_screen->height);
|
allocateBuffers(t_screen->width, t_screen->height);
|
||||||
initDrawingEnv(t_screen->width, t_screen->height);
|
initDrawingEnv(t_screen->width, t_screen->height);
|
||||||
setPrim();
|
setPrim();
|
||||||
|
worldColor.r = 0x10;
|
||||||
|
worldColor.g = 0x10;
|
||||||
|
worldColor.b = 0x10;
|
||||||
screen = t_screen;
|
screen = t_screen;
|
||||||
gifSender = new GifSender(t_packetSize, t_screen);
|
gifSender = new GifSender(t_packetSize, t_screen, &light);
|
||||||
vifSender = new VifSender();
|
vifSender = new VifSender(&light);
|
||||||
perspective.setPerspective(*t_screen);
|
perspective.setPerspective(*t_screen);
|
||||||
renderData.perspective = &perspective;
|
renderData.perspective = &perspective;
|
||||||
PRINT_LOG("Renderer initialized!");
|
PRINT_LOG("Renderer initialized!");
|
||||||
@@ -101,14 +104,26 @@ void Renderer::changeTexture(Texture *t_tex)
|
|||||||
|
|
||||||
void Renderer::draw(Sprite &t_sprite)
|
void Renderer::draw(Sprite &t_sprite)
|
||||||
{
|
{
|
||||||
|
Texture *texture = textureRepo.getBySprite(t_sprite.getId());
|
||||||
texrect_t rect;
|
texrect_t rect;
|
||||||
float texMax = t_sprite.size.x > t_sprite.size.y ? t_sprite.size.x : t_sprite.size.y;
|
float sizeX, sizeY;
|
||||||
float texS = texMax;
|
if (t_sprite.getMode() == MODE_REPEAT)
|
||||||
float texT = texMax;
|
{
|
||||||
if (t_sprite.size.x > t_sprite.size.y)
|
sizeX = t_sprite.size.x;
|
||||||
texT = texMax / (t_sprite.size.x / t_sprite.size.y);
|
sizeY = t_sprite.size.y;
|
||||||
else if (t_sprite.size.y > t_sprite.size.x)
|
}
|
||||||
texS = texMax / (t_sprite.size.y / t_sprite.size.x);
|
else
|
||||||
|
{
|
||||||
|
sizeX = (float)texture->getWidth();
|
||||||
|
sizeY = (float)texture->getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
float texS, texT;
|
||||||
|
float texMax = texT = texS = sizeX > sizeY ? sizeX : sizeY;
|
||||||
|
if (sizeX > sizeY)
|
||||||
|
texT = texMax / (sizeX / sizeY);
|
||||||
|
else if (sizeY > sizeX)
|
||||||
|
texS = texMax / (sizeY / sizeX);
|
||||||
rect.t0.s = t_sprite.isFlippedHorizontally() ? texS : 0.0F;
|
rect.t0.s = t_sprite.isFlippedHorizontally() ? texS : 0.0F;
|
||||||
rect.t0.t = t_sprite.isFlippedVertically() ? texT : 0.0F;
|
rect.t0.t = t_sprite.isFlippedVertically() ? texT : 0.0F;
|
||||||
rect.t1.s = t_sprite.isFlippedHorizontally() ? 0.0F : texS;
|
rect.t1.s = t_sprite.isFlippedHorizontally() ? 0.0F : texS;
|
||||||
@@ -125,7 +140,7 @@ void Renderer::draw(Sprite &t_sprite)
|
|||||||
rect.v1.y = (t_sprite.size.y * t_sprite.scale) + t_sprite.position.y;
|
rect.v1.y = (t_sprite.size.y * t_sprite.scale) + t_sprite.position.y;
|
||||||
rect.v1.z = (u32)-1;
|
rect.v1.z = (u32)-1;
|
||||||
beginFrameIfNeeded();
|
beginFrameIfNeeded();
|
||||||
changeTexture(textureRepo.getBySprite(t_sprite.getId()));
|
changeTexture(texture);
|
||||||
packet2_t *packet2 = packet2_create(12, P2_TYPE_NORMAL, P2_MODE_NORMAL, 0);
|
packet2_t *packet2 = packet2_create(12, P2_TYPE_NORMAL, P2_MODE_NORMAL, 0);
|
||||||
packet2_update(packet2, draw_primitive_xyoffset(packet2->next, 0, 2048, 2048));
|
packet2_update(packet2, draw_primitive_xyoffset(packet2->next, 0, 2048, 2048));
|
||||||
packet2_utils_gif_add_set(packet2, 1);
|
packet2_utils_gif_add_set(packet2, 1);
|
||||||
@@ -175,6 +190,13 @@ void Renderer::setPrim()
|
|||||||
PRINT_LOG("Prim set!");
|
PRINT_LOG("Prim set!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::setWorldColor(const color_t &t_rgb)
|
||||||
|
{
|
||||||
|
worldColor.r = t_rgb.r;
|
||||||
|
worldColor.g = t_rgb.g;
|
||||||
|
worldColor.b = t_rgb.b;
|
||||||
|
}
|
||||||
|
|
||||||
/** Defines and allocates framebuffers and zbuffer */
|
/** Defines and allocates framebuffers and zbuffer */
|
||||||
void Renderer::allocateBuffers(float t_screenW, float t_screenH)
|
void Renderer::allocateBuffers(float t_screenW, float t_screenH)
|
||||||
{
|
{
|
||||||
@@ -293,7 +315,7 @@ void Renderer::beginFrameIfNeeded()
|
|||||||
if (isFrameEmpty)
|
if (isFrameEmpty)
|
||||||
{
|
{
|
||||||
isFrameEmpty = false;
|
isFrameEmpty = false;
|
||||||
gifSender->sendClear(&zBuffer);
|
gifSender->sendClear(&zBuffer, &worldColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ extern u32 VU1Draw3D_CodeStart __attribute__((section(".vudata")));
|
|||||||
extern u32 VU1Draw3D_CodeEnd __attribute__((section(".vudata")));
|
extern u32 VU1Draw3D_CodeEnd __attribute__((section(".vudata")));
|
||||||
//
|
//
|
||||||
|
|
||||||
VifSender::VifSender()
|
VifSender::VifSender(Light *t_light)
|
||||||
{
|
{
|
||||||
|
light = t_light;
|
||||||
PRINT_LOG("Initializing VifSender");
|
PRINT_LOG("Initializing VifSender");
|
||||||
PRINT_LOG("VifSender initialized!");
|
PRINT_LOG("VifSender initialized!");
|
||||||
dma_channel_initialize(DMA_CHANNEL_VIF1, NULL, 0);
|
dma_channel_initialize(DMA_CHANNEL_VIF1, NULL, 0);
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ EE_OBJS = \
|
|||||||
managers/light_manager.o \
|
managers/light_manager.o \
|
||||||
managers/floor_manager.o \
|
managers/floor_manager.o \
|
||||||
camera.o \
|
camera.o \
|
||||||
|
objects/enemy.o \
|
||||||
objects/floor.o \
|
objects/floor.o \
|
||||||
objects/player.o \
|
objects/player.o \
|
||||||
|
ui.o \
|
||||||
utils.o \
|
utils.o \
|
||||||
floors.o \
|
floors.o \
|
||||||
main.o
|
main.o
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ void Camera::update(Pad &t_pad, Mesh &t_mesh)
|
|||||||
*/
|
*/
|
||||||
void Camera::rotate(Pad &t_pad)
|
void Camera::rotate(Pad &t_pad)
|
||||||
{
|
{
|
||||||
if (t_pad.rJoyH <= 50)
|
if (t_pad.rJoyH <= 100)
|
||||||
horizontalLevel -= 0.08;
|
horizontalLevel -= 0.08;
|
||||||
else if (t_pad.rJoyH >= 200)
|
else if (t_pad.rJoyH >= 200)
|
||||||
horizontalLevel += 0.04;
|
horizontalLevel += 0.08;
|
||||||
if (t_pad.rJoyV <= 50 && verticalLevel > 25.0F)
|
if (t_pad.rJoyV <= 50 && verticalLevel > 25.0F)
|
||||||
verticalLevel -= 0.9F;
|
verticalLevel -= 0.9F;
|
||||||
else if (t_pad.rJoyV >= 200 && verticalLevel < 80.0F)
|
else if (t_pad.rJoyV >= 200 && verticalLevel < 80.0F)
|
||||||
@@ -67,15 +67,4 @@ void Camera::followBy(Mesh &t_mesh)
|
|||||||
position.x = unitCirclePosition.x + t_mesh.position.x;
|
position.x = unitCirclePosition.x + t_mesh.position.x;
|
||||||
position.y = unitCirclePosition.y + t_mesh.position.y;
|
position.y = unitCirclePosition.y + t_mesh.position.y;
|
||||||
position.z = unitCirclePosition.z + t_mesh.position.z;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,22 @@
|
|||||||
// Constructors/Destructors
|
// Constructors/Destructors
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
const u8 FLOORS_COUNT = 144; // Temp change it also in floor_manager.hpp
|
const u16 FLOORS_COUNT = 144; // Temp change it also in floor_manager.hpp
|
||||||
|
|
||||||
Floors::Floors(Engine *t_engine)
|
Floors::Floors(Engine *t_engine)
|
||||||
: engine(t_engine), floorManager(FLOORS_COUNT), camera(&t_engine->screen)
|
: engine(t_engine), floorManager(), camera(&t_engine->screen)
|
||||||
{
|
{
|
||||||
audioTicks = 0;
|
audioTicks = 0;
|
||||||
|
skip1Beat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Floors::~Floors() {}
|
Floors::~Floors()
|
||||||
|
{
|
||||||
|
delete enemy;
|
||||||
|
delete ui;
|
||||||
|
delete floorManager;
|
||||||
|
delete player;
|
||||||
|
}
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// Methods
|
// Methods
|
||||||
@@ -30,43 +37,58 @@ Floors::~Floors() {}
|
|||||||
|
|
||||||
void Floors::onInit()
|
void Floors::onInit()
|
||||||
{
|
{
|
||||||
|
setBgColorAndAmbientColor();
|
||||||
engine->renderer->setCameraDefinitions(&camera.worldView, &camera.unitCirclePosition, camera.planes);
|
engine->renderer->setCameraDefinitions(&camera.worldView, &camera.unitCirclePosition, camera.planes);
|
||||||
engine->audio.addSongListener(this);
|
engine->audio.addSongListener(this);
|
||||||
engine->audio.loadSong("NF-CHILL.WAV");
|
engine->audio.loadSong("sounds/mafikizolo-loot.wav");
|
||||||
engine->audio.setSongVolume(100);
|
|
||||||
engine->audio.playSong();
|
engine->audio.playSong();
|
||||||
|
engine->audio.setSongVolume(80);
|
||||||
texRepo = engine->renderer->getTextureRepository();
|
texRepo = engine->renderer->getTextureRepository();
|
||||||
texRepo->addByMesh("warrior/", player.mesh, BMP);
|
enemy = new Enemy(texRepo);
|
||||||
texRepo->addByMesh("floor/", floorManager.floors[0].mesh, BMP);
|
ui = new Ui(texRepo);
|
||||||
for (u32 i = 1; i < floorManager.floorAmount; i++)
|
floorManager = new FloorManager(FLOORS_COUNT, texRepo);
|
||||||
texRepo->getByMesh(floorManager.floors[0].mesh.getId(), floorManager.floors[0].mesh.getMaterial(0).getId())
|
player = new Player(&engine->audio, texRepo);
|
||||||
->addLink(floorManager.floors[i].mesh.getId(), floorManager.floors[i].mesh.getMaterial(0).getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Floors::onUpdate()
|
void Floors::onUpdate()
|
||||||
{
|
{
|
||||||
if (engine->pad.isCrossClicked)
|
ui->update(*player);
|
||||||
printf("FPS:%f\n", engine->fps);
|
enemy->update(*floorManager);
|
||||||
lightManager.update();
|
lightManager.update();
|
||||||
camera.update(engine->pad, player.mesh);
|
camera.update(engine->pad, player->mesh);
|
||||||
floorManager.update(player);
|
floorManager->update(*player);
|
||||||
player.update(engine->pad, camera, floorManager);
|
player->update(engine->pad, camera, *floorManager, *enemy);
|
||||||
engine->renderer->draw(player.mesh);
|
engine->renderer->draw(player->mesh);
|
||||||
for (u8 i = 0; i < FLOORS_COUNT; i++)
|
engine->renderer->draw(enemy->getMeshes(), enemy->getMeshesCount());
|
||||||
engine->renderer->drawByPath3(floorManager.floors[i].mesh, lightManager.bulbs, lightManager.bulbsCount);
|
for (u16 i = 0; i < FLOORS_COUNT; i++)
|
||||||
|
engine->renderer->drawByPath3(floorManager->floors[i].mesh, lightManager.bulbs, lightManager.bulbsCount);
|
||||||
|
ui->render(engine->renderer); // 2D rendering ist LAST step, because layers gonna play there.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Floors::onAudioTick()
|
void Floors::onAudioTick()
|
||||||
{
|
{
|
||||||
if ((++audioTicks + 20) % 41 == 0)
|
if ((++audioTicks + 20) % 21 == 0)
|
||||||
{
|
{
|
||||||
floorManager.onAudioTick();
|
if (skip1Beat)
|
||||||
|
floorManager->onAudioTick();
|
||||||
lightManager.onAudioTick();
|
lightManager.onAudioTick();
|
||||||
|
skip1Beat = !skip1Beat;
|
||||||
}
|
}
|
||||||
if (audioTicks > 10000)
|
if (audioTicks > 10000)
|
||||||
audioTicks = 0;
|
audioTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Floors::setBgColorAndAmbientColor()
|
||||||
|
{
|
||||||
|
color_t bgColor;
|
||||||
|
bgColor.r = 0x20;
|
||||||
|
bgColor.g = 0x20;
|
||||||
|
bgColor.b = 0x20;
|
||||||
|
engine->renderer->setWorldColor(bgColor);
|
||||||
|
Vector3 ambient = Vector3(0.003F, 0.003F, 0.003F);
|
||||||
|
engine->renderer->setAmbientLight(ambient);
|
||||||
|
}
|
||||||
|
|
||||||
void Floors::onAudioFinish()
|
void Floors::onAudioFinish()
|
||||||
{
|
{
|
||||||
audioTicks = 0;
|
audioTicks = 0;
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
#include "managers/light_manager.hpp"
|
#include "managers/light_manager.hpp"
|
||||||
#include "modules/texture_repository.hpp"
|
#include "modules/texture_repository.hpp"
|
||||||
#include "objects/player.hpp"
|
#include "objects/player.hpp"
|
||||||
|
#include "objects/enemy.hpp"
|
||||||
#include "./camera.hpp"
|
#include "./camera.hpp"
|
||||||
|
#include "./ui.hpp"
|
||||||
|
|
||||||
class Floors : public Game, AudioListener
|
class Floors : public Game, AudioListener
|
||||||
{
|
{
|
||||||
@@ -35,12 +37,16 @@ public:
|
|||||||
Engine *engine;
|
Engine *engine;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setBgColorAndAmbientColor();
|
||||||
u32 audioTicks;
|
u32 audioTicks;
|
||||||
|
u8 skip1Beat;
|
||||||
TextureRepository *texRepo;
|
TextureRepository *texRepo;
|
||||||
LightManager lightManager;
|
LightManager lightManager;
|
||||||
FloorManager floorManager;
|
FloorManager *floorManager;
|
||||||
Player player;
|
Player *player;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
Ui *ui;
|
||||||
|
Enemy *enemy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,13 +20,18 @@
|
|||||||
/** Calculate square spiral offsets and initialize floors
|
/** Calculate square spiral offsets and initialize floors
|
||||||
* @param floorAmount must be a number from square root table
|
* @param floorAmount must be a number from square root table
|
||||||
*/
|
*/
|
||||||
FloorManager::FloorManager(int t_floorAmount)
|
FloorManager::FloorManager(int t_floorAmount, TextureRepository *t_texRepo)
|
||||||
{
|
{
|
||||||
|
texRepo = t_texRepo;
|
||||||
floorAmount = t_floorAmount;
|
floorAmount = t_floorAmount;
|
||||||
spirals = new Point[t_floorAmount];
|
spirals = new Point[t_floorAmount];
|
||||||
int floorSpiralMaxOffset = (int)Math::sqrt(t_floorAmount);
|
int floorSpiralMaxOffset = (int)Math::sqrt(t_floorAmount);
|
||||||
calcSpiral(floorSpiralMaxOffset, floorSpiralMaxOffset);
|
calcSpiral(floorSpiralMaxOffset, floorSpiralMaxOffset);
|
||||||
initFloors();
|
initFloors();
|
||||||
|
trick = 0.0F;
|
||||||
|
trickMode = 0;
|
||||||
|
isTimeForChangeTriggerColor = true;
|
||||||
|
isTimeForChangeDefaultColor = true;
|
||||||
audioOffset = audioMode = audioTick = 0;
|
audioOffset = audioMode = audioTick = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,11 +82,16 @@ void FloorManager::calcSpiral(int X, int Y)
|
|||||||
void FloorManager::initFloors()
|
void FloorManager::initFloors()
|
||||||
{
|
{
|
||||||
PRINT_LOG("Initializing floors");
|
PRINT_LOG("Initializing floors");
|
||||||
floors[0].mesh.loadObj("floor/", "floor", 3.0F, false);
|
floors[0].mesh.loadObj("meshes/floor/", "floor", 3.0F, false);
|
||||||
floors[0].mesh.shouldBeFrustumCulled = true;
|
floors[0].mesh.shouldBeFrustumCulled = true;
|
||||||
floors[0].mesh.shouldBeLighted = true;
|
floors[0].mesh.shouldBeLighted = true;
|
||||||
for (u8 i = 1; i < floorAmount; i++)
|
texRepo->addByMesh("meshes/floor/", floors[0].mesh, BMP);
|
||||||
|
for (u16 i = 1; i < floorAmount; i++)
|
||||||
|
{
|
||||||
floors[i].init(floors[0].mesh, spirals[i], i);
|
floors[i].init(floors[0].mesh, spirals[i], i);
|
||||||
|
texRepo->getByMesh(floors[0].mesh.getId(), floors[0].mesh.getMaterial(0).getId())
|
||||||
|
->addLink(floors[i].mesh.getId(), floors[i].mesh.getMaterial(0).getId());
|
||||||
|
}
|
||||||
PRINT_LOG("Floors initialized!");
|
PRINT_LOG("Floors initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,25 +102,75 @@ void FloorManager::initFloors()
|
|||||||
*/
|
*/
|
||||||
void FloorManager::update(Player &t_player)
|
void FloorManager::update(Player &t_player)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
if (isTimeForChangeTriggerColor)
|
||||||
|
{
|
||||||
|
isTimeForChangeTriggerColor = false;
|
||||||
|
trigColor.r = rand() % (128 - 64 + 1) + 64;
|
||||||
|
trigColor.g = rand() % (128 - 64 + 1) + 64;
|
||||||
|
trigColor.b = rand() % (128 - 64 + 1) + 64;
|
||||||
|
}
|
||||||
|
if (isTimeForChangeDefaultColor)
|
||||||
|
{
|
||||||
|
isTimeForChangeDefaultColor = false;
|
||||||
|
defaultColor.r = rand() % (64 + 1);
|
||||||
|
defaultColor.g = rand() % (64 + 1);
|
||||||
|
defaultColor.b = rand() % (64 + 1);
|
||||||
|
}
|
||||||
|
doTheTrick();
|
||||||
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
floors[i].animate(t_player);
|
floors[i].animate(t_player);
|
||||||
|
|
||||||
if (floors[i].isByAudioTriggered == true)
|
if (floors[i].isByAudioTriggered)
|
||||||
floors[i].mesh.color.a = 0x20;
|
{
|
||||||
|
floors[i].mesh.color.r = trigColor.r;
|
||||||
|
floors[i].mesh.color.g = trigColor.g;
|
||||||
|
floors[i].mesh.color.b = trigColor.b;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
floors[i].mesh.color.a = 0x80;
|
{
|
||||||
|
floors[i].mesh.color.r = defaultColor.r;
|
||||||
|
floors[i].mesh.color.g = defaultColor.g;
|
||||||
|
floors[i].mesh.color.b = defaultColor.b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FloorManager::doTheTrick()
|
||||||
|
{
|
||||||
|
if (trickMode == 0)
|
||||||
|
{
|
||||||
|
if (trick > 3.0F)
|
||||||
|
{
|
||||||
|
isTimeForChangeTriggerColor = true;
|
||||||
|
trickMode = 1;
|
||||||
|
}
|
||||||
|
trick += 0.01F;
|
||||||
|
}
|
||||||
|
else if (trickMode == 1)
|
||||||
|
{
|
||||||
|
if (trick <= 0.1F)
|
||||||
|
{
|
||||||
|
isTimeForChangeTriggerColor = true;
|
||||||
|
trickMode = 0;
|
||||||
|
}
|
||||||
|
trick -= 0.01F;
|
||||||
|
}
|
||||||
|
floors[0].mesh.getFrames()[0].getST(1).set(trick, trick);
|
||||||
|
floors[0].mesh.getFrames()[0].getST(4).set(trick, trick);
|
||||||
|
floors[0].mesh.getFrames()[0].getST(7).set(trick, trick);
|
||||||
|
floors[0].mesh.getFrames()[0].getST(10).set(trick, trick);
|
||||||
|
floors[0].mesh.getFrames()[0].getST(13).set(trick, trick);
|
||||||
|
}
|
||||||
|
|
||||||
/** Called by audio thread */
|
/** Called by audio thread */
|
||||||
void FloorManager::onAudioTick()
|
void FloorManager::onAudioTick()
|
||||||
{
|
{
|
||||||
if (audioTick++ > 16)
|
if (audioTick++ > 19)
|
||||||
{
|
{
|
||||||
if (audioMode == 0)
|
if (audioMode == 0)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if ((i + audioOffset) % 2 == 0)
|
if ((i + audioOffset) % 2 == 0)
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
@@ -120,12 +180,13 @@ void FloorManager::onAudioTick()
|
|||||||
if (++audioOffset > 3)
|
if (++audioOffset > 3)
|
||||||
{
|
{
|
||||||
audioOffset = 0;
|
audioOffset = 0;
|
||||||
|
isTimeForChangeDefaultColor = true;
|
||||||
audioMode = 1;
|
audioMode = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (audioMode == 1)
|
else if (audioMode == 1)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if (i < floorAmount / (audioOffset + 1))
|
if (i < floorAmount / (audioOffset + 1))
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
@@ -135,12 +196,13 @@ void FloorManager::onAudioTick()
|
|||||||
if (++audioOffset > 3)
|
if (++audioOffset > 3)
|
||||||
{
|
{
|
||||||
audioOffset = 0;
|
audioOffset = 0;
|
||||||
|
isTimeForChangeDefaultColor = true;
|
||||||
audioMode = 2;
|
audioMode = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (audioMode == 2)
|
else if (audioMode == 2)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if ((i + audioOffset) % 4 == 0)
|
if ((i + audioOffset) % 4 == 0)
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
@@ -150,14 +212,15 @@ void FloorManager::onAudioTick()
|
|||||||
if (++audioOffset > 3)
|
if (++audioOffset > 3)
|
||||||
{
|
{
|
||||||
audioOffset = 0;
|
audioOffset = 0;
|
||||||
|
isTimeForChangeDefaultColor = true;
|
||||||
audioMode = 3;
|
audioMode = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (audioMode == 3)
|
else if (audioMode == 3)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if (u8(i + 1) > floorAmount / (audioOffset + 1))
|
if (u16(i + 1) > floorAmount / (audioOffset + 1))
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
else
|
else
|
||||||
floors[i].isByAudioTriggered = false;
|
floors[i].isByAudioTriggered = false;
|
||||||
@@ -165,6 +228,7 @@ void FloorManager::onAudioTick()
|
|||||||
if (++audioOffset > 3)
|
if (++audioOffset > 3)
|
||||||
{
|
{
|
||||||
audioOffset = 0;
|
audioOffset = 0;
|
||||||
|
isTimeForChangeDefaultColor = true;
|
||||||
audioMode = 0;
|
audioMode = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
class Player; // Forward definition
|
class Player; // Forward definition
|
||||||
|
|
||||||
#include <models/math/point.hpp>
|
#include <models/math/point.hpp>
|
||||||
|
#include <modules/texture_repository.hpp>
|
||||||
#include <modules/camera_base.hpp>
|
#include <modules/camera_base.hpp>
|
||||||
#include <models/audio_listener.hpp>
|
#include <models/audio_listener.hpp>
|
||||||
|
|
||||||
@@ -24,18 +25,24 @@ class FloorManager
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FloorManager(int t_floorAmount);
|
FloorManager(int t_floorAmount, TextureRepository *t_texRepo);
|
||||||
~FloorManager();
|
~FloorManager();
|
||||||
Floor floors[144]; // Temp change it also in floors.cpp
|
Floor floors[144]; // Temp change it also in floors.cpp
|
||||||
u32 floorAmount;
|
u16 floorAmount;
|
||||||
void update(Player &t_player);
|
void update(Player &t_player);
|
||||||
void onAudioTick();
|
void onAudioTick();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
TextureRepository *texRepo;
|
||||||
u8 audioOffset, audioMode;
|
u8 audioOffset, audioMode;
|
||||||
u32 audioTick;
|
u32 audioTick;
|
||||||
|
float trick;
|
||||||
|
u8 isTimeForChangeTriggerColor, isTimeForChangeDefaultColor;
|
||||||
|
color_t trigColor, defaultColor;
|
||||||
|
u8 trickMode;
|
||||||
Point *spirals;
|
Point *spirals;
|
||||||
void calcSpiral(int X, int Y);
|
void calcSpiral(int X, int Y);
|
||||||
|
void doTheTrick();
|
||||||
void initFloors();
|
void initFloors();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ void LightManager::onAudioTick()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bulbs[0].intensity += 6;
|
bulbs[0].intensity += 9;
|
||||||
bulbs[1].intensity += 6;
|
bulbs[1].intensity += 9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "enemy.hpp"
|
||||||
|
#include "../utils.hpp"
|
||||||
|
|
||||||
|
#include <loaders/md2_loader.hpp>
|
||||||
|
#include <loaders/bmp_loader.hpp>
|
||||||
|
#include <modules/gif_sender.hpp>
|
||||||
|
#include <utils/debug.hpp>
|
||||||
|
#include <utils/math.hpp>
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Constructors/Destructors
|
||||||
|
// ----
|
||||||
|
|
||||||
|
Enemy::Enemy(TextureRepository *t_texRepo)
|
||||||
|
{
|
||||||
|
PRINT_LOG("Creating enemy object");
|
||||||
|
|
||||||
|
meshes = new Mesh[getMeshesCount()];
|
||||||
|
|
||||||
|
meshes[0].loadMD2("meshes/enemy/", "poss_head", 0.3F, false);
|
||||||
|
meshes[0].rotation.x = -1.566F;
|
||||||
|
meshes[0].rotation.z = 1.566F;
|
||||||
|
|
||||||
|
meshes[1].loadMD2("meshes/enemy/", "poss_body", 0.3F, false);
|
||||||
|
meshes[1].rotation.x = -1.566F;
|
||||||
|
meshes[1].rotation.z = 1.566F;
|
||||||
|
|
||||||
|
meshes[2].loadMD2("meshes/enemy/", "poss_weapon", 0.3F, false);
|
||||||
|
meshes[2].rotation.x = -1.566F;
|
||||||
|
meshes[2].rotation.z = 1.566F;
|
||||||
|
|
||||||
|
Vector3 initPos = Vector3(0.00F, 40.00F, 0.00F);
|
||||||
|
setPosition(initPos);
|
||||||
|
|
||||||
|
t_texRepo->addByMesh("meshes/enemy/", meshes[0], PNG);
|
||||||
|
t_texRepo->addByMesh("meshes/enemy/", meshes[1], PNG);
|
||||||
|
t_texRepo->addByMesh("meshes/enemy/", meshes[2], PNG);
|
||||||
|
|
||||||
|
meshes[0].playAnimation(1, 6);
|
||||||
|
meshes[1].playAnimation(1, 6);
|
||||||
|
meshes[2].playAnimation(1, 6);
|
||||||
|
|
||||||
|
isKilled = true;
|
||||||
|
|
||||||
|
PRINT_LOG("Enemy object created!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Enemy::~Enemy()
|
||||||
|
{
|
||||||
|
delete[] meshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Methods
|
||||||
|
// ----
|
||||||
|
|
||||||
|
void Enemy::setPosition(const Vector3 &t_vec)
|
||||||
|
{
|
||||||
|
position.set(t_vec);
|
||||||
|
for (u8 i = 0; i < getMeshesCount(); i++)
|
||||||
|
meshes[i].position.set(t_vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Enemy::setPosition(const float &t_y)
|
||||||
|
{
|
||||||
|
position.y = t_y;
|
||||||
|
for (u8 i = 0; i < getMeshesCount(); i++)
|
||||||
|
meshes[i].position.y = t_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by player class. */
|
||||||
|
void Enemy::kill(const Player &player)
|
||||||
|
{
|
||||||
|
isKilled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Enemy::update(const FloorManager &floorManager)
|
||||||
|
{
|
||||||
|
if (isKilled)
|
||||||
|
{
|
||||||
|
isKilled = false;
|
||||||
|
int randFloor = rand() % (floorManager.floorAmount + 1);
|
||||||
|
currentFloor = &floorManager.floors[randFloor];
|
||||||
|
setPosition(currentFloor->mesh.position);
|
||||||
|
}
|
||||||
|
updateGravity();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Enemy::updateGravity()
|
||||||
|
{
|
||||||
|
Utils::getMinMax(currentFloor->mesh, currFloorMin, currFloorMax);
|
||||||
|
setPosition(currFloorMax.y);
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ENEMY_
|
||||||
|
#define _ENEMY_
|
||||||
|
|
||||||
|
#include <tamtypes.h>
|
||||||
|
#include "../managers/floor_manager.hpp"
|
||||||
|
#include <modules/texture_repository.hpp>
|
||||||
|
|
||||||
|
/** Player 3D object class */
|
||||||
|
class Enemy
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
s16 indexOfCurrentFloor;
|
||||||
|
Enemy(TextureRepository *t_texRepo);
|
||||||
|
~Enemy();
|
||||||
|
|
||||||
|
inline Mesh *getMeshes() const { return meshes; }
|
||||||
|
inline u8 getMeshesCount() const { return 3; }
|
||||||
|
inline Vector3 getPosition() const { return position; }
|
||||||
|
void setPosition(const Vector3 &t_vec);
|
||||||
|
void setPosition(const float &t_y);
|
||||||
|
void kill(const Player &player);
|
||||||
|
void update(const FloorManager &t_floorManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** 0 - head, 1 - body, 2 - weapon */
|
||||||
|
Mesh *meshes;
|
||||||
|
const Floor *currentFloor;
|
||||||
|
Vector3 position, currFloorMin, currFloorMax;
|
||||||
|
u8 isKilled;
|
||||||
|
void updateGravity();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,7 +23,13 @@ const float FLOOR_ANIMATION_Y_MAX = 10.0F;
|
|||||||
// Constructors/Destructors
|
// Constructors/Destructors
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
Floor::Floor() {}
|
Floor::Floor()
|
||||||
|
{
|
||||||
|
animTimer = 0;
|
||||||
|
animDirection = 0;
|
||||||
|
initOffset = 0;
|
||||||
|
isByAudioTriggered = false;
|
||||||
|
}
|
||||||
|
|
||||||
Floor::~Floor() {}
|
Floor::~Floor() {}
|
||||||
|
|
||||||
@@ -31,11 +37,6 @@ Floor::~Floor() {}
|
|||||||
// Methods
|
// 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(const Mesh &mother, const Point &spiral, const u8 &initOffset)
|
void Floor::init(const Mesh &mother, const Point &spiral, const u8 &initOffset)
|
||||||
{
|
{
|
||||||
this->mesh.position.set(0.00F, -10.00F, 0.00F);
|
this->mesh.position.set(0.00F, -10.00F, 0.00F);
|
||||||
@@ -44,7 +45,6 @@ void Floor::init(const Mesh &mother, const Point &spiral, const u8 &initOffset)
|
|||||||
this->animTimer = rand() % FLOOR_ANIMATION_LENGTH;
|
this->animTimer = rand() % FLOOR_ANIMATION_LENGTH;
|
||||||
this->mesh.shouldBeLighted = true;
|
this->mesh.shouldBeLighted = true;
|
||||||
this->mesh.shouldBeFrustumCulled = true;
|
this->mesh.shouldBeFrustumCulled = true;
|
||||||
this->animDirection = 0;
|
|
||||||
this->mesh.position.x = spiral.x * 80.0F;
|
this->mesh.position.x = spiral.x * 80.0F;
|
||||||
this->mesh.position.z = spiral.y * 80.0F;
|
this->mesh.position.z = spiral.y * 80.0F;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Floor
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
u16 animTimer;
|
u16 animTimer;
|
||||||
u8 animDirection, initOffset, isByAudioTriggered;
|
s16 animDirection, initOffset, isByAudioTriggered;
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
|
|
||||||
Floor();
|
Floor();
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
#include "../utils.hpp"
|
||||||
|
|
||||||
#include <loaders/obj_loader.hpp>
|
#include <loaders/md2_loader.hpp>
|
||||||
#include <loaders/bmp_loader.hpp>
|
#include <loaders/bmp_loader.hpp>
|
||||||
#include <modules/gif_sender.hpp>
|
#include <modules/gif_sender.hpp>
|
||||||
#include <utils/debug.hpp>
|
#include <utils/debug.hpp>
|
||||||
@@ -20,20 +21,38 @@
|
|||||||
// Constructors/Destructors
|
// Constructors/Destructors
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
Player::Player()
|
Player::Player(Audio *t_audio, TextureRepository *t_texRepo)
|
||||||
{
|
{
|
||||||
PRINT_LOG("Creating player object");
|
PRINT_LOG("Creating player object");
|
||||||
this->gravity = 0.1F;
|
texRepo = t_texRepo;
|
||||||
this->lift = -1.0F;
|
audio = t_audio;
|
||||||
|
gravity = 0.1F;
|
||||||
|
lift = -1.0F;
|
||||||
|
jumpCounter = 0;
|
||||||
|
speed = 1.0F;
|
||||||
|
killedEnemies = 0;
|
||||||
|
isWalking = false;
|
||||||
|
isFighting = false;
|
||||||
|
isWalkingAnimationSet = false;
|
||||||
|
isJumpingAnimationSet = false;
|
||||||
|
isFightingAnimationSet = false;
|
||||||
|
|
||||||
this->mesh.loadMD2("warrior/", "warrior", 0.2F, true);
|
mesh.loadMD2("meshes/player/", "warrior", 0.2F, true);
|
||||||
this->mesh.position.set(0.00F, 20.00F, 0.00F);
|
mesh.position.set(0.00F, 40.00F, 0.00F);
|
||||||
this->mesh.rotation.x = -1.6F;
|
mesh.rotation.x = -1.566F;
|
||||||
this->mesh.shouldBeBackfaceCulled = false;
|
mesh.rotation.z = 1.566F;
|
||||||
this->mesh.shouldBeFrustumCulled = false;
|
mesh.shouldBeBackfaceCulled = false;
|
||||||
|
mesh.shouldBeFrustumCulled = false;
|
||||||
|
mesh.setAnimSpeed(0.17F);
|
||||||
|
mesh.playAnimation(0, 0);
|
||||||
|
|
||||||
|
texRepo->addByMesh("meshes/player/", mesh, BMP);
|
||||||
|
|
||||||
|
walkAdpcm = audio->loadADPCM("sounds/walk.adpcm");
|
||||||
|
jumpAdpcm = audio->loadADPCM("sounds/jump.adpcm");
|
||||||
|
boomAdpcm = audio->loadADPCM("sounds/boom.adpcm");
|
||||||
|
audio->setADPCMVolume(70, 0);
|
||||||
|
|
||||||
this->mesh.setAnimSpeed(0.2F);
|
|
||||||
this->mesh.playAnimation(0, 24);
|
|
||||||
PRINT_LOG("Player object created!");
|
PRINT_LOG("Player object created!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,139 +64,167 @@ Player::~Player()
|
|||||||
// Methods
|
// Methods
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
/** Update player position and control gravity */
|
void Player::update(const Pad &t_pad, const Camera &t_camera, const FloorManager &floorManager, Enemy &enemy)
|
||||||
void Player::update(Pad &pad, Camera &camera, FloorManager &floorManager)
|
|
||||||
{
|
{
|
||||||
this->updatePosition(pad, camera, floorManager);
|
Vector3 *nextPos = getNextPosition(t_pad, t_camera);
|
||||||
this->updateGravity(pad, floorManager);
|
FloorsCheck *floorsCheck = checkFloors(floorManager, *nextPos);
|
||||||
if (mesh.position.y < -60.0F)
|
if (floorsCheck->currentFloor != NULL)
|
||||||
|
indexOfCurrentFloor = floorsCheck->currentFloor->initOffset;
|
||||||
|
updatePosition(t_pad, t_camera, floorManager, *floorsCheck, *nextPos, enemy);
|
||||||
|
updateGravity(floorsCheck);
|
||||||
|
delete floorsCheck;
|
||||||
|
delete nextPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 *Player::getNextPosition(const Pad &t_pad, const Camera &t_camera)
|
||||||
|
{
|
||||||
|
Vector3 *result = new Vector3(mesh.position);
|
||||||
|
Vector3 normalizedCamera = Vector3(t_camera.unitCirclePosition);
|
||||||
|
normalizedCamera.normalize();
|
||||||
|
normalizedCamera *= speed;
|
||||||
|
if (t_pad.lJoyV <= 100)
|
||||||
{
|
{
|
||||||
mesh.position.y = 60.0F;
|
result->x += -normalizedCamera.x;
|
||||||
velocity = 0;
|
result->z += -normalizedCamera.z;
|
||||||
|
}
|
||||||
|
else if (t_pad.lJoyV >= 200)
|
||||||
|
{
|
||||||
|
result->x += normalizedCamera.x;
|
||||||
|
result->z += normalizedCamera.z;
|
||||||
|
}
|
||||||
|
if (t_pad.lJoyH <= 100)
|
||||||
|
{
|
||||||
|
result->x += -normalizedCamera.z;
|
||||||
|
result->z += normalizedCamera.x;
|
||||||
|
}
|
||||||
|
else if (t_pad.lJoyH >= 200)
|
||||||
|
{
|
||||||
|
result->x += normalizedCamera.z;
|
||||||
|
result->z += -normalizedCamera.x;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::updatePosition(const Pad &t_pad, const Camera &t_camera, const FloorManager &t_floorManager, const FloorsCheck &t_floorsCheck, const Vector3 &t_nextPos, Enemy &enemy)
|
||||||
|
{
|
||||||
|
if (t_pad.rJoyH >= 200)
|
||||||
|
mesh.rotation.z += 0.08;
|
||||||
|
else if (t_pad.rJoyH <= 100)
|
||||||
|
mesh.rotation.z -= 0.08;
|
||||||
|
|
||||||
|
isWalking = mesh.position.x != t_nextPos.x || mesh.position.z != t_nextPos.z;
|
||||||
|
isFighting = isFighting || t_pad.isCircleClicked;
|
||||||
|
|
||||||
|
if (isFighting)
|
||||||
|
{
|
||||||
|
if (!isFightingAnimationSet)
|
||||||
|
{
|
||||||
|
isFightingAnimationSet = true;
|
||||||
|
mesh.playAnimation(8, 19, 0);
|
||||||
|
fightTimer.prime();
|
||||||
|
}
|
||||||
|
if (fightTimer.getTimeDelta() > 25000)
|
||||||
|
{ // end of fighting
|
||||||
|
float distance = getPosition().distanceTo(enemy.getPosition());
|
||||||
|
if (16.0F > distance)
|
||||||
|
{
|
||||||
|
enemy.kill(*this);
|
||||||
|
audio->playADPCM(boomAdpcm);
|
||||||
|
speed += .5F;
|
||||||
|
killedEnemies++;
|
||||||
|
}
|
||||||
|
isFightingAnimationSet = false;
|
||||||
|
isFighting = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isWalking)
|
||||||
|
{
|
||||||
|
if (!isWalkingAnimationSet)
|
||||||
|
{
|
||||||
|
isWalkingAnimationSet = true;
|
||||||
|
this->mesh.playAnimation(1, 8);
|
||||||
|
}
|
||||||
|
if (walkTimer.getTimeDelta() > 8000)
|
||||||
|
{
|
||||||
|
walkTimer.prime();
|
||||||
|
audio->playADPCM(walkAdpcm, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isWalkingAnimationSet = false;
|
||||||
|
mesh.playAnimation(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_floorsCheck.willCollideFloor == NULL && !isFighting)
|
||||||
|
{
|
||||||
|
mesh.position.x = t_nextPos.x;
|
||||||
|
mesh.position.z = t_nextPos.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_pad.isCrossClicked == 1)
|
||||||
|
{
|
||||||
|
velocity = lift;
|
||||||
|
audio->playADPCM(jumpAdpcm);
|
||||||
|
jumpCounter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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)
|
* Do not call this.
|
||||||
{
|
|
||||||
|
|
||||||
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 (u32 i = 0; i < floorManager.floorAmount; i++)
|
|
||||||
{
|
|
||||||
getMinMax(&floorManager.floors[i].mesh, &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
|
* This is called by Floor::animate() on player's floor move in Y direction
|
||||||
*/
|
*/
|
||||||
void Player::onBeforePlayerFloorMove(Floor *floor, float &newY)
|
void Player::onBeforePlayerFloorMove(Floor *t_floor, float &t_newY)
|
||||||
{
|
{
|
||||||
if (floor->animDirection == 0 && newY > 0.0F)
|
if (t_floor->animDirection == 0 && t_newY > 0.0F)
|
||||||
this->mesh.position.y += newY * 1.05F;
|
this->mesh.position.y += t_newY * 1.05F;
|
||||||
else if ((floor->animDirection == 1 && -newY < 0.0F))
|
else if ((t_floor->animDirection == 1 && -t_newY < 0.0F))
|
||||||
this->mesh.position.y -= -newY * 1.05F;
|
this->mesh.position.y -= -t_newY * 1.05F;
|
||||||
}
|
|
||||||
|
|
||||||
/** Calculates minimum and maximum X, Y, Z of mesh vertices + current position */
|
|
||||||
void Player::getMinMax(Mesh *t_mesh, Vector3 *t_min, Vector3 *t_max)
|
|
||||||
{
|
|
||||||
Vector3 calc = Vector3();
|
|
||||||
u8 isInitialized = 0;
|
|
||||||
Vector3 *boundingBox = t_mesh->getCurrentBoundingBox();
|
|
||||||
for (u32 i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
calc.set(
|
|
||||||
boundingBox[i].x + t_mesh->position.x,
|
|
||||||
boundingBox[i].y + t_mesh->position.y,
|
|
||||||
boundingBox[i].z + t_mesh->position.z);
|
|
||||||
if (isInitialized == 0)
|
|
||||||
{
|
|
||||||
isInitialized = 1;
|
|
||||||
t_min->set(calc);
|
|
||||||
t_max->set(calc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t_min->x > calc.x)
|
|
||||||
t_min->x = calc.x;
|
|
||||||
if (calc.x > t_max->x)
|
|
||||||
t_max->x = calc.x;
|
|
||||||
|
|
||||||
if (t_min->y > calc.y)
|
|
||||||
t_min->y = calc.y;
|
|
||||||
if (calc.y > t_max->y)
|
|
||||||
t_max->y = calc.y;
|
|
||||||
|
|
||||||
if (t_min->z > calc.z)
|
|
||||||
t_min->z = calc.z;
|
|
||||||
if (calc.z > t_max->z)
|
|
||||||
t_max->z = calc.z;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update player position by gravity and update index of current floor */
|
/** Update player position by gravity and update index of current floor */
|
||||||
void Player::updateGravity(Pad &pad, FloorManager &floorManager)
|
void Player::updateGravity(FloorsCheck *t_floorsCheck)
|
||||||
{
|
{
|
||||||
Vector3 min = Vector3();
|
|
||||||
Vector3 max = Vector3();
|
|
||||||
|
|
||||||
if (pad.isCrossClicked == 1)
|
|
||||||
this->velocity = this->lift;
|
|
||||||
|
|
||||||
this->isOnFloor = 0;
|
|
||||||
for (u32 i = 0; i < floorManager.floorAmount; i++)
|
|
||||||
{
|
|
||||||
getMinMax(&floorManager.floors[i].mesh, &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->velocity += this->gravity;
|
||||||
this->mesh.position.y -= this->velocity;
|
this->mesh.position.y -= this->velocity;
|
||||||
|
u8 isOnFloor = t_floorsCheck->currentFloor != NULL && mesh.position.y < t_floorsCheck->currFloorMax.y;
|
||||||
|
|
||||||
if (this->mesh.position.y >= 60.0F)
|
if (this->mesh.position.y >= 60.0F || mesh.position.y < -60.0F)
|
||||||
{
|
{
|
||||||
this->mesh.position.y = 60.0F;
|
this->mesh.position.y = 60.0F;
|
||||||
this->velocity = 0;
|
this->velocity = 0;
|
||||||
}
|
}
|
||||||
else if ((this->mesh.position.y) < max.y && this->isOnFloor)
|
else if (isOnFloor)
|
||||||
{
|
{
|
||||||
this->mesh.position.y = max.y;
|
this->mesh.position.y = t_floorsCheck->currFloorMax.y;
|
||||||
this->velocity = 0;
|
this->velocity = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FloorsCheck *Player::checkFloors(const FloorManager &t_floorManager, const Vector3 &t_nextPos)
|
||||||
|
{
|
||||||
|
FloorsCheck *result = new FloorsCheck;
|
||||||
|
result->currentFloor = NULL;
|
||||||
|
result->willCollideFloor = NULL;
|
||||||
|
Vector3 min = Vector3();
|
||||||
|
Vector3 max = Vector3();
|
||||||
|
for (u32 i = 0; i < t_floorManager.floorAmount; i++)
|
||||||
|
{
|
||||||
|
Utils::getMinMax(t_floorManager.floors[i].mesh, min, max);
|
||||||
|
if (result->currentFloor == NULL && this->mesh.position.isOnSquare(min, max))
|
||||||
|
{
|
||||||
|
result->currentFloor = &t_floorManager.floors[i];
|
||||||
|
result->currFloorMin.set(min);
|
||||||
|
result->currFloorMax.set(max);
|
||||||
|
}
|
||||||
|
if (result->willCollideFloor == NULL && t_nextPos.collidesSquare(min, max))
|
||||||
|
{
|
||||||
|
result->willCollideFloor = &t_floorManager.floors[i];
|
||||||
|
result->willCollideFloorMin.set(min);
|
||||||
|
result->willCollideFloorMax.set(max);
|
||||||
|
}
|
||||||
|
if (result->currentFloor != NULL && result->willCollideFloor != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,8 +13,17 @@
|
|||||||
|
|
||||||
#include "../managers/floor_manager.hpp"
|
#include "../managers/floor_manager.hpp"
|
||||||
#include "../camera.hpp"
|
#include "../camera.hpp"
|
||||||
|
#include "./enemy.hpp"
|
||||||
#include <modules/pad.hpp>
|
#include <modules/pad.hpp>
|
||||||
|
#include <modules/timer.hpp>
|
||||||
#include <tamtypes.h>
|
#include <tamtypes.h>
|
||||||
|
#include <modules/audio.hpp>
|
||||||
|
|
||||||
|
struct FloorsCheck
|
||||||
|
{
|
||||||
|
const Floor *currentFloor, *willCollideFloor;
|
||||||
|
Vector3 currFloorMin, willCollideFloorMin, currFloorMax, willCollideFloorMax;
|
||||||
|
};
|
||||||
|
|
||||||
/** Player 3D object class */
|
/** Player 3D object class */
|
||||||
class Player
|
class Player
|
||||||
@@ -22,19 +31,31 @@ class Player
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
float gravity, velocity, lift;
|
float gravity, velocity, lift;
|
||||||
u8 isOnFloor, isCollideFloor, indexOfCurrentFloor;
|
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
Player();
|
s16 indexOfCurrentFloor;
|
||||||
|
Player(Audio *t_audio, TextureRepository *t_texRepo);
|
||||||
~Player();
|
~Player();
|
||||||
|
|
||||||
void update(Pad &pad, Camera &camera, FloorManager &floorManager);
|
void update(const Pad &t_pad, const Camera &t_camera, const FloorManager &t_floorManager, Enemy &enemy);
|
||||||
void onBeforePlayerFloorMove(Floor *floor, float &newY);
|
void onBeforePlayerFloorMove(Floor *t_floor, float &t_newY);
|
||||||
|
const inline u32 &getJumpCount() const { return jumpCounter; }
|
||||||
|
const inline u32 &getKilledEnemiesCount() const { return killedEnemies; }
|
||||||
|
inline const Vector3 &getPosition() const { return mesh.position; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector3 playerNextPosition;
|
TextureRepository *texRepo;
|
||||||
void getMinMax(Mesh *t_mesh, Vector3 *t_min, Vector3 *t_max);
|
u32 jumpCounter, killedEnemies;
|
||||||
void updatePosition(Pad &pad, Camera &camera, FloorManager &floorManager);
|
Vector3 *getNextPosition(const Pad &t_pad, const Camera &t_camera);
|
||||||
void updateGravity(Pad &pad, FloorManager &floorManager);
|
FloorsCheck *checkFloors(const FloorManager &t_floorManager, const Vector3 &t_nextPos);
|
||||||
|
u8 isWalkingAnimationSet, isJumpingAnimationSet, isFightingAnimationSet;
|
||||||
|
u8 isFighting, isWalking;
|
||||||
|
Audio *audio;
|
||||||
|
Timer walkTimer, fightTimer;
|
||||||
|
audsrv_adpcm_t *walkAdpcm, *jumpAdpcm, *boomAdpcm;
|
||||||
|
float speed;
|
||||||
|
void getMinMax(const Mesh &t_mesh, Vector3 &t_min, Vector3 &t_max);
|
||||||
|
void updatePosition(const Pad &t_pad, const Camera &t_camera, const FloorManager &t_floorManager, const FloorsCheck &t_floorsCheck, const Vector3 &nextPos, Enemy &enemy);
|
||||||
|
void updateGravity(FloorsCheck *t_floorsCheck);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ui.hpp"
|
||||||
|
|
||||||
|
#include <utils/debug.hpp>
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Constructors/Destructors
|
||||||
|
// ----
|
||||||
|
|
||||||
|
Ui::Ui(TextureRepository *t_texRepo)
|
||||||
|
{
|
||||||
|
PRINT_LOG("Initializing ui");
|
||||||
|
|
||||||
|
isTask1Done = false;
|
||||||
|
isTask2Done = false;
|
||||||
|
|
||||||
|
info.size.set(128.0F, 32.0F);
|
||||||
|
info.position.set(500.0F, 430.0F);
|
||||||
|
|
||||||
|
reward.size.set(128.0F, 128.0F);
|
||||||
|
reward.position.set(500.0F, 280.0F);
|
||||||
|
reward.flipVertically(true);
|
||||||
|
|
||||||
|
task1.size.set(128.0F, 32.0F);
|
||||||
|
task1.position.set(500.0F, 10.0F);
|
||||||
|
|
||||||
|
task2.size.set(128.0F, 32.0F);
|
||||||
|
task2.position.set(500.0F, 50.0F);
|
||||||
|
|
||||||
|
task1Checkbox.size.set(32.0F, 32.0F);
|
||||||
|
task1Checkbox.position.set(460.0F, 10.0F);
|
||||||
|
|
||||||
|
task2Checkbox.size.set(32.0F, 32.0F);
|
||||||
|
task2Checkbox.position.set(460.0F, 50.0F);
|
||||||
|
|
||||||
|
t_texRepo->add("ui/", "reward", BMP)->addLink(reward.getId());
|
||||||
|
t_texRepo->add("ui/", "info-text", PNG)->addLink(info.getId());
|
||||||
|
t_texRepo->add("ui/", "check1-text", PNG)->addLink(task1.getId());
|
||||||
|
t_texRepo->add("ui/", "check2-text", PNG)->addLink(task2.getId());
|
||||||
|
grayCheckboxTex = t_texRepo->add("ui/", "gray-checkmark", PNG);
|
||||||
|
blueCheckboxTex = t_texRepo->add("ui/", "blue-checkmark", PNG);
|
||||||
|
|
||||||
|
grayCheckboxTex->addLink(task1Checkbox.getId());
|
||||||
|
grayCheckboxTex->addLink(task2Checkbox.getId());
|
||||||
|
|
||||||
|
PRINT_LOG("Ui initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::~Ui() {}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Methods
|
||||||
|
// ----
|
||||||
|
|
||||||
|
void Ui::update(const Player &player)
|
||||||
|
{
|
||||||
|
if (!isTask1Done && player.getJumpCount() >= 10)
|
||||||
|
{
|
||||||
|
isTask1Done = true;
|
||||||
|
grayCheckboxTex->removeLinkBySprite(task1Checkbox.getId());
|
||||||
|
blueCheckboxTex->addLink(task1Checkbox.getId());
|
||||||
|
}
|
||||||
|
if (!isTask2Done && player.getKilledEnemiesCount() >= 10)
|
||||||
|
{
|
||||||
|
isTask2Done = true;
|
||||||
|
grayCheckboxTex->removeLinkBySprite(task2Checkbox.getId());
|
||||||
|
blueCheckboxTex->addLink(task2Checkbox.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ui::render(Renderer *t_renderer)
|
||||||
|
{
|
||||||
|
if (isTask1Done && isTask2Done)
|
||||||
|
t_renderer->draw(reward);
|
||||||
|
t_renderer->draw(info);
|
||||||
|
t_renderer->draw(task1);
|
||||||
|
t_renderer->draw(task2);
|
||||||
|
t_renderer->draw(task1Checkbox);
|
||||||
|
t_renderer->draw(task2Checkbox);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UI_
|
||||||
|
#define _UI_
|
||||||
|
|
||||||
|
#include <modules/texture_repository.hpp>
|
||||||
|
#include <modules/renderer.hpp>
|
||||||
|
#include "objects/player.hpp"
|
||||||
|
#include <tamtypes.h>
|
||||||
|
|
||||||
|
class Ui
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Ui(TextureRepository *t_texRepo);
|
||||||
|
~Ui();
|
||||||
|
|
||||||
|
void update(const Player &player);
|
||||||
|
void render(Renderer *t_renderer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
u8 isTask1Done, isTask2Done;
|
||||||
|
Sprite task1, task2, task1Checkbox, task2Checkbox, info, reward;
|
||||||
|
Texture *grayCheckboxTex, *blueCheckboxTex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -32,3 +32,39 @@ float Utils::expoEaseInOut(float t, float b, float c, float d)
|
|||||||
|
|
||||||
return c / 2 * (-powf(2, -10 * --t) + 2) + b;
|
return c / 2 * (-powf(2, -10 * --t) + 2) + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Calculates minimum and maximum X, Y, Z of mesh vertices + current position */
|
||||||
|
void Utils::getMinMax(const Mesh &t_mesh, Vector3 &t_min, Vector3 &t_max)
|
||||||
|
{
|
||||||
|
Vector3 calc = Vector3();
|
||||||
|
u8 isInitialized = 0;
|
||||||
|
Vector3 *boundingBox = t_mesh.getCurrentBoundingBox();
|
||||||
|
for (u32 i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
calc.set(
|
||||||
|
boundingBox[i].x + t_mesh.position.x,
|
||||||
|
boundingBox[i].y + t_mesh.position.y,
|
||||||
|
boundingBox[i].z + t_mesh.position.z);
|
||||||
|
if (isInitialized == 0)
|
||||||
|
{
|
||||||
|
isInitialized = 1;
|
||||||
|
t_min.set(calc);
|
||||||
|
t_max.set(calc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_min.x > calc.x)
|
||||||
|
t_min.x = calc.x;
|
||||||
|
if (calc.x > t_max.x)
|
||||||
|
t_max.x = calc.x;
|
||||||
|
|
||||||
|
if (t_min.y > calc.y)
|
||||||
|
t_min.y = calc.y;
|
||||||
|
if (calc.y > t_max.y)
|
||||||
|
t_max.y = calc.y;
|
||||||
|
|
||||||
|
if (t_min.z > calc.z)
|
||||||
|
t_min.z = calc.z;
|
||||||
|
if (calc.z > t_max.z)
|
||||||
|
t_max.z = calc.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,12 +12,15 @@
|
|||||||
#define _TYRA_UTILS_
|
#define _TYRA_UTILS_
|
||||||
|
|
||||||
#include <tamtypes.h>
|
#include <tamtypes.h>
|
||||||
|
#include <models/mesh.hpp>
|
||||||
|
#include <models/math/vector3.hpp>
|
||||||
|
|
||||||
class Utils
|
class Utils
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static float expoEaseInOut(float t, float b, float c, float d);
|
static float expoEaseInOut(float t, float b, float c, float d);
|
||||||
|
static void getMinMax(const Mesh &t_mesh, Vector3 &t_min, Vector3 &t_max);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user