Finished Tiling System

* Finished working on tiling
* Changed how sprite layers work. Sprite layers are now not confined to the limits of the actual canvas but instead will decide where to draw each sprite based on the canvas offset and the sprites location
This commit is contained in:
n00b
2024-10-21 18:35:13 -04:00
parent 78c897068b
commit 9cac24402e
22 changed files with 1009 additions and 2658 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,7 @@
#include <box2d/box2d.h>
#include "rc_sprite2D.h"
#include "rc_spritelib.h"
#include "rc_tilelib.h"
#include <irrtheora.h>
using namespace irr;
@@ -1019,9 +1020,10 @@ int rc_canvasOpen3D(int vx, int vy, int vw, int vh, int mode)
return rc_canvasOpen(vw, vh, vx, vy, vw, vh, mode, RC_CANVAS_TYPE_3D);
}
int rc_canvasOpenSpriteLayer(int w, int h, int vx, int vy, int vw, int vh)
int rc_canvasOpenSpriteLayer(int vx, int vy, int vw, int vh)
{
return rc_canvasOpen(w, h, vx, vy, vw, vh, 1, RC_CANVAS_TYPE_SPRITE);
//sprite layers are basically infinite since you are just placing objects in the world
return rc_canvasOpen(vw, vh, vx, vy, vw, vh, 1, RC_CANVAS_TYPE_SPRITE);
}
void rc_setCanvasPhysics2D(int canvas_id, bool flag)
@@ -2998,6 +3000,28 @@ int rc_canvasClip(int x, int y, int w, int h)
void rc_preUpdate()
{
//3D World Update
rc_physics3D.DeltaTime = device->getTimer()->getTime() - rc_physics3D.TimeStamp;
rc_physics3D.TimeStamp = device->getTimer()->getTime();
rc_physics3D.world->stepSimulation(rc_physics3D.DeltaTime*0.001f, rc_physics3D.maxSubSteps, rc_physics3D.fixedTimeStep);
for(int i = 0; i < rc_canvas.size(); i++)
{
if(rc_canvas[i].type != RC_CANVAS_TYPE_SPRITE)
continue;
float step = rc_canvas[i].physics2D.timeStep;
int32 velocityIterations = rc_canvas[i].physics2D.velocityIterations;
int32 positionIterations = rc_canvas[i].physics2D.positionIterations;
if(rc_canvas[i].physics2D.enabled)
rc_canvas[i].physics2D.world->Step(step, velocityIterations, positionIterations);
}
hasPreUpdated = true;
}
bool rc_update()
{
@@ -3348,23 +3372,34 @@ bool rc_update()
irr::core::vector2d<irr::f32> screenSize( (irr::f32) rc_canvas[0].dimension.Width, (irr::f32) rc_canvas[0].dimension.Height );
double frame_current_time = ((double)SDL_GetTicks())/1000.0;
Uint32 current_time_ms = SDL_GetTicks();
double frame_current_time = ((double)current_time_ms)/1000.0;
for(int i = 0; i < rc_transition_actor.size();)
{
if((frame_current_time - rc_actor[i].transition_start_time) >= rc_actor[i].transition_time)
int t_actor = rc_transition_actor[i];
if((frame_current_time - rc_actor[t_actor].transition_start_time) >= rc_actor[t_actor].transition_time)
{
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[i].mesh_node;
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[t_actor].mesh_node;
node->setTransitionTime(0);
node->setJointMode(irr::scene::EJUOR_NONE);
rc_actor[i].transition = false;
rc_actor[i].transition_time = 0;
rc_actor[i].transition_start_time = 0;
rc_transition_actor.erase(i);
rc_actor[t_actor].transition = false;
rc_actor[t_actor].transition_time = 0;
rc_actor[t_actor].transition_start_time = 0;
rc_transition_actor.erase(t_actor);
rc_actor[t_actor].animation[0].start_frame = (int)rc_actor[t_actor].transition_frame;
rc_actor[t_actor].animation[0].end_frame = (int)rc_actor[t_actor].transition_frame;
rc_actor[t_actor].animation[0].fps = 0;
rc_actor[t_actor].current_animation_loop = 0;
rc_actor[t_actor].isPlaying = true;
rc_actor[t_actor].current_animation = 0;
}
else
{
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[i].mesh_node;
//std::cout << "Animate dammit" << std::endl;
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[t_actor].mesh_node;
node->animateJoints();
i++;
}
@@ -3373,9 +3408,12 @@ bool rc_update()
VideoDriver->beginScene(true, true);
rc_physics3D.DeltaTime = device->getTimer()->getTime() - rc_physics3D.TimeStamp;
rc_physics3D.TimeStamp = device->getTimer()->getTime();
rc_physics3D.world->stepSimulation(rc_physics3D.DeltaTime*0.001f, rc_physics3D.maxSubSteps, rc_physics3D.fixedTimeStep);
if(!hasPreUpdated)
{
rc_physics3D.DeltaTime = device->getTimer()->getTime() - rc_physics3D.TimeStamp;
rc_physics3D.TimeStamp = device->getTimer()->getTime();
rc_physics3D.world->stepSimulation(rc_physics3D.DeltaTime*0.001f, rc_physics3D.maxSubSteps, rc_physics3D.fixedTimeStep);
}
for(int i = 0; i < rc_canvas.size(); i++)
{
@@ -3422,7 +3460,11 @@ bool rc_update()
//std::cout << "draw canvas[" << canvas_id << "]" << std::endl;
if(rc_canvas[canvas_id].type == RC_CANVAS_TYPE_SPRITE)
{
src = irr::core::rect<s32>( irr::core::vector2d<s32>(0, 0), rc_canvas[canvas_id].viewport.dimension); //sprite layers will just offset the sprites in drawSprites()
drawSprites(canvas_id);
}
draw2DImage2(VideoDriver, rc_canvas[canvas_id].texture, src, dest, irr::core::position2d<irr::s32>(0, 0), 0, true, color, screenSize);
@@ -3446,6 +3488,8 @@ bool rc_update()
rc_setActiveCanvas(rc_active_canvas);
}
hasPreUpdated = false; //Will be set to true if PreUpdate() is called
#ifdef RC_WEB
emscripten_sleep(0);
#else

View File

@@ -562,7 +562,7 @@ bool rc_getActorCollision(int actor1, int actor2)
//add mesh actor to scene
int rc_createMeshActor(int mesh_id)
int rc_createAnimatedActor(int mesh_id)
{
if(mesh_id < 0 || mesh_id >= rc_mesh.size())
return -1;
@@ -604,6 +604,23 @@ int rc_createMeshActor(int mesh_id)
rc_actor[actor_id] = actor;
}
//animation
rc_actor_animation_obj animation;
animation.start_frame = 0;
animation.end_frame = 0;
animation.fps = 60.0;
animation.frame_start_time = SDL_GetTicks();
animation.frame_swap_time = 1000/60;
rc_actor[actor_id].animation.push_back(animation);
rc_animEndCallBack* anim_callback = new rc_animEndCallBack();
anim_callback->ref_actor = &rc_actor[actor_id];
anim_callback->OnAnimationEnd(node);
node->setAnimationEndCallback(anim_callback);
node->setLoopMode(false);
node->setFrameLoop(0, 0);
anim_callback->drop();
//Actor RigidBody
rc_actor[actor_id].physics.shape_type = RC_NODE_SHAPE_TYPE_BOX;
rc_actor[actor_id].physics.rigid_body = NULL;
@@ -616,7 +633,7 @@ int rc_createMeshActor(int mesh_id)
//add mesh actor to scene
int rc_createMeshOctreeActor(int mesh_id)
int rc_createOctreeActor(int mesh_id)
{
if(mesh_id < 0 || mesh_id >= rc_mesh.size())
return -1;
@@ -4952,21 +4969,97 @@ void rc_setWorld3DTimeStep(double ts)
//set actor animation [TODO]
void rc_setActorAnimation(int actor, int start_frame, int end_frame)
int rc_createActorAnimation(int actor, int start_frame, int end_frame, double speed)
{
if(actor < 0 || actor >= rc_actor.size())
return -1;
rc_actor_animation_obj animation;
animation.active = true;
animation.start_frame = start_frame;
animation.end_frame = end_frame;
animation.fps = speed;
animation.frame_swap_time = 1000/speed;
int animation_id = rc_actor[actor].animation.size();
if(rc_actor[actor].deleted_animation.size() > 0)
{
animation_id = rc_actor[actor].deleted_animation[0];
rc_actor[actor].deleted_animation.erase(0);
rc_actor[actor].animation[animation_id] = animation;
}
else
rc_actor[actor].animation.push_back(animation);
return animation_id;
}
void rc_deleteActorAnimation(int actor, int animation)
{
if(actor < 0 || actor >= rc_actor.size())
return;
if(animation < 0 || animation >= rc_actor[actor].animation.size())
return;
if(!rc_actor[actor].animation[animation].active)
return;
rc_actor[actor].animation[animation].active = false;
rc_actor[actor].deleted_animation.push_back(animation);
}
void rc_setActorAnimation(int actor, int animation, int num_loops)
{
if(actor < 0 || actor >= rc_actor.size())
return;
if(animation < 0 || animation >= rc_actor[actor].animation.size())
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
int start_frame = rc_actor[actor].animation[animation].start_frame;
int end_frame = rc_actor[actor].animation[animation].end_frame;
rc_actor[actor].current_animation = animation;
rc_actor[actor].current_animation_loop = 0;
rc_actor[actor].num_animation_loops = num_loops;
rc_actor[actor].isPlaying = true;
node->setCurrentFrame(start_frame);
node->setFrameLoop((irr::s32)start_frame, (irr::s32)end_frame );
node->setAnimationSpeed(rc_actor[actor].animation[animation].fps);
break;
}
}
void rc_setActorMD2Animation(int actor, int md2_animation)
int rc_getActorCurrentAnimation(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return -1;
return rc_actor[actor].current_animation;
}
int rc_numActorAnimationLoops(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return -1;
return rc_actor[actor].num_animation_loops;
}
bool rc_actorAnimationIsPlaying(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return -1;
return rc_actor[actor].isPlaying;
}
void rc_setActorMD2Animation(int actor, int md2_animation, int num_loops)
{
if(actor < 0 || actor >= rc_actor.size())
return;
@@ -4976,11 +5069,21 @@ void rc_setActorMD2Animation(int actor, int md2_animation)
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setMD2Animation( (irr::scene::EMD2_ANIMATION_TYPE) md2_animation );
//int start_frame = node->getStartFrame();
//int end_frame = node->getEndFrame();
rc_actor[actor].current_animation = RC_ANIMATION_MD2;
rc_actor[actor].current_animation_loop = 0;
rc_actor[actor].num_animation_loops = num_loops;
rc_actor[actor].isPlaying = true;
//node->setCurrentFrame(start_frame);
//node->setFrameLoop((irr::s32)start_frame, (irr::s32)end_frame ); //setMD2Animation() does this for me
node->setAnimationSpeed(node->getMesh()->getAnimationSpeed());
break;
}
}
void rc_setActorMD2AnimationByName(int actor, std::string animation_name)
void rc_setActorMD2AnimationByName(int actor, std::string animation_name, int num_loops)
{
if(actor < 0 || actor >= rc_actor.size())
return;
@@ -4990,41 +5093,71 @@ void rc_setActorMD2AnimationByName(int actor, std::string animation_name)
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setMD2Animation( animation_name.c_str() );
//int start_frame = node->getStartFrame();
//int end_frame = node->getEndFrame();
rc_actor[actor].current_animation = RC_ANIMATION_MD2;
rc_actor[actor].current_animation_loop = 0;
rc_actor[actor].num_animation_loops = num_loops;
rc_actor[actor].isPlaying = true;
//node->setCurrentFrame(start_frame);
//node->setFrameLoop((irr::s32)start_frame, (irr::s32)end_frame ); //setMD2Animation() does this for me
node->setAnimationSpeed(node->getMesh()->getAnimationSpeed());
break;
}
}
int rc_getActorStartFrame(int actor)
int rc_getActorAnimationStartFrame(int actor, int animation)
{
if(actor < 0 || actor >= rc_actor.size())
return 0;
if(animation < 0 || animation >= rc_actor[actor].animation.size())
return 0;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
return node->getStartFrame();
if(rc_actor[actor].current_animation == animation)
{
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
return node->getStartFrame();
}
else
{
return rc_actor[actor].animation[animation].start_frame;
}
}
return 0;
}
int rc_getActorEndFrame(int actor)
int rc_getActorAnimationEndFrame(int actor, int animation)
{
if(actor < 0 || actor >= rc_actor.size())
return 0;
if(animation < 0 || animation >= rc_actor[actor].animation.size())
return 0;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
return node->getEndFrame();
if(rc_actor[actor].current_animation == animation)
{
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
return node->getEndFrame();
}
else
{
return rc_actor[actor].animation[animation].end_frame;
}
}
return 0;
}
int rc_getActorCurrentFrame(int actor)
int rc_getActorFrame(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return 0;
@@ -5040,33 +5173,37 @@ int rc_getActorCurrentFrame(int actor)
}
//set actor animation speed
void rc_setActorAnimationSpeed(int actor, double speed)
void rc_setActorAnimationSpeed(int actor, int animation, double speed)
{
if(actor < 0 || actor >= rc_actor.size())
return;
if(animation < 0 || animation >= rc_actor[actor].animation.size())
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setAnimationSpeed( (irr::f32)speed );
rc_actor[actor].animation[animation].fps = speed;
if(animation == rc_actor[actor].current_animation)
{
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setAnimationSpeed( (irr::f32)speed );
}
break;
}
}
double rc_getActorAnimationSpeed(int actor)
double rc_getActorAnimationSpeed(int actor, int animation)
{
if(actor < 0 || actor >= rc_actor.size())
return 0;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
return node->getAnimationSpeed();
}
if(animation < 0 || animation >= rc_actor[actor].animation.size())
return 0;
return 0;
return rc_actor[actor].animation[animation].fps;
}
void rc_setActorFrame(int actor, int frame)
@@ -5078,11 +5215,117 @@ void rc_setActorFrame(int actor, int frame)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
rc_actor[actor].animation[0].start_frame = frame;
rc_actor[actor].animation[0].end_frame = frame;
rc_actor[actor].animation[0].fps = 0;
rc_actor[actor].current_animation_loop = 0;
rc_actor[actor].isPlaying = true;
rc_actor[actor].current_animation = 0;
node->setCurrentFrame(frame);
break;
}
}
void rc_setActorAnimationFrames(int actor, int animation, int start_frame, int end_frame)
{
if(actor < 0 || actor >= rc_actor.size())
return;
if(animation < 0 || animation >= rc_actor[actor].animation.size())
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
rc_actor[actor].animation[animation].start_frame = start_frame;
rc_actor[actor].animation[animation].end_frame = end_frame;
if(animation == rc_actor[actor].current_animation)
{
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setFrameLoop(start_frame, end_frame);
}
break;
}
}
void rc_startActorTransition(int actor, double frame, double transition_time)
{
if(actor < 0 || actor >= rc_actor.size())
return;
if(rc_actor[actor].transition)
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setTransitionTime(transition_time);
//node->setJointMode(irr::scene::EJUOR_CONTROL); //This is actually called in setTransitionTime()
node->setCurrentFrame(frame);
rc_actor[actor].transition_frame = frame;
rc_actor[actor].transition = true;
rc_actor[actor].transition_time = transition_time;
rc_actor[actor].transition_start_time = ((double)SDL_GetTicks())/1000.0;
rc_actor[actor].current_animation = RC_ANIMATION_TRANSITION;
rc_transition_actor.push_back(actor);
}
}
double rc_getActorTransitionTime(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return 0;
if(rc_actor[actor].transition)
return rc_actor[actor].transition_time;
return 0;
}
void rc_stopActorTransition(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setTransitionTime(0);
node->setJointMode(irr::scene::EJUOR_NONE);
rc_actor[actor].transition = false;
rc_actor[actor].transition_time = 0;
rc_setActorFrame(actor, rc_actor[actor].transition_frame);
for(int i = 0; i < rc_transition_actor.size();)
{
if(rc_transition_actor[i] == actor)
{
rc_transition_actor.erase(i);
}
else
i++;
}
}
}
bool rc_actorIsInTransition(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return false;
return rc_actor[actor].transition;
}
//set actor animation speed
void rc_setActorAutoCulling(int actor, int cull_type)
{
@@ -5458,34 +5701,7 @@ Uint32 rc_getLightSpecularColor(int actor)
}
void rc_loopActorAnimation(int actor, bool flag)
{
if(actor < 0 || actor >= rc_actor.size())
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setLoopMode(flag);
break;
}
}
bool rc_actorAnimationIsLooped(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return false;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
return node->getLoopMode();
}
return false;
}
//set actor animation speed
void rc_setActorVisible(int actor, bool flag)
@@ -5505,75 +5721,6 @@ bool rc_actorIsVisible(int actor)
return rc_actor[actor].mesh_node->isVisible();
}
void rc_startActorTransition(int actor, double frame, double transition_time)
{
if(actor < 0 || actor >= rc_actor.size())
return;
if(rc_actor[actor].transition)
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setTransitionTime(transition_time);
node->setJointMode(irr::scene::EJUOR_CONTROL);
node->setCurrentFrame(frame);
rc_actor[actor].transition = true;
rc_actor[actor].transition_time = transition_time;
rc_actor[actor].transition_start_time = ((double)SDL_GetTicks())/1000.0;
rc_transition_actor.push_back(actor);
}
}
double rc_getActorTransitionTime(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return 0;
if(rc_actor[actor].transition)
return rc_actor[actor].transition_time;
return 0;
}
void rc_stopActorTransition(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return;
switch(rc_actor[actor].node_type)
{
case RC_NODE_TYPE_MESH:
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*)rc_actor[actor].mesh_node;
node->setTransitionTime(0);
node->setJointMode(irr::scene::EJUOR_NONE);
rc_actor[actor].transition = false;
rc_actor[actor].transition_time = 0;
for(int i = 0; i < rc_transition_actor.size();)
{
if(rc_transition_actor[i] == actor)
{
rc_transition_actor.erase(i);
}
else
i++;
}
}
}
bool rc_actorIsInTransition(int actor)
{
if(actor < 0 || actor >= rc_actor.size())
return false;
return rc_actor[actor].transition;
}
void rc_getTerrainPatchAABB(int actor, double patch_x, double patch_z, double* min_x, double* min_y, double* min_z, double* max_x, double* max_y, double* max_z)
{
@@ -6717,7 +6864,7 @@ double rc_getCameraNearValue()
return rc_canvas[rc_active_canvas].camera.camera->getNearValue();
}
void rc_setCameraProjectionMatrix(int proj_matrix, int proj_type)
void rc_setProjectionMatrix(int proj_matrix, int proj_type)
{
if(!(rc_active_canvas > 0 && rc_active_canvas < rc_canvas.size()))
return;
@@ -6733,7 +6880,7 @@ void rc_setCameraProjectionMatrix(int proj_matrix, int proj_type)
rc_canvas[rc_active_canvas].camera.camera->setProjectionMatrix(irr_mat, isOrtho);
}
void rc_getCameraProjectionMatrix(int proj_matrix)
void rc_getProjectionMatrix(int proj_matrix)
{
if(!(rc_active_canvas > 0 && rc_active_canvas < rc_canvas.size()))
return;

View File

@@ -307,7 +307,7 @@ struct rc_physicsWorld2D_obj
b2World* world;
rc_contactListener_obj* contact_listener;
float timeStep = 1/20.0; //the length of time passed to simulate (seconds)
float timeStep = 1/60.0; //the length of time passed to simulate (seconds)
int velocityIterations = 8; //how strongly to correct velocity
int positionIterations = 3; //how strongly to correct position
};
@@ -355,6 +355,7 @@ struct rc_canvas_obj
irr::core::array<rc_canvas_obj> rc_canvas;
irr::core::array<u32> rc_canvas_zOrder;
int rc_active_canvas = -1;
bool hasPreUpdated = false;
irr::video::SColor rc_active_color(0,0,0,0);
irr::video::SColor rc_clear_color(0,0,0,0);
@@ -516,6 +517,19 @@ struct rc_particle_properties_obj
bool outlineOnly;
};
#define RC_ANIMATION_MD2 -2
#define RC_ANIMATION_TRANSITION -3
struct rc_actor_animation_obj
{
bool active;
int start_frame;
int end_frame;
double fps;
irr::u32 frame_start_time;
irr::u32 frame_swap_time;
};
struct rc_scene_node
{
int node_type = 0;
@@ -525,12 +539,20 @@ struct rc_scene_node
rc_node_physics physics;
bool transition;
double transition_frame;
double transition_time;
double transition_start_time;
rc_particle_properties_obj particle_properties;
int material_ref_index = -1;
int current_animation;
int num_animation_loops;
int current_animation_loop;
bool isPlaying;
irr::core::array<int> deleted_animation;
irr::core::array<rc_actor_animation_obj> animation;
};
irr::core::array<rc_scene_node> rc_actor;
@@ -538,6 +560,35 @@ irr::core::array<rc_scene_node> rc_actor;
irr::core::array<int> rc_transition_actor;
class rc_animEndCallBack : public IAnimationEndCallBack
{
public:
rc_scene_node* ref_actor;
void OnAnimationEnd( IAnimatedMeshSceneNode *node)
{
if(ref_actor->current_animation_loop < ref_actor->num_animation_loops || ref_actor->num_animation_loops < 0)
{
//std::cout << "animating" << std::endl;
irr::scene::IAnimatedMeshSceneNode* node = (irr::scene::IAnimatedMeshSceneNode*) ref_actor->mesh_node;
int animation = ref_actor->current_animation;
if(animation < 0 || animation >= ref_actor->animation.size())
return;
int start_frame = ref_actor->animation[animation].start_frame;
int end_frame = ref_actor->animation[animation].end_frame;
node->setFrameLoop(start_frame, end_frame);
ref_actor->current_animation_loop++;
}
else
{
ref_actor->isPlaying = false;
}
//std::cout << "The animation has ended!" << std::endl;
// Your callback code goes there.
}
};
void myTickCallback2(btSoftRigidDynamicsWorld* dynamicsWorld, btScalar timeStep)
{
rc_collisions.clear();

View File

@@ -51,6 +51,7 @@ struct rc_sprite2D_obj
int num_animation_loops;
int current_animation_loop;
bool isPlaying;
irr::core::array<int> deleted_sprites;
irr::core::array<rc_sprite2D_animation_obj> animation;
int parent_canvas = -1;

View File

@@ -32,11 +32,29 @@ int rc_createSpriteAnimation(int spr_id, int anim_length, double fps)
animation.frames.push_back(0);
int animation_id = rc_sprite[spr_id].animation.size();
rc_sprite[spr_id].animation.push_back(animation);
if(rc_sprite[spr_id].deleted_sprites.size() > 0)
{
animation_id = rc_sprite[spr_id].deleted_sprites[0];
rc_sprite[spr_id].deleted_sprites.erase(0);
rc_sprite[spr_id].animation[animation_id] = animation;
}
else
rc_sprite[spr_id].animation.push_back(animation);
return animation_id;
}
void rc_deleteSpriteAnimation(int spr_id, int animation)
{
if(spr_id < 0 || spr_id >= rc_sprite.size())
return;
if(!rc_sprite[spr_id].active)
return;
rc_sprite[spr_id].deleted_sprites.push_back(animation);
}
void rc_setSpriteFrame(int spr_id, int frame)
{
if(spr_id < 0 || spr_id >= rc_sprite.size())
@@ -176,7 +194,7 @@ double rc_getSpriteAnimationSpeed(int spr_id, int animation)
return rc_sprite[spr_id].animation[animation].fps;
}
void rc_setSpriteAnimation(int spr_id, int animation)
void rc_setSpriteAnimation(int spr_id, int animation, int num_loops)
{
if(spr_id < 0 || spr_id >= rc_sprite.size())
return;
@@ -191,6 +209,7 @@ void rc_setSpriteAnimation(int spr_id, int animation)
rc_sprite[spr_id].animation[animation].current_frame = 0;
rc_sprite[spr_id].isPlaying = true;
rc_sprite[spr_id].animation[animation].frame_start_time = SDL_GetTicks();
rc_sprite[spr_id].num_animation_loops = num_loops;
}
int rc_getSpriteAnimation(int spr_id)
@@ -238,6 +257,17 @@ int rc_numSpriteAnimationLoops(int spr_id)
return rc_sprite[spr_id].num_animation_loops;
}
bool rc_spriteAnimationIsPlaying(int spr_id)
{
if(spr_id < 0 || spr_id >= rc_sprite.size())
return false;
if(!rc_sprite[spr_id].active)
return false;
return rc_sprite[spr_id].isPlaying;
}
//------------------------------SPRITES-------------------------------------------------------
//Larger z gets drawn first
void sortSpriteZ(int canvas_id)
@@ -575,7 +605,7 @@ void rc_setSpriteScale(int spr_id, double x, double y)
rc_sprite[spr_id].scale.set(x, y);
if(rc_sprite[spr_id].isSolid)
if(true) //(rc_sprite[spr_id].isSolid) //I probably originally planned on not having a fixture for non-solid sprites but then I discovered sensors
{
if(rc_sprite[spr_id].physics.fixture)
{
@@ -650,6 +680,19 @@ void rc_scaleSprite(int spr_id, double x, double y)
rc_setSpriteScale(spr_id, scale_x, scale_y);
}
void rc_getSpriteScale(int spr_id, double* x, double* y)
{
if(spr_id < 0 || spr_id >= rc_sprite.size())
return;
if(!rc_sprite[spr_id].active)
return;
*x = rc_sprite[spr_id].scale.X;
*y = rc_sprite[spr_id].scale.Y;
}
double rc_spriteWidth(int spr_id)
{
if(spr_id < 0 || spr_id >= rc_sprite.size())
@@ -748,11 +791,12 @@ void drawSprites(int canvas_id)
int32 velocityIterations = rc_canvas[canvas_id].physics2D.velocityIterations;
int32 positionIterations = rc_canvas[canvas_id].physics2D.positionIterations;
if(rc_canvas[canvas_id].physics2D.enabled)
if(rc_canvas[canvas_id].physics2D.enabled && (!hasPreUpdated))
rc_canvas[canvas_id].physics2D.world->Step(step, velocityIterations, positionIterations);
//Setting the render target to the current canvas. NOTE: I might change this target to a separate sprite layer later.
VideoDriver->setRenderTarget(rc_canvas[canvas_id].texture, true, false);
VideoDriver->setRenderTarget(rc_canvas[canvas_id].texture, true, true);
VideoDriver->clearBuffers(true, true, true, irr::video::SColor(0,0,0,0));
irr::core::dimension2d<irr::u32> src_size;
@@ -780,12 +824,38 @@ void drawSprites(int canvas_id)
double spr_timer = SDL_GetTicks();
int offset_x = rc_canvas[canvas_id].offset.X;
int offset_y = rc_canvas[canvas_id].offset.Y;
for(int spr_index = 0; spr_index < rc_canvas[canvas_id].sprite.size(); spr_index++)
{
rc_sprite2D_obj* sprite = rc_canvas[canvas_id].sprite[spr_index];
if(!sprite->visible)
continue;
physics_pos = sprite->physics.body->GetPosition();
x = (int)physics_pos.x - offset_x;
y = (int)physics_pos.y - offset_y;
int xf = x + sprite->frame_size.Width;
int yf = y + sprite->frame_size.Height;
//std::cout << "sprite info: " << xf << ", " << x << ", " << rc_canvas[canvas_id].viewport.dimension.Width << std::endl;
if( (xf < 0) || (x > ((int)rc_canvas[canvas_id].viewport.dimension.Width)) )
{
//std::cout << "skip draw[X]: " << spr_index << std::endl;
continue;
}
if( (yf < 0) || (y > ((int)rc_canvas[canvas_id].viewport.dimension.Height)) )
{
//std::cout << "skip draw[Y]: " << spr_index << std::endl;
continue;
}
position.set(x, y);
int img_id = sprite->image_id;
if(img_id < 0 || img_id >= rc_image.size())
continue;
@@ -826,10 +896,10 @@ void drawSprites(int canvas_id)
sourceRect = irr::core::rect<irr::s32>( frame_pos, src_size);
//sourceRect = irr::core::rect<irr::s32>( irr::core::vector2d<irr::s32>(0, 0), src_size);
physics_pos = sprite->physics.body->GetPosition();
x = (int)physics_pos.x;
y = (int)physics_pos.y;
position.set(x, y);
//physics_pos = sprite->physics.body->GetPosition();
//x = (int)physics_pos.x;
//y = (int)physics_pos.y;
//position.set(x, y);
rotationPoint.set(x + (src_size.Width/2), y + (src_size.Height/2)); //TODO: need to account for offset once that is implemented

View File

@@ -370,7 +370,7 @@ inline std::string rc_intern_replace(std::string src, std::string tgt, std::stri
return src;
}
inline string rc_intern_reverse(std::string rpc_string)
inline std::string rc_intern_reverse(std::string rpc_string)
{
std::string n_str = "";
if(rpc_string.length()==0)
@@ -409,7 +409,7 @@ inline std::string rc_intern_rtrim(std::string src)
if(i < 0)
return "";
if(src.find_first_not_of(" ") == string::npos)
if(src.find_first_not_of(" ") == std::string::npos)
return "";
return utf8_substr(src,0,i+1);
@@ -436,7 +436,7 @@ inline std::string rc_intern_stringFromBuffer(double* buffer, size_t buffer_size
return (std::string)c_buf;
}
inline string rc_intern_stringfill(std::string f_string, size_t n)
inline std::string rc_intern_stringfill(std::string f_string, size_t n)
{
std::string f = "";
for(size_t i = 0; i < n; i++)
@@ -446,21 +446,21 @@ inline string rc_intern_stringfill(std::string f_string, size_t n)
inline std::string rc_intern_str(double n)
{
stringstream ss;
std::stringstream ss;
ss << n;
return ss.str();
}
inline std::string rc_intern_str_f(double n)
{
stringstream ss;
std::stringstream ss;
ss << fixed << n;
return ss.str();
}
inline std::string rc_intern_str_s(double n)
{
stringstream ss;
std::stringstream ss;
ss << scientific << n;
return ss.str();
}
@@ -608,7 +608,7 @@ inline double rc_intern_frac(double n)
inline std::string rc_intern_hex(uint64_t n)
{
stringstream ss;
std::stringstream ss;
ss << hex << n;
return ss.str();
}
@@ -616,7 +616,7 @@ inline std::string rc_intern_hex(uint64_t n)
inline double rc_intern_hexInt(std::string n)
{
uint64_t x;
stringstream ss;
std::stringstream ss;
ss << hex << n;
ss >> x;
return (double)x;

View File

@@ -0,0 +1,413 @@
#ifndef RC_TILELIB_H_INCLUDED
#define RC_TILELIB_H_INCLUDED
#ifdef RC_ANDROID
#include "SDL.h"
#else
#include <SDL2/SDL.h>
#endif // _IRR_ANDROID_PLATFORM_
#include "rc_tilemap.h"
#include "rc_gfx_core.h"
int rc_createTileSet(int img_id, int tile_w, int tile_h)
{
if(img_id < 0 || img_id >= rc_image.size())
return -1;
if(!rc_image[img_id].image)
return -1;
rc_tileset_obj tset;
tset.active = true;
tset.img_id = img_id;
tset.tile_width = tile_w;
tset.tile_height = tile_h;
int num_tiles = ((int)rc_image[img_id].image->getSize().Width / tile_w) * ((int)rc_image[img_id].image->getSize().Height / tile_h);
tset.tiles.resize(num_tiles);
for(int i = 0; i < tset.tiles.size(); i++)
{
tset.tiles[i].frames.push_back(i);
tset.tiles[i].fps = 0;
tset.tiles[i].frame_swap_time = 0;
tset.tiles[i].frame_start_time = 0;
}
int tset_id = rc_tileset.size();
if(rc_deleted_tileset.size() > 0)
{
tset_id = rc_deleted_tileset[0];
rc_deleted_tileset.erase(rc_deleted_tileset.begin());
rc_tileset[tset_id] = tset;
}
else
rc_tileset.push_back(tset);
return tset_id;
}
void rc_setTileAnimationLength(int tileset, int base_tile, int num_frames)
{
if(tileset < 0 || tileset >= rc_tileset.size())
return;
if(!rc_tileset[tileset].active)
return;
if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size())
return;
rc_tileset[tileset].tiles[base_tile].frames.resize(num_frames);
rc_tileset[tileset].tiles[base_tile].num_frames = num_frames;
}
int rc_getTileAnimationLength(int tileset, int base_tile)
{
if(tileset < 0 || tileset >= rc_tileset.size())
return 0;
if(!rc_tileset[tileset].active)
return 0;
if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size())
return 0;
return rc_tileset[tileset].tiles[base_tile].num_frames;
}
void rc_setTileAnimationFrame(int tileset, int base_tile, int anim_frame, int tile_frame)
{
if(tileset < 0 || tileset >= rc_tileset.size())
return;
if(!rc_tileset[tileset].active)
return;
if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size())
return;
rc_tileset[tileset].tiles[base_tile].frames[anim_frame] = tile_frame;
}
int rc_getTileAnimationFrame(int tileset, int base_tile, int anim_frame)
{
if(tileset < 0 || tileset >= rc_tileset.size())
return -1;
if(!rc_tileset[tileset].active)
return -1;
if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size())
return -1;
return rc_tileset[tileset].tiles[base_tile].frames[anim_frame];
}
void rc_setTileAnimationSpeed(int tileset, int base_tile, double speed)
{
if(tileset < 0 || tileset >= rc_tileset.size())
return;
if(!rc_tileset[tileset].active)
return;
if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size())
return;
rc_tileset[tileset].tiles[base_tile].fps = speed;
rc_tileset[tileset].tiles[base_tile].frame_swap_time = 1000/speed;
}
double rc_getTileAnimationSpeed(int tileset, int base_tile)
{
if(tileset < 0 || tileset >= rc_tileset.size())
return 0;
if(!rc_tileset[tileset].active)
return 0;
if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size())
return 0;
return rc_tileset[tileset].tiles[base_tile].fps;
}
//--------------------------------------TILEMAP-----------------------------------------------
int rc_createTileMap(int tileset, int widthInTiles, int heightInTiles)
{
if(tileset < 0 || tileset >= rc_tileset.size())
return -1;
if(!rc_tileset[tileset].active)
return -1;
rc_tilemap_obj tilemap;
tilemap.active = true;
tilemap.texture = NULL;
tilemap.tileset = tileset;
tilemap.num_tiles_across = widthInTiles;
tilemap.num_tiles_down = heightInTiles;
tilemap.rows.resize(heightInTiles);
for(int i = 0; i < tilemap.rows.size(); i++)
{
tilemap.rows[i].tile.resize(widthInTiles);
}
int tm_id = rc_tilemap.size();
if(rc_deleted_tilemap.size() > 0)
{
tm_id = rc_deleted_tilemap[0];
rc_deleted_tilemap.erase(rc_deleted_tilemap.begin());
rc_tilemap[tm_id] = tilemap;
}
else
rc_tilemap.push_back(tilemap);
return tm_id;
}
void rc_setTileMapSize(int tilemap, int widthInTiles, int heightInTiles)
{
if(tilemap < 0 || tilemap >= rc_tilemap.size())
return;
if(!rc_tilemap[tilemap].active)
return;
rc_tilemap[tilemap].num_tiles_across = widthInTiles;
rc_tilemap[tilemap].num_tiles_down = heightInTiles;
rc_tilemap[tilemap].rows.resize(heightInTiles);
for(int i = 0; i < rc_tilemap[tilemap].rows.size(); i++)
{
rc_tilemap[tilemap].rows[i].tile.resize(widthInTiles);
}
}
void rc_getTileMapSize(int tilemap, double* widthInTiles, double* heightInTiles)
{
if(tilemap < 0 || tilemap >= rc_tilemap.size())
return;
if(!rc_tilemap[tilemap].active)
return;
*widthInTiles = rc_tilemap[tilemap].num_tiles_across;
*heightInTiles = rc_tilemap[tilemap].num_tiles_down;
}
void rc_setTile(int tilemap, int tile, int x, int y)
{
if(tilemap < 0 || tilemap >= rc_tilemap.size())
return;
if(!rc_tilemap[tilemap].active)
return;
int tileset = rc_tilemap[tilemap].tileset;
//if tilemap exists, then its safe to assume tileset is in range since tilemap can't be created if its not
if(!rc_tileset[tileset].active)
return;
int num_tset_tiles = rc_tileset[tileset].tiles.size();
if(tile < 0 || tile >= num_tset_tiles)
return;
if( (x < 0 || x >= rc_tilemap[tilemap].num_tiles_across) || (y < 0 || y >= rc_tilemap[tilemap].num_tiles_down) )
return;
rc_tilemap[tilemap].rows[y].tile[x] = tile;
}
int rc_getTile(int tilemap, int x, int y)
{
if(tilemap < 0 || tilemap >= rc_tilemap.size())
return -1;
if(!rc_tilemap[tilemap].active)
return -1;
if( (x < 0 || x >= rc_tilemap[tilemap].num_tiles_across) || (y < 0 || y >= rc_tilemap[tilemap].num_tiles_down) )
return -1;
return rc_tilemap[tilemap].rows[y].tile[x];
}
void rc_fillTile(int tilemap, int tile, int x, int y, int widthInTiles, int heightInTiles)
{
if(tilemap < 0 || tilemap >= rc_tilemap.size())
return;
if(!rc_tilemap[tilemap].active)
return;
int tileset = rc_tilemap[tilemap].tileset;
//if tilemap exists, then its safe to assume tileset is in range since tilemap can't be created if its not
if(!rc_tileset[tileset].active)
return;
int num_tset_tiles = rc_tileset[tileset].tiles.size();
if(tile < 0 || tile >= num_tset_tiles)
return;
if( (x < 0 || x >= rc_tilemap[tilemap].num_tiles_across) || (y < 0 || y >= rc_tilemap[tilemap].num_tiles_down) )
return;
if( ( (x+widthInTiles) < 0 || (x+widthInTiles) > rc_tilemap[tilemap].num_tiles_across) || ( (y+heightInTiles) < 0 || (y+heightInTiles) > rc_tilemap[tilemap].num_tiles_down) )
return;
for(int iy = 0; iy < heightInTiles; iy++)
for(int ix = 0; ix < widthInTiles; ix++)
rc_tilemap[tilemap].rows[y+iy].tile[x+ix] = tile;
}
void getTileInTileset(int tileset, int tile, int* x, int* y)
{
int img_w = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Width;
int img_h = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Height;
int tile_w = rc_tileset[tileset].tile_width;
int tile_h = rc_tileset[tileset].tile_height;
int widthInTiles = img_w / tile_w;
*x = (tile%widthInTiles) * tile_w;
*y = (tile/widthInTiles) * tile_h;
}
int getNumTilesInTileset(int tileset)
{
int img_w = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Width;
int img_h = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Height;
int tile_w = rc_tileset[tileset].tile_width;
int tile_h = rc_tileset[tileset].tile_height;
int widthInTiles = img_w / tile_w;
int heightInTiles = img_h / tile_h;
return (widthInTiles*heightInTiles);
}
void updateTileset(int tileset)
{
Uint32 current_time_ms = SDL_GetTicks();
for(int i = 0; i < rc_tileset[tileset].tiles.size(); i++)
{
if( (current_time_ms-rc_tileset[tileset].tiles[i].frame_start_time) >= rc_tileset[tileset].tiles[i].frame_swap_time )
{
rc_tileset[tileset].tiles[i].current_frame++;
if(rc_tileset[tileset].tiles[i].current_frame >= rc_tileset[tileset].tiles[i].num_frames)
rc_tileset[tileset].tiles[i].current_frame = 0;
rc_tileset[tileset].tiles[i].frame_start_time = current_time_ms;
}
}
}
void rc_drawTileMap(int tilemap, int x, int y, int w, int h, int offset_x, int offset_y)
{
if(tilemap < 0 || tilemap >= rc_tilemap.size())
return;
if(!rc_tilemap[tilemap].active)
return;
if(rc_active_canvas < 0 || rc_active_canvas >= rc_canvas.size())
return;
if(!rc_canvas[rc_active_canvas].type == RC_CANVAS_TYPE_2D)
return;
if(!rc_canvas[rc_active_canvas].texture)
return;
rc_tilemap[tilemap].texture = VideoDriver->addRenderTargetTexture(irr::core::dimension2d<u32>(w,h), "rt", ECF_A8R8G8B8);
VideoDriver->setRenderTarget(rc_tilemap[tilemap].texture, true, true, irr::video::SColor(0,0,0,0));
int tileset = rc_tilemap[tilemap].tileset;
updateTileset(tileset);
int vp_widthInTiles = w/rc_tileset[tileset].tile_width;
int vp_heightInTiles = h/rc_tileset[tileset].tile_height;
int tset_img_id = rc_tileset[tileset].img_id;
int src_w = rc_tileset[tileset].tile_width;
int src_h = rc_tileset[tileset].tile_height;
int tile_offset_x = offset_x / src_w;
int tile_offset_y = offset_y / src_h;
int screen_offset_x = 0 - (offset_x % src_w);
int screen_offset_y = 0 - (offset_y % src_h);
int num_tiles_in_tset = getNumTilesInTileset(tileset);
for(int iy = 0; iy < vp_heightInTiles+1; iy++)
{
for(int ix = 0; ix < vp_widthInTiles+1; ix++)
{
int current_frame = 0; //TODO: ADD TIMING
int map_x = tile_offset_x + ix;
int map_y = tile_offset_y + iy;
if(map_x < 0 || map_x >= rc_tilemap[tilemap].num_tiles_across || map_y < 0 || map_y >= rc_tilemap[tilemap].num_tiles_down)
continue;
int tile = rc_tilemap[tilemap].rows[map_y].tile[map_x];
if(tile < 0 || tile >= num_tiles_in_tset)
continue;
current_frame = rc_tileset[tileset].tiles[tile].current_frame;
tile = rc_tileset[tileset].tiles[tile].frames[current_frame];
if(tile < 0 || tile >= num_tiles_in_tset)
continue;
int src_x = 0;
int src_y = 0;
getTileInTileset(tileset, tile, &src_x, &src_y);
irr::core::rect<irr::s32> sourceRect( irr::core::vector2d<irr::s32>(src_x, src_y), irr::core::dimension2d<irr::s32>(src_w, src_h));
irr::video::SColor color(rc_image[tset_img_id].alpha,
rc_image[tset_img_id].color_mod.getRed(),
rc_image[tset_img_id].color_mod.getGreen(),
rc_image[tset_img_id].color_mod.getBlue());
int dst_x = screen_offset_x + (ix*src_w);
int dst_y = screen_offset_y + (iy*src_h);
irr::core::rect<irr::s32> dest( irr::core::vector2d<irr::s32>(dst_x, dst_y), irr::core::dimension2d<irr::s32>(src_w, src_h));
VideoDriver->draw2DImage(rc_image[tset_img_id].image, dest, sourceRect, 0, 0, true);
}
}
VideoDriver->setRenderTarget(rc_canvas[rc_active_canvas].texture, false, false);
irr::core::rect<irr::s32> sourceRect( irr::core::vector2d<irr::s32>(0, 0), irr::core::dimension2d<irr::s32>(w, h));
irr::core::rect<irr::s32> dest( irr::core::vector2d<irr::s32>(x, y), irr::core::dimension2d<irr::s32>(w, h));
VideoDriver->draw2DImage(rc_tilemap[tilemap].texture, dest, sourceRect, 0, 0, false);
VideoDriver->removeTexture(rc_tilemap[tilemap].texture);
rc_tilemap[tilemap].texture = NULL;
//draw2DImage(VideoDriver, rc_tilemap[tilemap].texture, src, pos,)
}
#endif // RC_TILELIB_H_INCLUDED

View File

@@ -0,0 +1,57 @@
#ifndef RC_TILEMAP_H_INCLUDED
#define RC_TILEMAP_H_INCLUDED
#include <irrlicht.h>
#include <vector>
struct rc_tile_obj
{
int id;
double fps;
int num_frames;
int current_frame;
std::vector<int> frames;
Uint32 frame_start_time;
Uint32 frame_swap_time;
};
struct rc_tileset_obj
{
bool active;
int img_id;
int tile_width;
int tile_height;
std::vector<rc_tile_obj> tiles;
};
struct rc_tilemap_row_obj
{
std::vector<int> tile;
};
struct rc_tilemap_obj
{
bool active;
int tileset;
irr::video::ITexture* texture;
int num_tiles_across;
int num_tiles_down;
std::vector<rc_tilemap_row_obj> rows;
};
std::vector<rc_tileset_obj> rc_tileset;
std::vector<rc_tilemap_obj> rc_tilemap;
std::vector<int> rc_deleted_tileset;
std::vector<int> rc_deleted_tilemap;
#endif // RC_TILEMAP_H_INCLUDED