diff --git a/rcbasic_build/main.cpp b/rcbasic_build/main.cpp index b351817..cb88e25 100755 --- a/rcbasic_build/main.cpp +++ b/rcbasic_build/main.cpp @@ -920,8 +920,9 @@ int main(int argc, char * argv[]) //DEBUG START //rc_filename = "/home/n00b/projects/bu/constraint_demo/main.bas"; - //rc_filename = "/home/n00b/Music/Simple 3D Platformer/main.bas"; + //rc_filename = "/home/n00b/Downloads/Tile Scrolling/main.bas"; //rc_filename = "/home/n00b/Programs/RCBasic_v400_Linux64/examples/Constraint/main.bas"; + //rc_filename = "/home/n00b/Programs/RCBasic_v400_Linux64/examples/Simple 3D Platformer/main.bas"; //DEBUG END //enable_presets = true; diff --git a/rcbasic_build/rcbasic4_changes.ods b/rcbasic_build/rcbasic4_changes.ods index 66106ff..5facb2c 100644 Binary files a/rcbasic_build/rcbasic4_changes.ods and b/rcbasic_build/rcbasic4_changes.ods differ diff --git a/rcbasic_runtime/main.cpp b/rcbasic_runtime/main.cpp index 13d9a48..6290418 100755 --- a/rcbasic_runtime/main.cpp +++ b/rcbasic_runtime/main.cpp @@ -4453,7 +4453,7 @@ int main(int argc, char * argv[]) } else { - rc_intern_dirChange("/home/n00b/Programs/RCBasic_v400_Linux64/examples/Constraint/"); + rc_intern_dirChange("/home/n00b/Programs/RCBasic_v400_Linux64/examples/Simple 3D Platformer/"); } #endif //--------------- diff --git a/rcbasic_runtime/rc_base_actor.h b/rcbasic_runtime/rc_base_actor.h index 435a0bd..5f073a9 100644 --- a/rcbasic_runtime/rc_base_actor.h +++ b/rcbasic_runtime/rc_base_actor.h @@ -311,7 +311,7 @@ int rc_createAnimatedActor(int mesh_id) rc_actor[actor_id].current_animation_loop = 0; rc_actor[actor_id].num_animation_loops = 0; rc_animEndCallBack* anim_callback = new rc_animEndCallBack(); - anim_callback->ref_actor = &rc_actor[actor_id]; + anim_callback->ref_id = actor_id; anim_callback->OnAnimationEnd(node); node->setAnimationEndCallback(anim_callback); node->setLoopMode(false); diff --git a/rcbasic_runtime/rc_gfx.h b/rcbasic_runtime/rc_gfx.h index 3ef015e..606908d 100644 --- a/rcbasic_runtime/rc_gfx.h +++ b/rcbasic_runtime/rc_gfx.h @@ -1055,6 +1055,7 @@ int rc_canvasOpen(int w, int h, int vx, int vy, int vw, int vh, int mode, int ca canvas.physics2D.enabled = true; canvas.physics2D.contact_listener = new rc_contactListener_obj(); canvas.physics2D.world->SetContactListener(canvas.physics2D.contact_listener); + canvas.sprite_id.clear(); } switch(mode) @@ -1133,13 +1134,14 @@ void rc_canvasClose(int canvas_id) } //sprites are destroyed when the world is deleted so I just to set the active attribute to false and set the body to NULL - for(int i = 0; i < rc_canvas[canvas_id].sprite.size(); i++) + for(int i = 0; i < rc_canvas[canvas_id].sprite_id.size(); i++) { - rc_canvas[canvas_id].sprite[i]->active = false; - rc_canvas[canvas_id].sprite[i]->physics.body = NULL; + int spr_id = rc_canvas[canvas_id].sprite_id[i]; + rc_sprite[spr_id].active = false; + rc_sprite[spr_id].physics.body = NULL; } - rc_canvas[canvas_id].sprite.clear(); + rc_canvas[canvas_id].sprite_id.clear(); if(rc_active_canvas == canvas_id) rc_active_canvas = -1; @@ -1177,25 +1179,6 @@ void rc_setCanvasPhysics2D(int canvas_id, bool flag) rc_canvas[canvas_id].physics2D.enabled = flag; } - -void rc_clearCanvas() -{ - if(rc_active_canvas >= 0 && rc_active_canvas < rc_canvas.size()) - { - if(rc_canvas[rc_active_canvas].texture) - switch(rc_canvas[rc_active_canvas].type) - { - case RC_CANVAS_TYPE_2D: - VideoDriver->clearBuffers(true, true, true, rc_clear_color); - break; - default: - VideoDriver->clearBuffers(true, true, true, rc_clear_color); - break; - } - - } -} - void rc_setCanvasVisible(int canvas_id, bool flag) { if(canvas_id <= 0 || canvas_id >= rc_canvas.size()) //canvas 0 is being excluded because its the back buffer diff --git a/rcbasic_runtime/rc_gfx_core.h b/rcbasic_runtime/rc_gfx_core.h index f6a0147..67fa666 100644 --- a/rcbasic_runtime/rc_gfx_core.h +++ b/rcbasic_runtime/rc_gfx_core.h @@ -298,9 +298,9 @@ class rc_contactListener_obj : public b2ContactListener { void BeginContact(b2Contact* contact) { - rc_sprite2D_obj* spriteA = (rc_sprite2D_obj*) contact->GetFixtureA()->GetBody()->GetUserData().pointer; + rc_sprite2D_obj* spriteA = &rc_sprite[contact->GetFixtureA()->GetBody()->GetUserData().pointer]; - rc_sprite2D_obj* spriteB = (rc_sprite2D_obj*) contact->GetFixtureB()->GetBody()->GetUserData().pointer; + rc_sprite2D_obj* spriteB = &rc_sprite[contact->GetFixtureB()->GetBody()->GetUserData().pointer]; //std::cout << "sprite[" << spriteA->id << "] collide with sprite[" << spriteB->id << "]" << std::endl; @@ -361,7 +361,7 @@ struct rc_canvas_obj irr::u32 color_mod; rc_physicsWorld2D_obj physics2D; - irr::core::array sprite; + irr::core::array sprite_id; }; irr::core::array rc_canvas; @@ -586,10 +586,11 @@ irr::core::array rc_transition_actor; class rc_animEndCallBack : public IAnimationEndCallBack { public: - rc_scene_node* ref_actor; + int ref_id; void OnAnimationEnd( IAnimatedMeshSceneNode *node) { + rc_scene_node* ref_actor = &rc_actor[ref_id]; if(ref_actor->current_animation_loop < ref_actor->num_animation_loops || ref_actor->num_animation_loops < 0) { //std::cout << "animating" << std::endl; diff --git a/rcbasic_runtime/rc_sprite2D.h b/rcbasic_runtime/rc_sprite2D.h index 74b3a25..1fa803e 100644 --- a/rcbasic_runtime/rc_sprite2D.h +++ b/rcbasic_runtime/rc_sprite2D.h @@ -51,7 +51,7 @@ struct rc_sprite2D_obj int num_animation_loops; int current_animation_loop; bool isPlaying; - irr::core::array deleted_sprites; + irr::core::array deleted_animation; irr::core::array animation; int parent_canvas = -1; diff --git a/rcbasic_runtime/rc_sprite_physics.h b/rcbasic_runtime/rc_sprite_physics.h index 935afe9..5443ae2 100644 --- a/rcbasic_runtime/rc_sprite_physics.h +++ b/rcbasic_runtime/rc_sprite_physics.h @@ -621,6 +621,9 @@ std::vector rc_rayHit2D; // Function to perform a ray cast and collect all hits int rc_castRay2D_All(double from_x, double from_y, double to_x, double to_y) { + if(rc_canvas[rc_active_canvas].type != RC_CANVAS_TYPE_SPRITE) + return 0; + rc_rayHit2D.clear(); RayCastCallback callback; const b2Vec2 point1(from_x, from_y); @@ -633,7 +636,7 @@ int rc_castRay2D_All(double from_x, double from_y, double to_x, double to_y) for(int i = 0; i < cb_hits.size(); i++) { rc_rayHit2D_obj hit; - rc_sprite2D_obj* h_sprite = (rc_sprite2D_obj*)cb_hits[i].fixture->GetBody()->GetUserData().pointer; + rc_sprite2D_obj* h_sprite = &rc_sprite[cb_hits[i].fixture->GetBody()->GetUserData().pointer]; hit.sprite_id = h_sprite->id; hit.hit_point = cb_hits[i].point; hit.hit_normal = cb_hits[i].normal; @@ -646,6 +649,9 @@ int rc_castRay2D_All(double from_x, double from_y, double to_x, double to_y) // Function to perform a ray cast and collect the closest hit int rc_castRay2D(double from_x, double from_y, double to_x, double to_y) { + if(rc_canvas[rc_active_canvas].type != RC_CANVAS_TYPE_SPRITE) + return 0; + rc_rayHit2D.clear(); RayCastCallback callback; const b2Vec2 point1(from_x, from_y); @@ -661,7 +667,7 @@ int rc_castRay2D(double from_x, double from_y, double to_x, double to_y) for(int i = 0; i < cb_hits.size(); i++) { rc_rayHit2D_obj hit; - rc_sprite2D_obj* h_sprite = (rc_sprite2D_obj*)cb_hits[i].fixture->GetBody()->GetUserData().pointer; + rc_sprite2D_obj* h_sprite = &rc_sprite[cb_hits[i].fixture->GetBody()->GetUserData().pointer]; hit.sprite_id = h_sprite->id; hit.hit_point = cb_hits[i].point; hit.hit_normal = cb_hits[i].normal; diff --git a/rcbasic_runtime/rc_spritelib.h b/rcbasic_runtime/rc_spritelib.h index c57905c..20ee38c 100644 --- a/rcbasic_runtime/rc_spritelib.h +++ b/rcbasic_runtime/rc_spritelib.h @@ -35,10 +35,10 @@ 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(); - if(rc_sprite[spr_id].deleted_sprites.size() > 0) + if(rc_sprite[spr_id].deleted_animation.size() > 0) { - animation_id = rc_sprite[spr_id].deleted_sprites[0]; - rc_sprite[spr_id].deleted_sprites.erase(0); + animation_id = rc_sprite[spr_id].deleted_animation[0]; + rc_sprite[spr_id].deleted_animation.erase(0); rc_sprite[spr_id].animation[animation_id] = animation; } else @@ -55,7 +55,13 @@ void rc_deleteSpriteAnimation(int spr_id, int animation) if(!rc_sprite[spr_id].active) return; - rc_sprite[spr_id].deleted_sprites.push_back(animation); + for(int i = 0; i < rc_sprite[spr_id].deleted_animation.size(); i++) + { + if(rc_sprite[spr_id].deleted_animation[i] == animation) + return; + } + + rc_sprite[spr_id].deleted_animation.push_back(animation); } void rc_setSpriteFrame(int spr_id, int frame) @@ -281,19 +287,18 @@ void sortSpriteZ(int canvas_id) if(!rc_canvas[canvas_id].texture) return; - for(int i = 0; i < rc_canvas[canvas_id].sprite.size(); i++) + for(int i = 0; i < rc_canvas[canvas_id].sprite_id.size(); i++) { - rc_sprite2D_obj* spriteA = rc_canvas[canvas_id].sprite[i]; + int spriteA = rc_canvas[canvas_id].sprite_id[i]; - for(int j = i+1; j < rc_canvas[canvas_id].sprite.size(); j++) + for(int j = i+1; j < rc_canvas[canvas_id].sprite_id.size(); j++) { - rc_sprite2D_obj* spriteB = rc_canvas[canvas_id].sprite[j]; + int spriteB = rc_canvas[canvas_id].sprite_id[j]; - if(spriteB->z > spriteA->z) + if(rc_sprite[spriteB].z > rc_sprite[spriteA].z) { - rc_canvas[canvas_id].sprite[j] = NULL; - rc_canvas[canvas_id].sprite.erase(j); - rc_canvas[canvas_id].sprite.insert(spriteB, i); + rc_canvas[canvas_id].sprite_id.erase(j); + rc_canvas[canvas_id].sprite_id.insert(spriteB, i); } } } @@ -352,7 +357,7 @@ int rc_createSprite(int img_id, double w, double h) sprBodyDef.type = b2_dynamicBody; sprBodyDef.position.Set(w/2, h/2); sprBodyDef.angle = 0; - sprBodyDef.userData.pointer = (uintptr_t)&rc_sprite[spr_id]; + sprBodyDef.userData.pointer = spr_id; rc_sprite[spr_id].physics.body = rc_canvas[rc_active_canvas].physics2D.world->CreateBody(&sprBodyDef); b2FixtureDef sprFixtureDef; @@ -386,7 +391,10 @@ int rc_createSprite(int img_id, double w, double h) rc_sprite[spr_id].animation.clear(); rc_createSpriteAnimation(spr_id, 1, 0); - rc_canvas[rc_active_canvas].sprite.push_back(&rc_sprite[spr_id]); + int i = rc_canvas[rc_active_canvas].sprite_id.size(); + rc_canvas[rc_active_canvas].sprite_id.push_back(spr_id); + + //std::cout << "Create Debug: [" << rc_active_canvas << "] index = " << i << " spr_id = " << rc_canvas[rc_active_canvas].sprite[i]->id << std::endl; sortSpriteZ(rc_active_canvas); @@ -412,13 +420,13 @@ void rc_deleteSprite(int spr_id) rc_sprite[spr_id].parent_canvas = -1; rc_sprite[spr_id].animation.clear(); - for(int i = 0; i < rc_canvas[rc_active_canvas].sprite.size(); i++) + for(int i = 0; i < rc_canvas[rc_active_canvas].sprite_id.size(); i++) { - rc_sprite2D_obj* canvas_sprite = rc_canvas[rc_active_canvas].sprite[i]; - rc_sprite2D_obj* global_sprite = &rc_sprite[spr_id]; - if(canvas_sprite == global_sprite) + int canvas_sprite = rc_canvas[rc_active_canvas].sprite_id[i]; + + if(canvas_sprite == spr_id) { - rc_canvas[rc_active_canvas].sprite.erase(i); + rc_canvas[rc_active_canvas].sprite_id.erase(i); break; } } @@ -846,9 +854,11 @@ void drawSprites(int canvas_id) 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++) + for(int spr_index = 0; spr_index < rc_canvas[canvas_id].sprite_id.size(); spr_index++) { - rc_sprite2D_obj* sprite = rc_canvas[canvas_id].sprite[spr_index]; + int spr_id = rc_canvas[canvas_id].sprite_id[spr_index]; + rc_sprite2D_obj* sprite = &rc_sprite[spr_id]; + //std::cout << "debug info: " << canvas_id << " --> " << spr_index << " id = " << sprite->id << " anim_size = " << sprite->animation.size() << std::endl; continue; if(!sprite->visible) continue; diff --git a/rcbasic_runtime/rc_windowclose.h b/rcbasic_runtime/rc_windowclose.h index 65cc851..c040214 100644 --- a/rcbasic_runtime/rc_windowclose.h +++ b/rcbasic_runtime/rc_windowclose.h @@ -1,6 +1,44 @@ #ifndef RC_WINDOWCLOSE_H_INCLUDED #define RC_WINDOWCLOSE_H_INCLUDED +void rc_clearCanvas() +{ + if(rc_active_canvas >= 0 && rc_active_canvas < rc_canvas.size()) + { + if(rc_canvas[rc_active_canvas].texture) + switch(rc_canvas[rc_active_canvas].type) + { + case RC_CANVAS_TYPE_2D: + VideoDriver->clearBuffers(true, true, true, rc_clear_color); + break; + case RC_CANVAS_TYPE_SPRITE: + VideoDriver->clearBuffers(true, true, true, rc_clear_color); + + for(int i = 0; i < rc_joint.size(); i++) + { + if(rc_joint[i].canvas == rc_active_canvas) + { + rc_deleteJoint(i); + } + } + + for(int i = 0; i < rc_sprite.size(); i++) + { + if(rc_sprite[i].parent_canvas == rc_active_canvas) + { + rc_deleteSprite(i); + } + } + + break; + default: + VideoDriver->clearBuffers(true, true, true, rc_clear_color); + break; + } + + } +} + void rc_closeWindow_hw() { irrtheora::stopVideo();