├── graphics ├── retro_image.cpp ├── retro_image.h ├── retro_fx.cpp ├── retro_scene.h ├── retro_texture.h ├── retro_camera.h ├── retro_fx.h ├── retro_light.h ├── retro_camera.cpp └── retro_texture.cpp ├── frontend ├── retro_sound_device.cpp ├── retro_video_device.cpp ├── retro_render_device.cpp ├── retro_device.h ├── retro_sound_device.h ├── retro_input_device.cpp ├── retro_video_device.h ├── retro_input_device.h └── retro_render_device.h ├── ecs ├── systems │ ├── retro_transform_system.cpp │ ├── retro_transform_system.h │ ├── retro_light_system.h │ ├── retro_audio_system.h │ ├── retro_audio_system.cpp │ ├── retro_scene_system.cpp │ ├── retro_render_system.h │ ├── retro_collision_system.h │ ├── retro_scene_system.h │ ├── retro_light_system.cpp │ ├── retro_render_system.cpp │ └── retro_collision_system.cpp ├── entities │ ├── retro_delayedcall.cpp │ ├── retro_tween.cpp │ ├── retro_delayedcall.h │ └── retro_tween.h ├── components │ ├── retro_physics_component.h │ ├── retro_scene_component.h │ ├── retro_transform_component.h │ ├── retro_light_component.h │ ├── retro_transform_component.cpp │ ├── retro_physics_component.cpp │ ├── retro_scene_component.cpp │ ├── retro_timer_component.h │ ├── retro_audio_component.h │ ├── retro_collider_component.h │ ├── retro_light_component.cpp │ ├── retro_collider_component.cpp │ ├── retro_timer_component.cpp │ ├── retro_render_component.h │ ├── retro_audio_component.cpp │ └── retro_render_component.cpp ├── retro_system.cpp ├── retro_component.cpp ├── retro_component.h ├── retro_system.h ├── retro_entity.cpp └── retro_entity.h ├── common ├── md5_old │ ├── LICENSE │ ├── README.md │ ├── md5.h │ └── md5.cpp ├── retro_dynref.cpp ├── retro_assert.h ├── retro_containers.h ├── retro_rand.h ├── retro_rand.cpp ├── retro_factory.h ├── retro_dynref.h ├── retro_assets.h ├── retro_transform.h ├── retro_defs.h ├── retro_transform.cpp └── retro_time.h ├── .gitmodules ├── serial ├── retro_serialize.h ├── retro_serialize.cpp ├── retro_reader.h ├── retro_config.cpp ├── retro_reader.cpp ├── retro_config.h └── retro_import.h ├── backend ├── null_input_device.h ├── sdl_video_device.h ├── null_video_device.h ├── null_sound_device.h ├── sdl_input_device.h ├── sdl_sound_device.h ├── null_render_device.h ├── sdl_video_device.cpp └── sdl_sound_device.cpp ├── LICENSE ├── audio ├── retro_voice.cpp ├── retro_voice.h └── retro_sound.h └── physics ├── retro_physics.h └── retro_collider.h /graphics/retro_image.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_image.h" 2 | -------------------------------------------------------------------------------- /frontend/retro_sound_device.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_sound_device.h" 2 | 3 | retro3d::SoundDevice::~SoundDevice( void ) 4 | {} 5 | -------------------------------------------------------------------------------- /frontend/retro_video_device.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_video_device.h" 2 | 3 | retro3d::VideoDevice::~VideoDevice( void ) 4 | {} 5 | -------------------------------------------------------------------------------- /frontend/retro_render_device.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_render_device.h" 2 | 3 | retro3d::RenderDevice::~RenderDevice( void ) 4 | {} 5 | -------------------------------------------------------------------------------- /ecs/systems/retro_transform_system.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_transform_system.h" 2 | 3 | retro3d::TransformSystem::TransformSystem( void ) : mtlInherit(this) 4 | {} 5 | -------------------------------------------------------------------------------- /common/md5_old/LICENSE: -------------------------------------------------------------------------------- 1 | github.com/SirJonthe 2 | 2019 3 | 4 | PUBLIC DOMAIN 5 | 6 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 7 | IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 8 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 9 | -------------------------------------------------------------------------------- /common/retro_dynref.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_dynref.h" 2 | 3 | retro3d::IDynRef::IDynRef( void ) : m_self_ref(mtlShared< retro3d::IDynRef*>::Create()) 4 | { 5 | *m_self_ref.GetShared() = this; 6 | } 7 | 8 | retro3d::IDynRef::~IDynRef( void ) 9 | { 10 | *m_self_ref.GetShared() = nullptr; 11 | } 12 | -------------------------------------------------------------------------------- /graphics/retro_image.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_IMAGE_H 2 | #define RETRO_IMAGE_H 3 | 4 | #include "../api/tiny3d/tiny_image.h" 5 | 6 | namespace retro3d 7 | { 8 | 9 | class Image 10 | { 11 | private: 12 | tiny3d::Image m_img; 13 | 14 | public: 15 | }; 16 | 17 | } 18 | 19 | #endif // RETRO_IMAGE_H 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "api/tiny3d"] 2 | path = api/tiny3d 3 | url = https://www.github.com/SirJonthe/tiny3d.git 4 | [submodule "common/MiniLib"] 5 | path = common/MiniLib 6 | url = https://www.github.com/SirJonthe/MiniLib.git 7 | [submodule "common/md5"] 8 | path = common/md5 9 | url = https://github.com/SirJonthe/md5.git 10 | -------------------------------------------------------------------------------- /common/retro_assert.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_ASSERT_H 2 | #define RETRO_ASSERT_H 3 | 4 | #include 5 | 6 | #ifdef RETRO3D_ASSERT 7 | #undef RETRO3D_ASSERT 8 | #endif 9 | 10 | #ifdef RETRO3D_DEBUG 11 | #define RETRO3D_ASSERT(x) assert(x) 12 | #else 13 | #define RETRO3D_ASSERT(x) 14 | #endif 15 | 16 | #endif // RETRO_ASSERT_H 17 | -------------------------------------------------------------------------------- /common/md5_old/README.md: -------------------------------------------------------------------------------- 1 | # md5 2 | 3 | ## Description 4 | 5 | A C++ implementation of the MD5 message digest algorithm heavily inspired by the Wikipedia (as per y2019-m10-d01) implementation found at 6 | 7 | https://en.wikipedia.org/wiki/MD5 8 | 9 | ## Note 10 | 11 | I can not vouch for the correctness of the implementation of the algorithm. 12 | 13 | -------------------------------------------------------------------------------- /ecs/systems/retro_transform_system.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_TRANSFORM_SYSTEM_H 2 | #define RETRO_TRANSFORM_SYSTEM_H 3 | 4 | #include "../retro_system.h" 5 | #include "../components/retro_transform_component.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | retro_system(TransformSystem, retro3d::TransformComponent) 11 | { 12 | public: 13 | TransformSystem( void ); 14 | }; 15 | 16 | } 17 | 18 | #endif // RETRO_TRANSFORM_SYSTEM_H 19 | -------------------------------------------------------------------------------- /ecs/entities/retro_delayedcall.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_delayedcall.h" 2 | 3 | void retro3d::DelayedCall::OnUpdate( void ) 4 | { 5 | if (LifeTime(m_timer_type) >= m_time) { 6 | (*m_procedure.GetShared())(); 7 | Destroy(); 8 | } 9 | } 10 | 11 | retro3d::DelayedCall::DelayedCall(const mtlShared &procedure, retro3d::Time time, retro3d::TimerType timer_type) : mtlInherit(this), m_time(time), m_timer_type(timer_type), m_procedure(procedure) 12 | {} 13 | -------------------------------------------------------------------------------- /ecs/entities/retro_tween.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_tween.h" 2 | 3 | retro3d::ITween::ITween( void ) : mtlInherit(this), m_mode(MODE_REL_LERP), m_duration(1_s), m_timer_type(retro3d::TIMER_GAME) 4 | {} 5 | 6 | void retro3d::ITween::SetProperties(retro3d::ITween::Mode mode, retro3d::Time duration, retro3d::TimerType timer_type) 7 | { 8 | m_mode = mode; 9 | m_duration = duration; 10 | m_timer_type = timer_type; 11 | } 12 | 13 | void retro3d::ITween::Cancel( void ) 14 | { 15 | Destroy(); 16 | } 17 | -------------------------------------------------------------------------------- /frontend/retro_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_DEVICE_H 2 | #define RETRO_DEVICE_H 3 | 4 | namespace retro3d 5 | { 6 | 7 | class Engine; 8 | 9 | class Device 10 | { 11 | friend class retro3d::Engine; 12 | 13 | private: 14 | retro3d::Engine *m_engine; 15 | 16 | public: 17 | retro3d::Engine *GetEngine( void ) { return m_engine; } 18 | const retro3d::Engine *GetEngine( void ) const { return m_engine; } 19 | 20 | // Initialize 21 | // Queue job 22 | // Flush queue 23 | }; 24 | 25 | } 26 | 27 | #endif // RETRO_DEVICE_H 28 | -------------------------------------------------------------------------------- /common/retro_containers.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_CONTAINERS_H 2 | #define RETRO_CONTAINERS_H 3 | 4 | #include "../common/MiniLib/MTL/mtlArray.h" 5 | #include "retro_assets.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | template < typename type_t > 11 | class Array : public retro3d::Asset< retro3d::Array >, public mtlArray 12 | {}; 13 | 14 | template < typename type_t > 15 | class Singleton 16 | { 17 | public: 18 | static type_t &Instance( void ) { 19 | static type_t instance; 20 | return instance; 21 | } 22 | }; 23 | 24 | } 25 | 26 | #endif // RETRO_CONTAINERS_H 27 | -------------------------------------------------------------------------------- /ecs/components/retro_physics_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_PHYSICS_COMPONENT_H 2 | #define RETRO_PHYSICS_COMPONENT_H 3 | 4 | #include "../retro_component.h" 5 | #include "../../physics/retro_physics.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | retro_component(PhysicsComponent), public retro3d::PhysicsProperties 11 | { 12 | private: 13 | mmlVector<3> m_gravity_vec; 14 | 15 | protected: 16 | void OnSpawn( void ) override; 17 | void OnUpdate( void ) override; 18 | 19 | public: 20 | PhysicsComponent( void ); 21 | 22 | mmlVector<3> GetGravityVector( void ) const; 23 | void SetGravityVector(const mmlVector<3> &vec); 24 | }; 25 | 26 | } 27 | 28 | #endif // RETRO_PHYSICS_COMPONENT_H 29 | -------------------------------------------------------------------------------- /common/retro_rand.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_RAND_H 2 | #define RETRO_RAND_H 3 | 4 | #include 5 | #include "MiniLib/MML/mmlRandom.h" 6 | #include "MiniLib/MML/mmlVector.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | class Random 12 | { 13 | private: 14 | mmlRandom m_rand; 15 | 16 | public: 17 | Random(uint64_t seed, uint64_t inc = 1); 18 | 19 | int32_t Range(int32_t min, int32_t max); 20 | float Range(float min, float max); 21 | float Unit( void ); 22 | uint32_t Bits( void ); 23 | mmlVector<2> Normal2( void ); 24 | mmlVector<3> Normal3( void ); 25 | mmlVector<2> InCircle( void ); 26 | mmlVector<3> InSphere( void ); 27 | }; 28 | 29 | } 30 | 31 | #endif // RETRO_RAND_H 32 | -------------------------------------------------------------------------------- /ecs/components/retro_scene_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SCENE_COMPONENT_H 2 | #define RETRO_SCENE_COMPONENT_H 3 | 4 | #include "../retro_component.h" 5 | #include "../../graphics/retro_model.h" 6 | #include "../../graphics/retro_light.h" 7 | #include "../../physics/retro_collider_tree.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | retro_component(SceneComponent) 13 | { 14 | private: 15 | // divvied up into sectors 16 | // each sector contains info 17 | // a stage for dynamic game objects 18 | // a stage for static game objects 19 | // a stage for lights 20 | 21 | protected: 22 | void OnSpawn( void ) override; 23 | 24 | public: 25 | SceneComponent( void ); 26 | }; 27 | 28 | } 29 | 30 | #endif // RETRO_SCENE_COMPONENT_H 31 | -------------------------------------------------------------------------------- /serial/retro_serialize.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SERIALIZE_H 2 | #define RETRO_SERIALIZE_H 3 | 4 | #include "../common/MiniLib/MTL/mtlType.h" 5 | #include "../common/MiniLib/MTL/mtlPath.h" 6 | #include "retro_reader.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | class Serializeable : public mtlBase 12 | { 13 | public: 14 | Serializeable( void ); 15 | Serializeable(const Serializeable&); 16 | Serializeable(Serializeable&&); 17 | 18 | Serializeable &operator=(const Serializeable&); 19 | 20 | virtual bool Deserialize(retro3d::Reader &reader); 21 | virtual bool Deserialize(const mtlChars &data); 22 | virtual bool Serialize(const mtlPath &file_name) const; 23 | virtual bool Serialize(mtlString &out_data) const; 24 | }; 25 | 26 | } 27 | 28 | #endif // RETRO_SERIALIZE_H 29 | -------------------------------------------------------------------------------- /graphics/retro_fx.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_fx.h" 2 | 3 | void retro3d::FX_InitFire( void ) {} 4 | void retro3d::FX_SpreadFire(const tiny3d::Color *fire_palette) {} 5 | 6 | void retro3d::FX_Desaturate(tiny3d::Image &img, const tiny3d::URect *dst_rect) 7 | { 8 | tiny3d::URect fs_rect = tiny3d::URect{ tiny3d::UPoint{ 0, 0 }, tiny3d::UPoint{ img.GetWidth(), img.GetHeight() } }; 9 | tiny3d::URect rect = dst_rect != nullptr ? tiny3d::Clip(*dst_rect, fs_rect) : fs_rect; 10 | 11 | for (tiny3d::UInt y = rect.a.y; y < rect.b.y; ++y) { 12 | for (tiny3d::UInt x = rect.a.x; x < rect.b.x; ++x) { 13 | tiny3d::UPoint p = { x, y }; 14 | tiny3d::Color c = img.GetColor(p); 15 | tiny3d::Byte i = tiny3d::Illum(c); 16 | c = { i, i, i, c.blend }; 17 | img.SetColor(p, c); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ecs/entities/retro_delayedcall.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_DELAYEDCALL_H 2 | #define RETRO_DELAYEDCALL_H 3 | 4 | #include "../retro_entity.h" 5 | #include "../../common/retro_defs.h" 6 | #include "../../common/retro_time.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | class DelayedCall : public mtlInherit< retro3d::Entity, DelayedCall > 12 | { 13 | private: 14 | retro3d::Time m_time; 15 | retro3d::TimerType m_timer_type; 16 | mtlShared m_procedure; 17 | 18 | protected: 19 | virtual void OnUpdate( void ); 20 | 21 | public: 22 | DelayedCall( void ) = delete; 23 | DelayedCall(const mtlShared &procedure, retro3d::Time time, retro3d::TimerType timer_type = retro3d::TIMER_REAL); 24 | }; 25 | 26 | } 27 | 28 | #endif // RETRO_DELAYEDCALL_H 29 | -------------------------------------------------------------------------------- /ecs/systems/retro_light_system.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_LIGHT_SYSTEM_H 2 | #define RETRO_LIGHT_SYSTEM_H 3 | 4 | #include "../retro_system.h" 5 | #include "../components/retro_light_component.h" 6 | #include "../../physics/retro_collider_tree.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | retro_system(LightSystem, retro3d::LightComponent) 12 | { 13 | private: 14 | retro3d::ColliderTree m_light_tree; 15 | 16 | protected: 17 | void OnSpawn(retro3d::LightComponent &c) override; 18 | void OnUpdate(retro3d::LightComponent &c) override; 19 | void OnDestroy(retro3d::LightComponent &c) override; 20 | 21 | public: 22 | LightSystem( void ); 23 | 24 | void Debug_PrintTree( void ) const; 25 | void Debug_RenderTree( void ); 26 | 27 | void UpdateLightmap( void ); 28 | }; 29 | 30 | } 31 | 32 | #endif // RETRO_LIGHT_SYSTEM_H 33 | -------------------------------------------------------------------------------- /ecs/systems/retro_audio_system.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_AUDIO_SYSTEM_H 2 | #define RETRO_AUDIO_SYSTEM_H 3 | 4 | #include "../retro_system.h" 5 | #include "../components/retro_audio_component.h" 6 | #include "../../physics/retro_collider_tree.h" 7 | #include "../../common/retro_transform.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | retro_system(AudioSystem, retro3d::AudioComponent) 13 | { 14 | private: 15 | retro3d::ColliderTree m_sound_stage; 16 | mtlList< retro3d::AudioComponent* > m_components; // TODO: use a faster data structure for insert, remove 17 | 18 | protected: 19 | void OnSpawn(retro3d::AudioComponent &c); 20 | void OnDestroy(retro3d::AudioComponent &c); 21 | void OnUpdate( void ); 22 | 23 | public: 24 | AudioSystem( void ); 25 | }; 26 | 27 | } 28 | 29 | #endif // RETRO_AUDIO_SYSTEM_H 30 | -------------------------------------------------------------------------------- /serial/retro_serialize.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_serialize.h" 2 | 3 | retro3d::Serializeable::Serializeable( void ) : mtlBase(this) 4 | {} 5 | 6 | retro3d::Serializeable::Serializeable(const Serializeable&) : mtlBase(this) 7 | {} 8 | 9 | retro3d::Serializeable::Serializeable(Serializeable&&) : mtlBase(this) 10 | {} 11 | 12 | retro3d::Serializeable &retro3d::Serializeable::operator=(const retro3d::Serializeable&) 13 | { 14 | return *this; 15 | } 16 | 17 | bool retro3d::Serializeable::Deserialize(retro3d::Reader&) 18 | { 19 | return false; 20 | } 21 | 22 | bool retro3d::Serializeable::Deserialize(const mtlChars &data) 23 | { 24 | return false; 25 | } 26 | 27 | bool retro3d::Serializeable::Serialize(const mtlPath&) const 28 | { 29 | return false; 30 | } 31 | 32 | bool retro3d::Serializeable::Serialize(mtlString &out_data) const 33 | { 34 | return false; 35 | } 36 | -------------------------------------------------------------------------------- /ecs/components/retro_transform_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO3D_TRANSFORM_COMPONENT_H 2 | #define RETRO3D_TRANSFORM_COMPONENT_H 3 | 4 | #include "../../common/MiniLib/MTL/mtlPointer.h" 5 | #include "../../common/retro_transform.h" 6 | #include "../../physics/retro_collider.h" 7 | #include "../retro_component.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | retro_component(TransformComponent) 13 | { 14 | private: 15 | retro3d::SharedTransform m_transform; 16 | retro3d::Transform m_old_transform; // or should we store next_transform? 17 | 18 | protected: 19 | void OnUpdate( void ); 20 | 21 | public: 22 | TransformComponent( void ); 23 | 24 | const retro3d::SharedTransform GetTransform( void ) const; 25 | retro3d::SharedTransform GetTransform( void ); 26 | 27 | mmlVector<3> GetLastMove( void ) const; 28 | retro3d::Transform GetLastTransform( void ) const; 29 | }; 30 | 31 | } 32 | 33 | #endif // RETRO3D_TRANSFORM_COMPONENT_H 34 | -------------------------------------------------------------------------------- /ecs/components/retro_light_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_LIGHT_COMPONENT_H 2 | #define RETRO_LIGHT_COMPONENT_H 3 | 4 | #include "../../graphics/retro_light.h" 5 | #include "../retro_component.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | retro_component(LightComponent), private retro3d::Light 11 | { 12 | private: 13 | retro3d::AABBCollider m_collider; 14 | bool m_is_static; 15 | bool m_reinsert; 16 | uint64_t m_filter_flags; 17 | 18 | protected: 19 | void OnSpawn( void ) override; 20 | 21 | public: 22 | LightComponent( void ); 23 | 24 | bool IsStatic( void ) const; 25 | void ToggleStatic( void ); 26 | 27 | uint64_t GetFilterFlags( void ) const; 28 | void SetFilterFlags(uint64_t filter_flags); 29 | 30 | bool ShouldReinsert( void ) const; 31 | void ToggleReinsert( void ); 32 | 33 | retro3d::AABBCollider &GetActivationBounds( void ); 34 | }; 35 | 36 | } 37 | 38 | #endif // RETRO_LIGHT_COMPONENT_H 39 | -------------------------------------------------------------------------------- /backend/null_input_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_NULL_INPUT_H 2 | #define RETRO_NULL_INPUT_H 3 | 4 | #include "../frontend/retro_input_device.h" 5 | 6 | namespace platform 7 | { 8 | 9 | class NullInputDevice : public retro3d::InputDevice 10 | { 11 | public: 12 | bool Init( void ) override { return true; } 13 | 14 | bool UserQuit( void ) const override { return false; } 15 | uint64_t GetRealTimeMS( void ) const override { return 0; } 16 | uint64_t GetProgramTimeMS( void ) const override { return 0; } 17 | void Sleep(retro3d::Time) const override { return; } 18 | void ToggleMouseCursorLock( void ) override { return; } 19 | bool IsMouseCursorLocked( void ) const override { return false; } 20 | void ToggleMouseCursorVisibility( void ) override { return; } 21 | bool IsMouseCursorVisible( void ) const override { return false; } 22 | void Update( void ) override { return; } 23 | }; 24 | 25 | } 26 | 27 | #endif // RETRO_NULL_INPUT_H 28 | -------------------------------------------------------------------------------- /ecs/components/retro_transform_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_transform_component.h" 2 | 3 | namespace retro3d { retro_register_component(TransformComponent) } 4 | 5 | void retro3d::TransformComponent::OnUpdate( void ) 6 | { 7 | m_old_transform = m_transform->GetFinalMatrix(); 8 | } 9 | 10 | retro3d::TransformComponent::TransformComponent( void ) : mtlInherit(this), m_old_transform() 11 | { 12 | m_transform.New(); 13 | } 14 | 15 | const retro3d::SharedTransform retro3d::TransformComponent::GetTransform( void ) const 16 | { 17 | return m_transform; 18 | } 19 | 20 | retro3d::SharedTransform retro3d::TransformComponent::GetTransform( void ) 21 | { 22 | return m_transform; 23 | } 24 | 25 | mmlVector<3> retro3d::TransformComponent::GetLastMove( void ) const 26 | { 27 | return m_transform->GetPosition() - m_old_transform.GetPosition(); 28 | } 29 | 30 | retro3d::Transform retro3d::TransformComponent::GetLastTransform( void ) const 31 | { 32 | return m_old_transform; 33 | } 34 | -------------------------------------------------------------------------------- /backend/sdl_video_device.h: -------------------------------------------------------------------------------- 1 | #ifndef SDL_VIDEO_DEVICE_H 2 | #define SDL_VIDEO_DEVICE_H 3 | 4 | #include "../frontend/retro_video_device.h" 5 | 6 | namespace platform 7 | { 8 | 9 | class SDLVideoDevice : public retro3d::VideoDevice 10 | { 11 | public: 12 | ~SDLVideoDevice( void ); 13 | 14 | bool Init( void ) override; 15 | bool CreateWindow(uint32_t width, uint32_t height, bool enable_fullscreen) override; 16 | void SetWindowCaption(const std::string &caption) override; 17 | void DestroyWindow( void ) override; 18 | void FromImage(const tiny3d::Image &src, const retro3d::URect &dst_rect) override; 19 | void Display(const retro3d::Rect &rect) override; 20 | void Display( void ) override; 21 | retro3d::Point GetWindowPosition( void ) const override; 22 | uint32_t GetWindowWidth( void ) const override; 23 | uint32_t GetWindowHeight( void ) const override; 24 | std::string GetWindowCaption( void ) const override; 25 | }; 26 | 27 | } 28 | 29 | #endif // SDL_VIDEO_DEVICE_H 30 | -------------------------------------------------------------------------------- /ecs/retro_system.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_system.h" 2 | #include "../common/MiniLib/MML/mmlMath.h" 3 | 4 | retro3d::ISystem::ISystem( void ) : 5 | mtlBase(this), 6 | m_is_active(1), m_should_destroy(false) 7 | {} 8 | 9 | retro3d::ISystem::~ISystem( void ) 10 | {} 11 | 12 | void retro3d::ISystem::Destroy( void ) 13 | { 14 | m_should_destroy = true; 15 | } 16 | 17 | bool retro3d::ISystem::IsDestroyed( void ) const 18 | { 19 | return m_should_destroy; 20 | } 21 | 22 | bool retro3d::ISystem::IsActive( void ) const 23 | { 24 | return IsDestroyed() == false && m_is_active > 0; 25 | } 26 | 27 | void retro3d::ISystem::Deactivate( void ) 28 | { 29 | --m_is_active; 30 | } 31 | 32 | void retro3d::ISystem::Activate( void ) 33 | { 34 | m_is_active = mmlMin(1, m_is_active + 1); 35 | } 36 | 37 | retro3d::Engine *retro3d::ISystem::GetEngine( void ) 38 | { 39 | return m_engine; 40 | } 41 | 42 | const retro3d::Engine *retro3d::ISystem::GetEngine( void ) const 43 | { 44 | return m_engine; 45 | } 46 | -------------------------------------------------------------------------------- /backend/null_video_device.h: -------------------------------------------------------------------------------- 1 | #ifndef NULL_VIDEO_DEVICE_H 2 | #define NULL_VIDEO_DEVICE_H 3 | 4 | #include "../frontend/retro_video_device.h" 5 | 6 | namespace platform 7 | { 8 | 9 | class NullVideoDevice : public retro3d::VideoDevice 10 | { 11 | public: 12 | ~NullVideoDevice( void ) {} 13 | 14 | bool Init( void ) override { return true; } 15 | bool CreateWindow(uint32_t, uint32_t, bool) override { return true; } 16 | void SetWindowCaption(const std::string&) override {} 17 | void DestroyWindow( void ) override {} 18 | virtual void FromImage(const tiny3d::Image&, const retro3d::URect&) override {} 19 | void Display(const retro3d::Rect&) override {} 20 | void Display( void ) override {} 21 | retro3d::Point GetWindowPosition( void ) const override { return retro3d::Point{ 0, 0 }; } 22 | uint32_t GetWindowWidth( void ) const override { return 0; } 23 | uint32_t GetWindowHeight( void ) const override { return 0; } 24 | std::string GetWindowCaption( void ) const override { return ""; } 25 | }; 26 | 27 | } 28 | 29 | #endif // NULL_VIDEO_DEVICE_H 30 | -------------------------------------------------------------------------------- /ecs/components/retro_physics_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_physics_component.h" 2 | #include "../retro_entity.h" 3 | #include "retro_transform_component.h" 4 | 5 | namespace retro3d { retro_register_component(PhysicsComponent) } 6 | 7 | void retro3d::PhysicsComponent::OnSpawn( void ) 8 | { 9 | AttachTransform(GetObject()->AddComponent()->GetTransform()); 10 | } 11 | 12 | void retro3d::PhysicsComponent::OnUpdate( void ) 13 | { 14 | float delta_time = float(GetObject()->DeltaTime()); 15 | StepSimulation(delta_time); 16 | ApplyLinearImpulse(m_gravity_vec * delta_time); 17 | } 18 | 19 | retro3d::PhysicsComponent::PhysicsComponent( void ) : mtlInherit(this), m_gravity_vec() 20 | { 21 | m_gravity_vec[0] = 0.0f; 22 | m_gravity_vec[1] = -9.8f; 23 | m_gravity_vec[2] = 0.0f; 24 | } 25 | 26 | mmlVector<3> retro3d::PhysicsComponent::GetGravityVector( void ) const 27 | { 28 | return m_gravity_vec; 29 | } 30 | 31 | void retro3d::PhysicsComponent::SetGravityVector(const mmlVector<3> &vec) 32 | { 33 | m_gravity_vec = vec; 34 | } 35 | -------------------------------------------------------------------------------- /ecs/components/retro_scene_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_scene_component.h" 2 | #include "retro_render_component.h" 3 | #include "../retro_entity.h" 4 | 5 | namespace retro3d { retro_register_component(SceneComponent) } 6 | 7 | retro_component(C_SceneConstructor) 8 | { 9 | // object that waits for a render component to be added to the object so that sectoring can be done 10 | protected: 11 | void OnUpdate( void ) override { 12 | auto *r = GetObject()->GetComponent(); 13 | if (r != nullptr && r->GetModel().IsNull() == false) { 14 | // TODO: Do work 15 | Destroy(); // NOTE: Remove component. 16 | } 17 | } 18 | 19 | public: 20 | C_SceneConstructor( void ) : mtlInherit(this) {} 21 | }; 22 | 23 | void retro3d::SceneComponent::OnSpawn( void ) 24 | { 25 | auto *r = GetObject()->GetComponent(); 26 | if (r == nullptr || r->GetModel().IsNull()) { 27 | GetObject()->AddComponent(); 28 | } 29 | } 30 | 31 | retro3d::SceneComponent::SceneComponent( void ) : mtlInherit(this) 32 | {} 33 | -------------------------------------------------------------------------------- /ecs/systems/retro_audio_system.cpp: -------------------------------------------------------------------------------- 1 | #include "../../retro3d.h" 2 | #include "retro_audio_system.h" 3 | #include "../components/retro_transform_component.h" 4 | 5 | 6 | void retro3d::AudioSystem::OnSpawn(retro3d::AudioComponent &c) 7 | { 8 | // Add to sound_stage 9 | m_components.AddLast(&c); 10 | } 11 | 12 | void retro3d::AudioSystem::OnDestroy(retro3d::AudioComponent &c) 13 | { 14 | // Remove from sound_stage 15 | mtlItem *i = m_components.GetFirst(); 16 | while (i != nullptr) { // TODO: Find a better solution to O(n) for this 17 | if (i->GetItem() == &c) { 18 | i = i->Remove(); 19 | break; 20 | } else { 21 | i = i->GetNext(); 22 | } 23 | } 24 | } 25 | 26 | void retro3d::AudioSystem::OnUpdate( void ) 27 | { 28 | // TODO: Support arbitrary sound receiver transform (not just camera transform) 29 | GetEngine()->GetSoundDevice()->SetReceiverTransform(GetEngine()->GetCamera()->GetTransform()); 30 | GetEngine()->GetSoundDevice()->Update(); 31 | } 32 | 33 | retro3d::AudioSystem::AudioSystem( void ) : mtlInherit(this), m_sound_stage() 34 | {} 35 | -------------------------------------------------------------------------------- /backend/null_sound_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_NULL_SOUND_H 2 | #define RETRO_NULL_SOUND_H 3 | 4 | #include "../frontend/retro_sound_device.h" 5 | 6 | namespace platform 7 | { 8 | 9 | class NullSoundDevice : public retro3d::SoundDevice 10 | { 11 | public: 12 | bool Init(const retro3d::Sound::Format&) override { return true; } 13 | 14 | void SetReceiverTransform(const retro3d::SharedTransform&) override {} 15 | void SetReceiverTransform(const retro3d::Transform&) override {} 16 | 17 | retro3d::Transform GetReceiverTransform( void ) const override { return mmlMatrix<4,4>::Identity(); } 18 | retro3d::Sound::Format GetFormat( void ) const override { return retro3d::Sound::Format{ retro3d::Sound::Channels_Mono, 22050, retro3d::Sound::SampleFormat_UINT8 }; } 19 | 20 | int32_t Play(const retro3d::Voice &, const retro3d::SharedTransform &, double) override { return -1; } 21 | int32_t Play(const retro3d::Voice &, const retro3d::Transform &, double) override { return -1; } 22 | void Kill(int32_t) override {} 23 | 24 | void Update( void ) override {} 25 | }; 26 | 27 | } 28 | 29 | #endif // RETRO_NULL_SOUND_H 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jonathan Karlsson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ecs/components/retro_timer_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_TIMER_COMPONENT_H 2 | #define RETRO_TIMER_COMPONENT_H 3 | 4 | #include "../retro_entity.h" 5 | #include "../../common/retro_defs.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | retro_component(TimerComponent) 11 | { 12 | private: 13 | retro3d::RealTimeTimer m_timer; 14 | int64_t m_tick_count; 15 | mtlShared m_on_tick; 16 | mtlShared m_on_destroy; 17 | bool m_multitick; 18 | 19 | protected: 20 | void OnSpawn( void ); 21 | void OnUpdate( void ); 22 | void OnDestroy( void ); 23 | 24 | public: 25 | TimerComponent( void ); 26 | 27 | void SetTickRate(retro3d::TimerType timer_type, uint32_t num_ticks, retro3d::Time over_time = 1_s); 28 | 29 | void Start( void ); 30 | void Pause( void ); 31 | void Reset( void ); 32 | 33 | void SetOnTick(const mtlShared &procedure); 34 | void DisableOnTick( void ); 35 | 36 | void SetOnDestroy(const mtlShared &procedure); 37 | void DisableOnDestroy( void ); 38 | }; 39 | 40 | } 41 | 42 | #endif // RETRO_TIMER_COMPONENT_H 43 | -------------------------------------------------------------------------------- /backend/sdl_input_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SDL_INPUT_H 2 | #define RETRO_SDL_INPUT_H 3 | 4 | #include "../frontend/retro_input_device.h" 5 | 6 | namespace platform 7 | { 8 | 9 | class SDLInputDevice : public retro3d::InputDevice 10 | { 11 | private: 12 | uint64_t m_last_update; 13 | int32_t m_mouse_correction_x, m_mouse_correction_y; 14 | bool m_mouse_locked; 15 | bool m_mouse_visible; 16 | bool m_user_quit; 17 | 18 | private: 19 | void UpdateState(retro3d::InputDevice::Input &internal_state, float api_state, double delta_time); 20 | 21 | public: 22 | SDLInputDevice( void ); 23 | ~SDLInputDevice( void ) override; 24 | 25 | bool Init( void ) override; 26 | 27 | bool UserQuit( void ) const override; 28 | uint64_t GetRealTimeMS( void ) const override; 29 | uint64_t GetProgramTimeMS( void ) const override; 30 | void Sleep(retro3d::Time time) const override; 31 | void ToggleMouseCursorLock( void ) override; 32 | bool IsMouseCursorLocked( void ) const override; 33 | void ToggleMouseCursorVisibility( void ) override; 34 | bool IsMouseCursorVisible( void ) const override; 35 | void Update( void ) override; 36 | }; 37 | 38 | } 39 | 40 | #endif // RETRO_SDL_INPUT_H 41 | -------------------------------------------------------------------------------- /frontend/retro_sound_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SOUND_DEVICE_H 2 | #define RETRO_SOUND_DEVICE_H 3 | 4 | #include 5 | #include "retro_device.h" 6 | #include "../audio/retro_voice.h" 7 | #include "../graphics/retro_camera.h" 8 | #include "../common/retro_transform.h" 9 | 10 | namespace retro3d 11 | { 12 | 13 | class SoundDevice : public retro3d::Device 14 | { 15 | public: 16 | virtual ~SoundDevice( void ); 17 | 18 | virtual bool Init(const retro3d::Sound::Format &format) = 0; 19 | 20 | virtual void SetReceiverTransform(const retro3d::SharedTransform &world_transform) = 0; 21 | virtual void SetReceiverTransform(const retro3d::Transform &world_transform) = 0; 22 | 23 | virtual retro3d::Transform GetReceiverTransform( void ) const = 0; 24 | virtual retro3d::Sound::Format GetFormat( void ) const = 0; 25 | 26 | virtual int32_t Play(const retro3d::Voice &voice, const retro3d::SharedTransform &world_transform, double time_stamp = 0.0) = 0; 27 | virtual int32_t Play(const retro3d::Voice &voice, const retro3d::Transform &world_transform, double time_stamp = 0.0) = 0; 28 | virtual void Kill(int32_t audio_index) = 0; 29 | 30 | virtual void Update( void ) = 0; 31 | }; 32 | 33 | } 34 | 35 | #endif // RETRO_SOUND_DEVICE_H 36 | -------------------------------------------------------------------------------- /common/retro_rand.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_rand.h" 2 | 3 | retro3d::Random::Random(uint64_t seed, uint64_t inc) : m_rand(seed, inc) 4 | {} 5 | 6 | int32_t retro3d::Random::Range(int32_t min, int32_t max) 7 | { 8 | return m_rand.GetInt(min, max); 9 | } 10 | 11 | float retro3d::Random::Range(float min, float max) 12 | { 13 | return m_rand.GetFloat(min, max); 14 | } 15 | 16 | float retro3d::Random::Unit( void ) 17 | { 18 | return m_rand.GetFloat(); 19 | } 20 | 21 | uint32_t retro3d::Random::Bits( void ) 22 | { 23 | return m_rand.GetUint(); 24 | } 25 | 26 | mmlVector<2> retro3d::Random::Normal2( void ) 27 | { 28 | const float a = Range(0.0f, mmlTAU); 29 | mmlVector<2> v; 30 | v[0] = mmlCos(a); 31 | v[1] = mmlSin(a); 32 | return v; 33 | } 34 | 35 | mmlVector<3> retro3d::Random::Normal3( void ) 36 | { 37 | const float a = Range(0.0f, mmlTAU); 38 | const float b = Range(0.0f, mmlTAU); 39 | mmlVector<3> v; 40 | v[0] = mmlSin(b) * mmlCos(a); 41 | v[1] = mmlSin(b) * mmlSin(a); 42 | v[2] = mmlCos(b); 43 | return v; 44 | } 45 | 46 | mmlVector<2> retro3d::Random::InCircle( void ) 47 | { 48 | return Normal2() * Range(-1.0f, 1.0f); 49 | } 50 | 51 | mmlVector<3> retro3d::Random::InSphere( void ) 52 | { 53 | return Normal3() * Range(-1.0f, 1.0f); 54 | } 55 | -------------------------------------------------------------------------------- /frontend/retro_input_device.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_input_device.h" 2 | 3 | void retro3d::InputMap::Bind(const mtlChars &action, uint64_t input_code) 4 | { 5 | *m_binds.CreateEntry(action) = input_code; 6 | } 7 | 8 | void retro3d::InputMap::Unbind(const mtlChars &action) 9 | { 10 | m_binds.RemoveEntry(action); 11 | } 12 | 13 | void retro3d::InputMap::UnbindAll( void ) 14 | { 15 | m_binds.RemoveAll(); 16 | } 17 | 18 | const uint64_t *retro3d::InputMap::GetInput(const mtlChars &action) const 19 | { 20 | return m_binds.GetEntry(action); 21 | } 22 | 23 | void retro3d::InputDevice::CreateStateTable(uint64_t size) 24 | { 25 | m_state.Create(int(size)); 26 | for (int i = 0; i < m_state.GetSize(); ++i) { 27 | m_state[i] = Input{ 0.0f, 0.0f, 0.0, false }; 28 | } 29 | } 30 | 31 | retro3d::InputDevice::InputDevice( void ) : m_binds(nullptr) 32 | {} 33 | 34 | retro3d::InputDevice::~InputDevice( void ) 35 | { 36 | m_state.Free(); 37 | } 38 | 39 | void retro3d::InputDevice::SetInputMap(const InputMap *binds) 40 | { 41 | m_binds = binds; 42 | } 43 | 44 | retro3d::InputDevice::Input retro3d::InputDevice::GetState(const mtlChars &action) const 45 | { 46 | const uint64_t *lookup = m_binds != nullptr ? m_binds->GetInput(action) : nullptr; 47 | return lookup != nullptr ? m_state[*lookup] : Input{ 0.0f, 0.0f, 0.0, false }; 48 | } 49 | -------------------------------------------------------------------------------- /serial/retro_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_READER_H 2 | #define RETRO_READER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace retro3d 9 | { 10 | 11 | class Reader 12 | { 13 | private: 14 | std::istream *m_in; 15 | std::string m_file; 16 | std::string m_path; 17 | bool m_is_open; 18 | 19 | private: 20 | void UpdatePath(const std::string &file); 21 | 22 | public: 23 | Reader( void ); 24 | ~Reader( void ); 25 | 26 | bool ReadFromFile(const std::string &file); 27 | void ReadFromMemory(const char *buf, uint64_t byte_count, const std::string &virtual_file = ""); 28 | void Close( void ); 29 | 30 | void SkipTo(uint64_t byte_loc); 31 | uint64_t ReadBin(char *out, uint64_t byte_count); 32 | bool ReadLine(std::string &out); 33 | bool ReadWord(std::string &out); 34 | bool ReadChar(char &out); 35 | template < typename type_t > 36 | bool Read(type_t &out); 37 | 38 | bool IsOpen( void ) const; 39 | bool IsEnd( void ) const; 40 | 41 | const std::string &GetFile( void ) const; 42 | const std::string &GetPath( void ) const; 43 | }; 44 | 45 | } 46 | 47 | template < typename type_t > 48 | bool retro3d::Reader::Read(type_t &out) 49 | { 50 | if (m_in == nullptr) { return false; } 51 | return ((*m_in) >> out) ? true : false; 52 | } 53 | 54 | #endif // RETRO_READER_H 55 | -------------------------------------------------------------------------------- /ecs/systems/retro_scene_system.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_scene_system.h" 2 | 3 | void retro3d::SceneSystem::OnSpawn(retro3d::SceneComponent &scene) 4 | { 5 | ++m_num_scenes; 6 | if (m_num_scenes > 1) { 7 | std::cout << "[Warning] Multiple SceneComponents in SceneSystem." << std::endl; 8 | } 9 | if (m_current_scene == nullptr) { 10 | m_current_scene = &scene; 11 | 12 | // TODO: split geometry into sectors 13 | // Idea: 14 | // Generate a convex hull (C) based on the input hull (I) 15 | // If there are points that are not included on C (i.e. points inside C) do: 16 | // >= 3 points inside C: use 3 points to generate a splitting plane and split I (or maybe C?). 17 | // < 3 points inside C: use available points inside C and together point(s) on C to generate splitting plane and split I (or maybe C?) 18 | // Apply algorithm recursively to the two new parts of I. 19 | } 20 | } 21 | 22 | void retro3d::SceneSystem::OnUpdate(retro3d::SceneComponent &scene) 23 | { 24 | if (m_current_scene == nullptr) { 25 | m_current_scene = &scene; 26 | } 27 | } 28 | 29 | void retro3d::SceneSystem::OnDestroy(retro3d::SceneComponent &scene) 30 | { 31 | --m_num_scenes; 32 | if (m_current_scene == &scene) { 33 | m_current_scene = nullptr; 34 | } 35 | } 36 | 37 | retro3d::SceneSystem::SceneSystem( void ) : mtlInherit(this), m_current_scene(nullptr), m_num_scenes(0) 38 | {} 39 | -------------------------------------------------------------------------------- /ecs/components/retro_audio_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_AUDIO_COMPONENT_H 2 | #define RETRO_AUDIO_COMPONENT_H 3 | 4 | #include "../retro_component.h" 5 | #include "../../audio/retro_voice.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | retro_component(AudioComponent) 11 | { 12 | private: 13 | retro3d::Voice m_voice; 14 | double m_time_stamp; 15 | mtlShared< retro3d::Sound > m_synthed; // TODO: the synthesized piece of sound to be played (we can do frequency manipulation) 16 | int32_t m_audio_index; 17 | int32_t m_loops; 18 | bool m_playing; 19 | bool m_moving_emitter; 20 | 21 | protected: 22 | void OnUpdate( void ) override; 23 | void OnDestroy( void ) override; 24 | 25 | private: 26 | void SetAudioIndex(int32_t audio_index); 27 | int32_t GetAudioIndex( void ) const; 28 | void Unlock( void ); 29 | bool IsLocked( void ) const; 30 | 31 | public: 32 | AudioComponent( void ); 33 | 34 | void Play(int32_t times = 1); 35 | void Reset(double to_time = 0.0); 36 | void Pause( void ); 37 | void Stop( void ); 38 | 39 | bool IsPlaying( void ) const; 40 | 41 | retro3d::Voice &GetVoice( void ); 42 | const retro3d::Voice &GetVoice( void ) const; 43 | 44 | bool IsMovingEmitter( void ) const; 45 | void ToggleMovingEmitter( void ); 46 | }; 47 | 48 | } 49 | 50 | #endif // RETRO_AUDIO_COMPONENT_H 51 | -------------------------------------------------------------------------------- /ecs/components/retro_collider_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO3D_COLLIDER_COMPONENT_H 2 | #define RETRO3D_COLLIDER_COMPONENT_H 3 | 4 | #include "../../physics/retro_collider.h" 5 | #include "../retro_component.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | retro_component(ColliderComponent) 11 | { 12 | private: 13 | mtlShared m_collider; 14 | uint64_t m_filter_flags; 15 | bool m_is_static; 16 | bool m_reinsert; 17 | 18 | protected: 19 | void OnSpawn( void ); 20 | 21 | public: 22 | ColliderComponent( void ); 23 | 24 | Collider &GetCollider( void ); 25 | const Collider &GetCollider( void ) const; 26 | template < typename collider_t > 27 | collider_t *CreateCollider( void ); 28 | 29 | uint64_t GetFilterFlags( void ) const; 30 | bool GetFilterFlag(uint32_t flag_index) const; 31 | void SetFilterFlags(uint64_t filter_flags); 32 | void SetFilterFlag(uint32_t flag_index, bool state); 33 | 34 | bool IsStatic( void ) const; 35 | void ToggleStatic( void ); 36 | 37 | bool ShouldReinsert( void ) const; 38 | void ToggleReinsert( void ); 39 | }; 40 | 41 | } 42 | 43 | template < typename collider_t > 44 | collider_t *retro3d::ColliderComponent::CreateCollider( void ) 45 | { 46 | mtlShared n = mtlShared::Create(); 47 | m_collider = n; 48 | m_reinsert = true; 49 | return n.GetShared(); 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /ecs/components/retro_light_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_light_component.h" 2 | #include "retro_transform_component.h" 3 | #include "../retro_entity.h" 4 | 5 | namespace retro3d { retro_register_component(LightComponent) } 6 | 7 | void retro3d::LightComponent::OnSpawn( void ) 8 | { 9 | m_collider.AttachTransform(GetObject()->AddComponent()->GetTransform()); 10 | m_collider.SetLocalAABB(retro3d::AABB(mmlVector<3>::Fill(0.0f), mmlVector<3>::Fill(radius))); 11 | } 12 | 13 | retro3d::LightComponent::LightComponent( void ) : mtlInherit(this), Light(), m_is_static(true), m_reinsert(false), m_filter_flags(~uint64_t(0)) 14 | {} 15 | 16 | uint64_t retro3d::LightComponent::GetFilterFlags( void ) const 17 | { 18 | return m_filter_flags; 19 | } 20 | 21 | void retro3d::LightComponent::SetFilterFlags(uint64_t filter_flags) 22 | { 23 | m_filter_flags = filter_flags; 24 | } 25 | 26 | bool retro3d::LightComponent::IsStatic( void ) const 27 | { 28 | return m_is_static; 29 | } 30 | 31 | void retro3d::LightComponent::ToggleStatic( void ) 32 | { 33 | m_is_static = !m_is_static; 34 | } 35 | 36 | bool retro3d::LightComponent::ShouldReinsert( void ) const 37 | { 38 | return m_reinsert; 39 | } 40 | 41 | void retro3d::LightComponent::ToggleReinsert( void ) 42 | { 43 | m_reinsert = !m_reinsert; 44 | } 45 | 46 | retro3d::AABBCollider &retro3d::LightComponent::GetActivationBounds( void ) 47 | { 48 | return m_collider; 49 | } 50 | -------------------------------------------------------------------------------- /common/retro_factory.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_FACTORY_H 2 | #define RETRO_FACTORY_H 3 | 4 | #include 5 | #include "MiniLib/MTL/mtlStringMap.h" 6 | #include "retro_defs.h" 7 | #include "retro_assert.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | template < typename type_t > 13 | class Factory 14 | { 15 | private: 16 | mtlStringMap< retro3d::Schematic< type_t* > > m_schematics; 17 | 18 | public: 19 | bool AddSchematic(const std::string &name, retro3d::Schematic< type_t* > schematic); 20 | type_t *Assemble(const std::string &name) const; 21 | }; 22 | 23 | } 24 | 25 | template < typename type_t > 26 | bool retro3d::Factory::AddSchematic(const std::string &name, retro3d::Schematic< type_t* > schematic) 27 | { 28 | const mtlChars chars = mtlChars::FromDynamic(name.c_str(), int(name.size())); 29 | retro3d::Schematic< type_t* > *entry = m_schematics.GetEntry(chars); 30 | 31 | RETRO3D_ASSERT(entry == nullptr); 32 | 33 | if (entry != nullptr) { return false; } 34 | 35 | entry = m_schematics.CreateEntry(chars); 36 | *entry = schematic; 37 | 38 | return true; 39 | } 40 | 41 | template < typename type_t > 42 | type_t *retro3d::Factory::Assemble(const std::string &name) const 43 | { 44 | const mtlChars chars = mtlChars::FromDynamic(name.c_str(), int(name.size())); 45 | const retro3d::Schematic *entry = m_schematics.GetEntry(chars); 46 | return entry != nullptr ? (*entry)() : nullptr; 47 | } 48 | 49 | #endif // RETRO_FACTORY_H 50 | -------------------------------------------------------------------------------- /audio/retro_voice.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_voice.h" 2 | 3 | retro3d::Voice::Voice( void ) : m_sound(), m_range_radius(50.0f), m_volume(1.0f), m_pitch(1.0f), m_playback_speed(1.0f), m_type(retro3d::Voice::Point) 4 | {} 5 | 6 | mtlShared retro3d::Voice::GetSound( void ) const 7 | { 8 | return m_sound; 9 | } 10 | 11 | float retro3d::Voice::GetRangeRadius( void ) const 12 | { 13 | return m_range_radius; 14 | } 15 | 16 | float retro3d::Voice::GetVolume( void ) const 17 | { 18 | return m_volume; 19 | } 20 | 21 | float retro3d::Voice::GetPitch( void ) const 22 | { 23 | return m_pitch; 24 | } 25 | 26 | float retro3d::Voice::GetPlaybackSpeed( void ) const 27 | { 28 | return m_playback_speed; 29 | } 30 | 31 | retro3d::Voice::Type retro3d::Voice::GetType( void ) const 32 | { 33 | return m_type; 34 | } 35 | 36 | void retro3d::Voice::SetSound(const mtlShared &sound) 37 | { 38 | m_sound = sound; 39 | } 40 | 41 | void retro3d::Voice::SetRangeRadius(float radius) 42 | { 43 | m_range_radius = mmlAbs(radius); 44 | } 45 | 46 | void retro3d::Voice::SetVolume(float volume) 47 | { 48 | m_volume = mmlClamp(0.0f, volume, 1.0f); 49 | } 50 | 51 | void retro3d::Voice::SetPitch(float pitch) 52 | { 53 | m_pitch = pitch; 54 | } 55 | 56 | void retro3d::Voice::SetPlaybackSpeed(float playback_speed) 57 | { 58 | m_playback_speed = playback_speed; 59 | } 60 | 61 | void retro3d::Voice::SetType(retro3d::Voice::Type type) 62 | { 63 | m_type = type; 64 | } 65 | -------------------------------------------------------------------------------- /graphics/retro_scene.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SCENE_H 2 | #define RETRO_SCENE_H 3 | 4 | #include "retro_light.h" 5 | #include "../retro_object.h" 6 | #include "../common/retro_geom.h" 7 | #include "../common/retro_transform.h" 8 | #include "../common/MiniLib/MTL/mtlPointer.h" 9 | 10 | namespace retro3d 11 | { 12 | 13 | class Scene 14 | { 15 | private: 16 | struct DispalyObject 17 | { 18 | retro3d::Model *model; // use BSP model instead 19 | mtlShared< Transform > transform; 20 | // how to render (point, line, triangle) 21 | // override materials 22 | // disregard light 23 | }; 24 | 25 | struct Sector 26 | { 27 | tiny3d::Array< Sector* > connected; // sectors connected to the current sector. 28 | tiny3d::Array< Sector* > visible; // sectors visible from the current sector. 29 | tiny3d::Array< DispalyObject* > objects; // list of all objects in the currect sector. 30 | tiny3d::Array< retro3d::Light > lights; // every sector has its own list of lights in the entire scene (can be used to simplify lights far away from camera) 31 | retro3d::AABB aabb; // the bounding box of the sector for fast culling against camera. 32 | }; 33 | 34 | // BSP model of the scene 35 | // list of sectors 36 | // list of lights 37 | // camera 38 | // the renderer basically only renders a scene, and traverses scene structure, rendering scene geometry and Objects as it goes using the light information in the leaf (not the) 39 | 40 | }; 41 | 42 | 43 | 44 | } 45 | 46 | #endif // RETRO_SCENE_H 47 | -------------------------------------------------------------------------------- /ecs/systems/retro_render_system.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_RENDER_SYSTEM_H 2 | #define RETRO_RENDER_SYSTEM_H 3 | 4 | #include "../../frontend/retro_render_device.h" 5 | #include "../retro_system.h" 6 | #include "../components/retro_render_component.h" 7 | #include "../../physics/retro_collider_tree.h" 8 | 9 | // NOTE: CONSIDER SPLITTING UP GEOMETRY SYSTEM FROM RENDER SYSTEM 10 | // Geometry system polls occlusion queries and inserts visible geometry into scene (at appropriate LOD). 11 | // Render system simply traverses scene/scenes and renders contents (in appropriate order). 12 | 13 | namespace retro3d 14 | { 15 | 16 | retro_system(RenderSystem, retro3d::RenderComponent) 17 | { 18 | private: 19 | retro3d::ColliderTree m_view_hierarchy; 20 | retro3d::ColliderTree m_light_hierarchy; 21 | retro3d::Frustum m_view_frustum; 22 | uint32_t m_render_items; 23 | uint32_t m_potentially_visible_items; 24 | uint32_t m_potentially_visible_items_counter; 25 | // Shared pointer to SCENE data structure 26 | 27 | protected: 28 | void OnSpawn(retro3d::RenderComponent &c) override; 29 | void OnUpdate(retro3d::RenderComponent &c) override; 30 | void OnDestroy(retro3d::RenderComponent &c) override; 31 | void OnUpdate( void ) override; 32 | 33 | public: 34 | RenderSystem( void ); 35 | 36 | uint32_t GetPotentiallyVisibleCount( void ) const; 37 | uint32_t GetRenderItemCount( void ) const; 38 | }; 39 | 40 | } 41 | 42 | #endif // RETRO_RENDER_SYSTEM_H 43 | -------------------------------------------------------------------------------- /audio/retro_voice.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_VOICE_H 2 | #define RETRO_VOICE_H 3 | 4 | #include "../common/MiniLib/MML/mmlVector.h" 5 | #include "retro_sound.h" 6 | #include "../common/retro_geom.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | class Voice 12 | { 13 | public: 14 | enum Type 15 | { 16 | Ambient, // equally audible within range AABB 17 | Directional, // ambient sound coming from certain direction, equally audible within range AABB 18 | Point, // originating from point, falloff based on receiver position within range AABB (fallof approaches 0 at end of radius) 19 | Cone // originating from point, falloff based on receiver position within range AABB and sound direction 20 | }; 21 | 22 | private: 23 | mtlShared m_sound; 24 | float m_range_radius; 25 | float m_volume; 26 | float m_pitch; 27 | float m_playback_speed; 28 | Type m_type; 29 | // NOTE: origin and direction is determined separately by supplied transform matrix 30 | 31 | public: 32 | Voice( void ); 33 | 34 | mtlShared GetSound( void ) const; 35 | float GetRangeRadius( void ) const; 36 | float GetVolume( void ) const; 37 | float GetPitch( void ) const; 38 | float GetPlaybackSpeed( void ) const; 39 | Type GetType( void ) const; 40 | 41 | void SetSound(const mtlShared &sound); 42 | void SetRangeRadius(float radius); 43 | void SetVolume(float volume); 44 | void SetPitch(float pitch); 45 | void SetPlaybackSpeed(float playback_speed); 46 | void SetType(retro3d::Voice::Type type); 47 | }; 48 | 49 | }; 50 | 51 | #endif // RETRO_VOICE_H 52 | -------------------------------------------------------------------------------- /ecs/systems/retro_collision_system.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_COLLISION_SYSTEM_H 2 | #define RETRO_COLLISION_SYSTEM_H 3 | 4 | #include "../retro_system.h" 5 | #include "../components/retro_collider_component.h" 6 | #include "../../physics/retro_collider_tree.h" 7 | #include "../../physics/retro_physics.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | retro_system(CollisionSystem, retro3d::ColliderComponent) 13 | { 14 | private: 15 | retro3d::ColliderTree m_collider_tree; 16 | 17 | protected: 18 | void OnSpawn(retro3d::ColliderComponent &c) override; 19 | void OnUpdate(retro3d::ColliderComponent &c) override; 20 | void OnDestroy(retro3d::ColliderComponent &c) override; 21 | void OnUpdate( void ) override; 22 | 23 | private: 24 | void ResolveContactA(const retro3d::ColliderTree::Contact &contact_pair, const retro3d::Collider::Contact &contact_info) const; 25 | 26 | public: 27 | CollisionSystem( void ); 28 | 29 | retro3d::Entity *CastRay(const retro3d::Ray &world_ray, uint64_t filter_flags, retro3d::Ray::Contact *contact_info = nullptr) const; 30 | bool Contains(const mmlVector<3> &world_point, uint64_t filter_flags, mtlList *colliders = nullptr); 31 | 32 | // TODO: Physics commands that only apply to objects with physics components 33 | retro3d::Entity *ApplyForce(const retro3d::Ray &world_force, float force_magnitude, uint64_t filter_flags, retro3d::Ray::Contact *contact_info = nullptr); 34 | 35 | void Debug_PrintTree( void ) const; 36 | void Debug_RenderTree( void ); 37 | const retro3d::ColliderTree::Contacts &Debug_GetPotentialContacts( void ) const; 38 | }; 39 | 40 | } 41 | 42 | #endif // RETRO_COLLISION_SYSTEM_H 43 | -------------------------------------------------------------------------------- /serial/retro_config.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_config.h" 2 | 3 | void retro3d::Configs::Config::Set(const mtlChars &name, const mtlChars &value) 4 | { 5 | auto *e = m_map.GetEntry(name); 6 | if (e == nullptr) { 7 | e = m_map.CreateEntry(name); 8 | } 9 | *e = value; 10 | } 11 | 12 | void retro3d::Configs::Set(mtlChars name, mtlChars value) 13 | { 14 | mtlSyntaxParser p; 15 | p.SetBuffer(name); 16 | mtlArray m; 17 | 18 | mtlChars subname; 19 | 20 | switch (p.Match("%s.%S %| %S", m)) { 21 | case 0: 22 | name = m[0].GetTrimmed(); 23 | name = name.GetSize() > 0 ? name : "global"; 24 | subname = m[1].GetTrimmed(); 25 | break; 26 | case 1: 27 | name = "global"; 28 | subname = m[0].GetTrimmed(); 29 | break; 30 | } 31 | 32 | auto *e = m_map.GetEntry(name); 33 | if (e == nullptr) { 34 | e = m_map.CreateEntry(name); 35 | } 36 | e->Set(subname, value); 37 | } 38 | 39 | bool retro3d::Configs::Read(const mtlChars &filename) 40 | { 41 | if (!mtlBufferFile(filename, m_buffer)) { return false; } 42 | mtlSyntaxParser p; 43 | p.SetBuffer(m_buffer); 44 | mtlArray m; 45 | while (!p.IsEnd()) { 46 | switch (p.Match("%S=\"%s\" %| %S=%w %| %s", m)) { 47 | case 0: 48 | case 1: 49 | Set(m[0], m[1]); 50 | break; 51 | default: 52 | break; 53 | } 54 | } 55 | return true; 56 | } 57 | 58 | bool retro3d::Configs::Read(const mtlChars &filename, const mtlChars §ion) 59 | { 60 | // Refresh the contents of a Config 61 | return false; 62 | } 63 | 64 | bool retro3d::Configs::Write(const mtlChars &filename) 65 | { 66 | return false; 67 | } 68 | 69 | void retro3d::Configs::Clear( void ) 70 | { 71 | m_map.RemoveAll(); 72 | m_buffer.Free(); 73 | } 74 | -------------------------------------------------------------------------------- /frontend/retro_video_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_VIDEO_DEVICE_H 2 | #define RETRO_VIDEO_DEVICE_H 3 | 4 | #include 5 | #include 6 | #include "../common/retro_geom.h" 7 | #include "../api/tiny3d/tiny3d.h" 8 | #include "retro_device.h" 9 | 10 | namespace retro3d 11 | { 12 | 13 | // @info The video device only manages the window and retrieves (relatively) platform independent information about it. 14 | class VideoDevice : public retro3d::Device 15 | { 16 | public: 17 | // @info The destructor should close the video subsystem. 18 | virtual ~VideoDevice( void ); 19 | 20 | // @info Initialize the video subsystem 21 | virtual bool Init( void ) = 0; 22 | 23 | // @info Create a window with the properties. 24 | virtual bool CreateWindow(uint32_t width, uint32_t height, bool enable_fullscreen) = 0; 25 | 26 | // @info Sets the window caption. 27 | virtual void SetWindowCaption(const std::string &caption) = 0; 28 | 29 | // @info Destroy the window. 30 | virtual void DestroyWindow( void ) = 0; 31 | 32 | // @info Transfer pixel data (from one format) to the internal representation of the video device. Stretches based on the relationship between the source rectangle and destination rectangle. 33 | virtual void FromImage(const tiny3d::Image &src, const retro3d::URect &dst_rect) = 0; 34 | 35 | // @info Ultimately displays the viewable video surface with the results from 36 | virtual void Display(const retro3d::Rect &rect) = 0; 37 | virtual void Display( void ) = 0; 38 | 39 | // @info Get window properties. 40 | virtual retro3d::Point GetWindowPosition( void ) const = 0; 41 | virtual uint32_t GetWindowWidth( void ) const = 0; 42 | virtual uint32_t GetWindowHeight( void ) const = 0; 43 | virtual std::string GetWindowCaption( void ) const = 0; 44 | }; 45 | 46 | } 47 | 48 | #endif // RETRO_VIDEO_DEVICE_H 49 | -------------------------------------------------------------------------------- /graphics/retro_texture.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_TEXTURE_H 2 | #define RETRO_TEXTURE_H 3 | 4 | #include "../api/tiny3d/tiny_texture.h" 5 | #include "../api/tiny3d/tiny_image.h" 6 | #include "../common/retro_assets.h" 7 | 8 | // 256x256 9 | // 64x64 10 | // 32x32 11 | // 16x16 12 | // 8x8 13 | // 4x4 14 | #define RETRO3D_MIP_COUNT 6 15 | 16 | namespace retro3d 17 | { 18 | 19 | class Texture : public retro3d::Asset 20 | { 21 | private: 22 | tiny3d::Texture m_mip_data[RETRO3D_MIP_COUNT]; 23 | tiny3d::Texture *m_mip_refs[RETRO3D_MIP_COUNT]; // TODO: Decouple from Tiny3d (for compatibility with other API:s) - This must instead be an index array 24 | 25 | private: 26 | void Delete( void ); 27 | void CreateErrorTexture( void ); 28 | void BuildRefs( void ); 29 | 30 | public: 31 | Texture( void ); 32 | Texture(const retro3d::Texture &mips); 33 | explicit Texture(const tiny3d::Image &img); 34 | 35 | bool FromImage(const tiny3d::Image &img); 36 | void Copy(const Texture &mips); 37 | void Destroy( void ); 38 | void SetBlendMode1(tiny3d::Color::BlendMode blend_mode); 39 | void SetBlendMode2(tiny3d::Color::BlendMode blend_mode); 40 | void SetBlendModes(tiny3d::Color::BlendMode mode_1, tiny3d::Color::BlendMode mode_2); 41 | void ResetBlendMode1( void ); 42 | void ResetBlendMode2( void ); 43 | void ResetBlendModes( void ); 44 | 45 | const tiny3d::Texture *operator[](tiny3d::UInt level) const; 46 | retro3d::Texture &operator=(const Texture &mips); 47 | 48 | const tiny3d::Texture *GetHighestQuality( void ) const; 49 | const tiny3d::Texture *GetLowestQuality( void ) const; 50 | 51 | static constexpr uint32_t MaxDimension( void ) { return tiny3d::Texture::MaxDimension(); } 52 | static constexpr uint32_t MinDimension( void ) { return tiny3d::Texture::MinDimension(); } 53 | }; 54 | 55 | } 56 | 57 | #endif // RETRO_TEXTURE_H 58 | -------------------------------------------------------------------------------- /ecs/systems/retro_scene_system.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SCENE_SYSTEM_H 2 | #define RETRO_SCENE_SYSTEM_H 3 | 4 | #include 5 | #include "../retro_system.h" 6 | #include "../components/retro_scene_component.h" 7 | #include "../components/retro_render_component.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | retro_system(SceneSystem, retro3d::SceneComponent) 13 | { 14 | private: 15 | struct Sector; 16 | 17 | struct Neighbor 18 | { 19 | retro3d::Frustum portal; 20 | Sector *sector; 21 | }; 22 | struct Sector 23 | { 24 | retro3d::ColliderTree lights; 25 | retro3d::ColliderTree visibles; 26 | retro3d::AABB aabb; 27 | mtlList neighbors; 28 | }; 29 | 30 | public: 31 | struct PV_Object 32 | { 33 | retro3d::RenderComponent *render_component; 34 | retro3d::Light *l_point; 35 | retro3d::Light *l_dir; 36 | retro3d::Light *l_amb; 37 | }; 38 | struct PV_Sector 39 | { 40 | mtlList pv_objects; // sorted in 41 | }; 42 | struct PV_Set 43 | { 44 | mtlList pv_sectors; 45 | }; 46 | 47 | private: 48 | SceneComponent *m_current_scene; 49 | uint32_t m_num_scenes; 50 | retro3d::Frustum m_view_frustum; 51 | 52 | protected: 53 | void OnSpawn(retro3d::SceneComponent &scene) override; 54 | void OnUpdate(retro3d::SceneComponent &scene) override; 55 | void OnDestroy(retro3d::SceneComponent &scene) override; 56 | 57 | public: 58 | SceneSystem( void ); 59 | 60 | // void ProcessSceneModel(const retro3d::Model &model); // Converts to sectors, converts each sector into BSP tree 61 | // void SetViewFrustum(const retro3d::Frustum &frustum); 62 | // const retro3d::Frustum &GetViewFrustum( void ) const; 63 | // void BuildPotentiallyVisibleSet(SceneSystem::PV_Set &out); 64 | }; 65 | 66 | } 67 | 68 | #endif // RETRO_SCENE_SYSTEM_H 69 | -------------------------------------------------------------------------------- /common/retro_dynref.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_DYNREF_H 2 | #define RETRO_DYNREF_H 3 | 4 | #include 5 | #include "MiniLib/MTL/mtlPointer.h" 6 | #include "retro_assert.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | class IDynRef; 12 | 13 | // DynRef 14 | // A dynamic reference that automatically updates to null when the owner destroys the object being referred to. 15 | template < typename ref_t > 16 | class DynRef 17 | { 18 | friend class IDynRef; 19 | 20 | private: 21 | mtlShared< retro3d::IDynRef* > m_ref; 22 | ref_t *m_data; 23 | 24 | public: 25 | void Release( void ); 26 | bool IsNull( void ) const; 27 | 28 | ref_t *operator->( void ); 29 | const ref_t *operator->( void ) const; 30 | }; 31 | 32 | // IDynRef 33 | // The interface of an object that can be dynamically referred to. 34 | class IDynRef 35 | { 36 | private: 37 | mtlShared< retro3d::IDynRef* > m_self_ref; 38 | 39 | public: 40 | IDynRef( void ); 41 | IDynRef(const IDynRef&) = delete; 42 | IDynRef &operator=(const IDynRef&) = delete; 43 | ~IDynRef( void ); 44 | 45 | template < typename ref_t > 46 | DynRef CreateReference( void ); 47 | }; 48 | 49 | } 50 | 51 | template < typename ref_t > 52 | void retro3d::DynRef::Release( void ) 53 | { 54 | m_data = nullptr; 55 | m_ref.Delete(); 56 | } 57 | 58 | template < typename ref_t > 59 | bool retro3d::DynRef::IsNull( void ) const 60 | { 61 | return m_ref.IsNull() || *m_ref.GetShared() == nullptr; 62 | } 63 | 64 | template < typename ref_t > 65 | ref_t *retro3d::DynRef::operator->( void ) 66 | { 67 | return !IsNull() ? m_data : nullptr; 68 | } 69 | 70 | template < typename ref_t > 71 | const ref_t *retro3d::DynRef::operator->( void ) const 72 | { 73 | return !IsNull() ? m_data : nullptr; 74 | } 75 | 76 | template < typename ref_t > 77 | retro3d::DynRef retro3d::IDynRef::CreateReference( void ) 78 | { 79 | retro3d::DynRef ref; 80 | ref.m_ref = m_self_ref; 81 | ref.m_data = this; 82 | return ref; 83 | } 84 | 85 | #endif // RETRO_DYNREF_H 86 | -------------------------------------------------------------------------------- /ecs/components/retro_collider_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_collider_component.h" 2 | #include "retro_transform_component.h" 3 | #include "../retro_entity.h" 4 | 5 | namespace retro3d { retro_register_component(ColliderComponent) } 6 | 7 | void retro3d::ColliderComponent::OnSpawn( void ) 8 | { 9 | m_collider->AttachTransform(GetObject()->AddComponent()->GetTransform()); 10 | m_reinsert = false; 11 | } 12 | 13 | retro3d::ColliderComponent::ColliderComponent( void ) : mtlInherit(this), m_filter_flags(uint64_t(~0)), m_is_static(false), m_reinsert(false) 14 | { 15 | CreateCollider(); 16 | } 17 | 18 | retro3d::Collider &retro3d::ColliderComponent::GetCollider( void ) 19 | { 20 | return *m_collider.GetShared(); 21 | } 22 | 23 | const retro3d::Collider &retro3d::ColliderComponent::GetCollider( void ) const 24 | { 25 | return *m_collider.GetShared(); 26 | } 27 | 28 | uint64_t retro3d::ColliderComponent::GetFilterFlags( void ) const 29 | { 30 | return m_filter_flags; 31 | } 32 | 33 | bool retro3d::ColliderComponent::GetFilterFlag(uint32_t flag_index) const 34 | { 35 | return (m_filter_flags & (uint64_t(1) << flag_index)) != 0; 36 | } 37 | 38 | void retro3d::ColliderComponent::SetFilterFlags(uint64_t filter_flags) 39 | { 40 | m_filter_flags = filter_flags; 41 | m_reinsert = true; 42 | } 43 | 44 | void retro3d::ColliderComponent::SetFilterFlag(uint32_t flag_index, bool state) 45 | { 46 | if (state == true) { 47 | m_filter_flags |= (uint64_t(1) << flag_index); 48 | } else { 49 | m_filter_flags &= ~(uint64_t(1) << flag_index); 50 | } 51 | } 52 | 53 | bool retro3d::ColliderComponent::IsStatic( void ) const 54 | { 55 | return m_is_static; 56 | } 57 | 58 | void retro3d::ColliderComponent::ToggleStatic( void ) 59 | { 60 | m_is_static = !m_is_static; 61 | m_reinsert = true; 62 | } 63 | 64 | bool retro3d::ColliderComponent::ShouldReinsert( void ) const 65 | { 66 | return m_reinsert; 67 | } 68 | 69 | void retro3d::ColliderComponent::ToggleReinsert( void ) 70 | { 71 | m_reinsert = !m_reinsert; 72 | } 73 | -------------------------------------------------------------------------------- /backend/sdl_sound_device.h: -------------------------------------------------------------------------------- 1 | #ifndef SDL_SOUND_DEVICE_H 2 | #define SDL_SOUND_DEVICE_H 3 | 4 | #include 5 | #include "../frontend/retro_sound_device.h" 6 | 7 | // Roll own mixer 8 | // https://ericscrivner.me/2017/10/getting-circular-sdl-audio/ 9 | 10 | namespace platform 11 | { 12 | 13 | class SDLSoundDevice : public retro3d::SoundDevice 14 | { 15 | private: 16 | struct PlaybackJob 17 | { 18 | mtlShared sound; 19 | void *api_data; 20 | retro3d::SharedTransform world_transform; 21 | retro3d::AABB world_aabb; 22 | int32_t channel; 23 | retro3d::Voice::Type type; 24 | float volume; 25 | float radius; 26 | }; 27 | 28 | typedef std::unordered_map PlaybackJobs; 29 | 30 | private: 31 | PlaybackJobs m_playback_jobs; 32 | retro3d::SharedTransform m_internal_transform_copy; 33 | retro3d::SharedTransform m_world_transform; 34 | retro3d::Sound::Format m_format; 35 | int32_t m_audio_count; 36 | 37 | private: 38 | void UpdateAABB(PlaybackJob &j); 39 | void UpdateVolume(PlaybackJob &j); 40 | 41 | public: 42 | SDLSoundDevice( void ); 43 | ~SDLSoundDevice( void ) override; 44 | 45 | bool Init(const retro3d::Sound::Format &format) override; 46 | 47 | void SetReceiverTransform(const retro3d::SharedTransform &world_to_view) override; 48 | void SetReceiverTransform(const retro3d::Transform &world_to_view) override; 49 | 50 | retro3d::Transform GetReceiverTransform( void ) const override; 51 | retro3d::Sound::Format GetFormat( void ) const override; 52 | 53 | int32_t Play(const retro3d::Voice &voice, const retro3d::SharedTransform &world_transform, double time_stamp = 0.0) override; 54 | int32_t Play(const retro3d::Voice &voice, const retro3d::Transform &world_transform, double time_stamp = 0.0) override; 55 | void Kill(int32_t audio_index) override; 56 | 57 | void Update( void ) override; 58 | }; 59 | 60 | } 61 | 62 | #endif // SDL_SOUND_DEVICE_H 63 | -------------------------------------------------------------------------------- /graphics/retro_camera.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_CAMERA_H 2 | #define RETRO_CAMERA_H 3 | 4 | #include "../common/MiniLib/MML/mmlMatrix.h" 5 | #include "../common/MiniLib/MML/mmlVector.h" 6 | #include "../api/tiny3d/tiny_math.h" 7 | #include "../common/retro_geom.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | class Camera 13 | { 14 | private: 15 | float m_head; 16 | float m_pitch; // [-pi, x, pi] 17 | float m_roll; 18 | mmlMatrix<3,3> m_rx; 19 | mmlMatrix<3,3> m_ry; 20 | mmlMatrix<3,3> m_rz; 21 | mmlVector<3> m_pos; 22 | retro3d::SharedTransform m_view_to_world; 23 | 24 | public: 25 | static mmlVector<3> GlobalUp( void ); 26 | static mmlVector<3> GlobalRight( void ); 27 | static mmlVector<3> GlobalForward( void ); 28 | 29 | public: 30 | Camera( void ); 31 | Camera(const retro3d::Camera &c); 32 | Camera &operator=(const retro3d::Camera &c); 33 | 34 | mmlVector<3> GroundedForward( void ) const; 35 | mmlVector<3> GroundedUp( void ) const; 36 | mmlVector<3> GroundedRight( void ) const; 37 | mmlVector<3> Forward( void ) const; 38 | mmlVector<3> Up( void ) const; 39 | mmlVector<3> Right( void ) const; 40 | 41 | const mmlVector<3> &GetPosition( void ) const; 42 | void SetPosition(const mmlVector<3> &pos); 43 | void Move(const mmlVector<3> &move); 44 | void LocalMove(const mmlVector<3> &move); 45 | void LocalFly(const mmlVector<3> &move); 46 | 47 | const retro3d::SharedTransform GetTransform( void ) const; 48 | retro3d::Transform GetViewTransform( void ) const; 49 | 50 | float GetHeadAngle( void ) const; 51 | float GetPitchAngle( void ) const; 52 | float GetRollAngle( void ) const; 53 | void SetRotation(float x_head, float y_pitch, float z_roll); 54 | void Rotate(float x_head, float y_pitch, float z_roll); 55 | 56 | mmlMatrix<3,3> GetRX( void ) const; 57 | mmlMatrix<3,3> GetRY( void ) const; 58 | mmlMatrix<3,3> GetRZ( void ) const; 59 | }; 60 | 61 | } 62 | 63 | #endif // RETRO_CAMERA_H 64 | -------------------------------------------------------------------------------- /ecs/systems/retro_light_system.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_light_system.h" 2 | #include "../../retro3d.h" 3 | 4 | void retro3d::LightSystem::OnSpawn(retro3d::LightComponent &c) 5 | { 6 | m_light_tree.Insert(c.GetObject(), &c.GetActivationBounds(), c.IsStatic(), c.GetFilterFlags()); 7 | if (c.ShouldReinsert() == true) { 8 | c.ToggleReinsert(); 9 | } 10 | } 11 | 12 | void retro3d::LightSystem::OnUpdate(retro3d::LightComponent &c) 13 | { 14 | if (c.ShouldReinsert() == true) { 15 | m_light_tree.Remove(c.GetObject()); 16 | m_light_tree.Insert(c.GetObject(), &c.GetActivationBounds(), c.IsStatic(), c.GetFilterFlags()); 17 | c.ToggleReinsert(); 18 | } 19 | } 20 | 21 | void retro3d::LightSystem::OnDestroy(retro3d::LightComponent &c) 22 | { 23 | m_light_tree.Remove(c.GetObject()); 24 | } 25 | 26 | retro3d::LightSystem::LightSystem( void ) : mtlInherit(this) 27 | { 28 | if (m_light_tree.IsCheckingContacts() == true) { 29 | m_light_tree.ToggleContactCheck(); 30 | } 31 | } 32 | 33 | void retro3d::LightSystem::Debug_PrintTree( void ) const 34 | { 35 | m_light_tree.Debug_PrintTree(); 36 | } 37 | 38 | void retro3d::LightSystem::Debug_RenderTree( void ) 39 | { 40 | std::queue::Debug_AABB> q = m_light_tree.Debug_GetTree(); 41 | while (q.empty() == false) { 42 | mmlVector<3> c = mmlVector<3>::Fill(0.0f); 43 | switch (q.front().type) { 44 | case retro3d::ColliderTree::Debug_AABB::Node_Dynamic: 45 | c[2] = 1.0f; 46 | break; 47 | case retro3d::ColliderTree::Debug_AABB::Node_Static: 48 | c[0] = 1.0f; 49 | c[1] = 1.0f; 50 | break; 51 | case retro3d::ColliderTree::Debug_AABB::Leaf_Dynamic: 52 | c[1] = 1.0f; 53 | break; 54 | case retro3d::ColliderTree::Debug_AABB::Leaf_Static: 55 | c[0] = 1.0f; 56 | break; 57 | } 58 | GetEngine()->GetRenderer()->RenderAABB(q.front(), mmlMatrix<4,4>::Identity(), c); 59 | q.pop(); 60 | } 61 | } 62 | 63 | void retro3d::LightSystem::UpdateLightmap( void ) 64 | { 65 | // render static lights to the light map 66 | // need input vertex, normals, light uvs 67 | } 68 | -------------------------------------------------------------------------------- /ecs/components/retro_timer_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_timer_component.h" 2 | 3 | namespace retro3d { retro_register_component(TimerComponent) } 4 | 5 | void retro3d::TimerComponent::OnSpawn( void ) 6 | { 7 | m_timer = this->GetObject()->CreateGameTimer(); 8 | } 9 | 10 | void retro3d::TimerComponent::OnUpdate( void ) 11 | { 12 | const uint32_t ticks = m_timer.GetTicks(); 13 | m_timer.ResetTicks(); 14 | 15 | if (m_on_tick.IsNull() == false && m_on_tick->IsNull() == false) { 16 | const uint32_t clipped_ticks = ticks > 0 && m_multitick == false ? 1 : ticks; 17 | for (uint32_t i = 0; i < clipped_ticks; ++i) { 18 | (*m_on_tick.GetShared())(); 19 | } 20 | } 21 | 22 | if (m_tick_count > -1 && (m_tick_count -= ticks) == 0) { 23 | Destroy(); 24 | } 25 | } 26 | 27 | void retro3d::TimerComponent::OnDestroy( void ) 28 | { 29 | if (m_on_destroy.IsNull() == false) { 30 | (*m_on_destroy.GetShared())(); 31 | } 32 | } 33 | 34 | retro3d::TimerComponent::TimerComponent( void ) : mtlInherit(this), m_timer(), m_tick_count(-1), m_on_tick(), m_on_destroy(), m_multitick(false) 35 | {} 36 | 37 | void retro3d::TimerComponent::SetTickRate(retro3d::TimerType timer_type, uint32_t num_ticks, retro3d::Time over_time) 38 | { 39 | switch (timer_type) { 40 | case retro3d::TIMER_REAL: 41 | m_timer = retro3d::RealTimeTimer(num_ticks, over_time); 42 | break; 43 | case retro3d::TIMER_SIM: 44 | m_timer = GetEngine()->CreateSimulationTimer(num_ticks, over_time); 45 | break; 46 | case retro3d::TIMER_GAME: 47 | m_timer = GetObject()->CreateGameTimer(num_ticks, over_time); 48 | break; 49 | } 50 | } 51 | 52 | void retro3d::TimerComponent::Start( void ) 53 | { 54 | m_timer.Start(); 55 | } 56 | 57 | void retro3d::TimerComponent::Pause( void ) 58 | { 59 | m_timer.Pause(); 60 | } 61 | 62 | void retro3d::TimerComponent::Reset( void ) 63 | { 64 | m_timer.Reset(); 65 | } 66 | 67 | void retro3d::TimerComponent::SetOnTick(const mtlShared &procedure) 68 | { 69 | m_on_tick = procedure; 70 | } 71 | 72 | void retro3d::TimerComponent::DisableOnTick( void ) 73 | { 74 | m_on_tick.Delete(); 75 | } 76 | 77 | void retro3d::TimerComponent::SetOnDestroy(const mtlShared &procedure) 78 | { 79 | m_on_destroy = procedure; 80 | } 81 | 82 | void retro3d::TimerComponent::DisableOnDestroy( void ) 83 | { 84 | m_on_destroy.Delete(); 85 | } 86 | -------------------------------------------------------------------------------- /ecs/retro_component.cpp: -------------------------------------------------------------------------------- 1 | #include "../common/MiniLib/MML/mmlMath.h" 2 | #include "retro_component.h" 3 | #include "retro_entity.h" 4 | 5 | void retro3d::Component::OnSpawn( void ) 6 | {} 7 | 8 | void retro3d::Component::OnUpdate( void ) 9 | {} 10 | 11 | void retro3d::Component::OnCollision(retro3d::Entity&) 12 | {} 13 | 14 | void retro3d::Component::OnDestroy( void ) 15 | {} 16 | 17 | retro3d::Component::Component( void ) : 18 | mtlInherit(this), m_object(nullptr), m_is_active(1), m_should_destroy(false) 19 | {} 20 | 21 | retro3d::Component::~Component( void ) 22 | {} 23 | 24 | void retro3d::Component::Destroy( void ) 25 | { 26 | m_should_destroy = true; 27 | } 28 | 29 | bool retro3d::Component::IsDestroyed( void ) const 30 | { 31 | return m_should_destroy || m_object->IsDestroyed(); 32 | } 33 | 34 | bool retro3d::Component::IsActive( void ) const 35 | { 36 | return !IsDestroyed() && m_is_active > 0 && m_object->IsActive(); 37 | } 38 | 39 | void retro3d::Component::Deactivate( void ) 40 | { 41 | --m_is_active; 42 | } 43 | 44 | void retro3d::Component::Activate( void ) 45 | { 46 | m_is_active = mmlMin(1, m_is_active + 1); 47 | } 48 | 49 | retro3d::Entity *retro3d::Component::GetObject( void ) 50 | { 51 | return m_object; 52 | } 53 | 54 | const retro3d::Entity *retro3d::Component::GetObject( void ) const 55 | { 56 | return m_object; 57 | } 58 | 59 | retro3d::Engine *retro3d::Component::GetEngine( void ) 60 | { 61 | return m_object->GetEngine(); 62 | } 63 | 64 | const retro3d::Engine *retro3d::Component::GetEngine( void ) const 65 | { 66 | return m_object->GetEngine(); 67 | } 68 | 69 | 70 | retro3d::RenderDevice *retro3d::Component::GetRenderer( void ) 71 | { 72 | return m_object->GetRenderer(); 73 | } 74 | 75 | const retro3d::RenderDevice *retro3d::Component::GetRenderer( void ) const 76 | { 77 | return m_object->GetRenderer(); 78 | } 79 | 80 | retro3d::SoundDevice *retro3d::Component::GetSoundDevice( void ) 81 | { 82 | return m_object->GetSoundDevice(); 83 | } 84 | 85 | const retro3d::SoundDevice *retro3d::Component::GetSoundDevice( void ) const 86 | { 87 | return m_object->GetSoundDevice(); 88 | } 89 | 90 | retro3d::InputDevice *retro3d::Component::GetInput( void ) 91 | { 92 | return m_object->GetInput(); 93 | } 94 | 95 | const retro3d::InputDevice *retro3d::Component::GetInput( void ) const 96 | { 97 | return m_object->GetInput(); 98 | } 99 | -------------------------------------------------------------------------------- /common/md5_old/md5.h: -------------------------------------------------------------------------------- 1 | // md5.h 2 | // github.com/SirJonthe 3 | // 2019 4 | 5 | // Public domain 6 | 7 | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 8 | // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 9 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 10 | 11 | #ifndef MD5_H_INCLUDED__ 12 | #define MD5_H_INCLUDED__ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | // @data md5sum 19 | // @info Container for an MD5 digest. Takes an arbitrary input of bytes (in the form of a string) and converts it into a 16 byte number (or 'digest') representing that input with a fair degree of uniqueness. 20 | class md5sum 21 | { 22 | private: 23 | uint8_t m_digest[16]; 24 | 25 | private: 26 | static uint32_t leftrotate(uint32_t x, uint32_t c); 27 | 28 | public: 29 | md5sum( void ); 30 | md5sum(const md5sum&) = default; 31 | md5sum &operator=(const md5sum&) = default; 32 | md5sum(const std::string &message); 33 | md5sum(const char *message, uint64_t byte_size); 34 | md5sum &operator=(const std::string &message); 35 | 36 | // @algo calc_sum 37 | // @info Generates a digest based on the input and stores it in the container. 38 | // @in message -> The message to digest. 39 | void calc_sum(std::string message); 40 | 41 | // @algo calc_sum 42 | // @info Generates a digest based on the input and stores it in the container. 43 | // @in 44 | // message -> The message to digest. 45 | // byte_size -> The size (in bytes) of the input message. 46 | void calc_sum(const char *message, uint64_t byte_size); 47 | 48 | // @algo hex 49 | // @out The digest converted as a human readable hexadecimal ASCII string. 50 | std::string hex( void ) const; 51 | 52 | // @algo == 53 | // @info Tests for equality between digests. 54 | // @in Right-hand side MD5 value. 55 | // @out TRUE on equality. 56 | bool operator==(const md5sum &r) const; 57 | 58 | // @algo != 59 | // @info Tests for inequality between digests. 60 | // @in Right-hand side MD5 value. 61 | // @out TRUE on inequality. 62 | bool operator!=(const md5sum &r) const; 63 | 64 | // @algo uint8_t* 65 | // @info Returns the pointer to the digest. 66 | // @note It is assumed that the user knows the size of 16 bytes. 67 | // @out The pointer to the digest. 68 | operator const uint8_t*( void ) const; 69 | }; 70 | 71 | // @algo md5 72 | // @info Helper function designed to take a message and return its ASCII hex string. 73 | // @in message -> The message to digest. 74 | // @out The ASCII hex string digest. 75 | std::string md5(const std::string &message); 76 | 77 | #endif 78 | 79 | -------------------------------------------------------------------------------- /ecs/components/retro_render_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_RENDER_COMPONENT_H 2 | #define RETRO_RENDER_COMPONENT_H 3 | 4 | #include "../retro_component.h" 5 | #include "../../graphics/retro_model.h" 6 | #include "retro_transform_component.h" 7 | #include "../../frontend/retro_render_device.h" 8 | #include "../../physics/retro_collider.h" 9 | 10 | namespace retro3d 11 | { 12 | 13 | // TODO: Take into account level of detail 14 | 15 | retro_component(RenderComponent) 16 | { 17 | private: 18 | struct Frame 19 | { 20 | mtlShared model; 21 | float display_time = 0.0f; 22 | }; 23 | 24 | struct Animation 25 | { 26 | retro3d::Array frames; 27 | retro3d::AABB biggest_aabb; 28 | }; 29 | 30 | typedef mtlStringMap< Animation > Animations; 31 | 32 | private: 33 | retro3d::SharedTransform m_transform; 34 | Animations m_animations; 35 | Animation *m_first_animation; 36 | Animation *m_current_animation; 37 | uint32_t m_frame_index; 38 | float m_current_frame_countdown; 39 | retro3d::AABB m_biggest_aabb; 40 | retro3d::AABBCollider m_occlusion_collider; 41 | retro3d::RenderDevice::LightMode m_light_mode; 42 | float m_animation_speed_scale; 43 | 44 | protected: 45 | void OnSpawn( void ) override; 46 | void OnUpdate( void ) override; 47 | 48 | public: 49 | RenderComponent( void ); 50 | 51 | mtlShared GetModel( void ); 52 | const mtlShared GetModel( void ) const; 53 | void SetFrame(const mtlShared &model, float display_time = 0.0f); 54 | 55 | retro3d::AABB GetBiggestAnimationAABB( void ) const; 56 | retro3d::AABB GetBiggestAABB( void ) const; 57 | 58 | const retro3d::AABBCollider &GetOcclusionCollider( void ) const; 59 | 60 | void CreateAnimation(const mtlChars &animation_name, uint32_t frame_count = 1); 61 | void CreateAnimation(uint32_t frame_count); 62 | void SetAnimation(const mtlChars &animation_name); 63 | 64 | uint32_t GetFrameIndex( void ) const; 65 | void SetFrameIndex(uint32_t i); 66 | uint32_t GetAnimationFrameCount( void ) const; 67 | 68 | mmlMatrix<4,4> GetTransformMatrix( void ) const; 69 | 70 | retro3d::RenderDevice::LightMode GetLightMode( void ) const; 71 | void SetLightMode(retro3d::RenderDevice::LightMode light_mode); 72 | 73 | float GetAnimationSpeedScale( void ) const; 74 | void SetAnimationSpeedScale(float scale); 75 | }; 76 | 77 | } 78 | 79 | #endif // RETRO_RENDER_COMPONENT_H 80 | -------------------------------------------------------------------------------- /graphics/retro_fx.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_FX_H 2 | #define RETRO_FX_H 3 | 4 | #include 5 | #include "../api/tiny3d/tiny_structs.h" 6 | #include "../api/tiny3d/tiny_image.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | static constexpr uint32_t FX_FIRE_PALETTE_SIZE = 38; 12 | static constexpr tiny3d::Color FX_FIRE_PALETTE[FX_FIRE_PALETTE_SIZE] = { 13 | tiny3d::Color{0x00,0x00,0x00,tiny3d::Color::Transparent}, 14 | tiny3d::Color{0x07,0x07,0x07,tiny3d::Color::Transparent}, 15 | tiny3d::Color{0x1F,0x07,0x07,tiny3d::Color::Solid}, 16 | tiny3d::Color{0x2F,0x0F,0x07,tiny3d::Color::Solid}, 17 | tiny3d::Color{0x47,0x0F,0x07,tiny3d::Color::Solid}, 18 | tiny3d::Color{0x57,0x17,0x07,tiny3d::Color::Solid}, 19 | tiny3d::Color{0x67,0x1F,0x07,tiny3d::Color::Solid}, 20 | tiny3d::Color{0x77,0x1F,0x07,tiny3d::Color::Solid}, 21 | tiny3d::Color{0x8F,0x27,0x07,tiny3d::Color::Solid}, 22 | tiny3d::Color{0x9F,0x2F,0x07,tiny3d::Color::Solid}, 23 | tiny3d::Color{0xAF,0x3F,0x07,tiny3d::Color::Solid}, 24 | tiny3d::Color{0xBF,0x47,0x07,tiny3d::Color::Solid}, 25 | tiny3d::Color{0xC7,0x47,0x07,tiny3d::Color::Solid}, 26 | tiny3d::Color{0xDF,0x4F,0x07,tiny3d::Color::Solid}, 27 | tiny3d::Color{0xDF,0x57,0x07,tiny3d::Color::Solid}, 28 | tiny3d::Color{0xDF,0x57,0x07,tiny3d::Color::Solid}, 29 | tiny3d::Color{0xD7,0x5F,0x07,tiny3d::Color::Solid}, 30 | tiny3d::Color{0xD7,0x5F,0x07,tiny3d::Color::Solid}, 31 | tiny3d::Color{0xD7,0x67,0x0F,tiny3d::Color::Solid}, 32 | tiny3d::Color{0xCF,0x6F,0x0F,tiny3d::Color::Solid}, 33 | tiny3d::Color{0xCF,0x77,0x0F,tiny3d::Color::Solid}, 34 | tiny3d::Color{0xCF,0x7F,0x0F,tiny3d::Color::Solid}, 35 | tiny3d::Color{0xCF,0x87,0x17,tiny3d::Color::Solid}, 36 | tiny3d::Color{0xC7,0x87,0x17,tiny3d::Color::Solid}, 37 | tiny3d::Color{0xC7,0x8F,0x17,tiny3d::Color::Solid}, 38 | tiny3d::Color{0xC7,0x97,0x1F,tiny3d::Color::Solid}, 39 | tiny3d::Color{0xBF,0x9F,0x1F,tiny3d::Color::Solid}, 40 | tiny3d::Color{0xBF,0x9F,0x1F,tiny3d::Color::Solid}, 41 | tiny3d::Color{0xBF,0xA7,0x27,tiny3d::Color::Solid}, 42 | tiny3d::Color{0xBF,0xA7,0x27,tiny3d::Color::Solid}, 43 | tiny3d::Color{0xBF,0xAF,0x2F,tiny3d::Color::Solid}, 44 | tiny3d::Color{0xB7,0xAF,0x2F,tiny3d::Color::Solid}, 45 | tiny3d::Color{0xB7,0xB7,0x2F,tiny3d::Color::Solid}, 46 | tiny3d::Color{0xB7,0xB7,0x37,tiny3d::Color::Solid}, 47 | tiny3d::Color{0xCF,0xCF,0x6F,tiny3d::Color::Solid}, 48 | tiny3d::Color{0xDF,0xDF,0x9F,tiny3d::Color::Solid}, 49 | tiny3d::Color{0xEF,0xEF,0xC7,tiny3d::Color::Solid}, 50 | tiny3d::Color{0xFF,0xFF,0xFF,tiny3d::Color::Solid} 51 | }; 52 | 53 | void FX_InitFire(); 54 | void FX_SpreadFire(const tiny3d::Color *fire_palette = FX_FIRE_PALETTE); 55 | void FX_Desaturate(tiny3d::Image &img, const tiny3d::URect *dst_rect = nullptr); 56 | 57 | } 58 | 59 | #endif // RETRO_FX_H 60 | -------------------------------------------------------------------------------- /ecs/systems/retro_render_system.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_render_system.h" 2 | #include "../retro_entity.h" 3 | #include "../../backend/null_render_device.h" 4 | #include "../../backend/t3d_render_device.h" 5 | 6 | void retro3d::RenderSystem::OnSpawn(retro3d::RenderComponent &c) 7 | { 8 | m_view_hierarchy.Insert(&c, const_cast(&c.GetOcclusionCollider())); 9 | ++m_render_items; 10 | } 11 | 12 | void retro3d::RenderSystem::OnUpdate(retro3d::RenderComponent &c) 13 | { 14 | // NOTE: Immediate rendering of potentially visible RenderComponents. 15 | 16 | if (c.GetModel().IsNull() == false) { 17 | const mmlMatrix<4,4> world_transform = c.GetTransformMatrix(); 18 | const retro3d::AABB world_aabb = c.GetModel()->aabb.ApplyTransform(world_transform); 19 | const retro3d::Contain world_occlusion = m_view_frustum.Contains(world_aabb, false, true); 20 | if (world_occlusion >= retro3d::Contain_Partial) { 21 | GetEngine()->GetRenderer()->RenderModel(*c.GetModel().GetShared(), c.GetTransformMatrix(), c.GetLightMode()); 22 | ++m_potentially_visible_items_counter; 23 | } 24 | } 25 | } 26 | 27 | void retro3d::RenderSystem::OnDestroy(retro3d::RenderComponent &c) 28 | { 29 | m_view_hierarchy.Remove(&c); 30 | --m_render_items; 31 | } 32 | 33 | void retro3d::RenderSystem::OnUpdate( void ) 34 | { 35 | // NOTE: Deferred rendering of RenderComponents, omitting objects outside of view frustum via BVH. 36 | 37 | m_potentially_visible_items = m_potentially_visible_items_counter; 38 | m_potentially_visible_items_counter = 0; 39 | 40 | // m_view_hierarchy.Update(); 41 | 42 | retro3d::RenderDevice *r = GetEngine()->GetRenderer(); 43 | r->SetViewTransform(GetEngine()->GetCamera()->GetViewTransform()); 44 | 45 | m_view_frustum = r->GetViewFrustum(); 46 | 47 | // mtlList pvs; 48 | 49 | // m_view_hierarchy.Contains(m_view_frustum, ~uint64_t(0), &pvs); 50 | 51 | // mtlItem *i = pvs.GetFirst(); 52 | // while (i != nullptr) { 53 | // retro3d::RenderComponent *rc = i->GetItem(); 54 | // if (rc->GetModel().IsNull() == false) { 55 | // GetEngine()->GetRenderer()->RenderModel(*rc->GetModel().GetShared(), rc->GetTransformMatrix(), rc->GetLightMode()); 56 | // } 57 | // i = i->GetNext(); 58 | // } 59 | 60 | r->FinishRender(); 61 | } 62 | 63 | retro3d::RenderSystem::RenderSystem( void ) : mtlInherit(this), m_view_hierarchy(), m_light_hierarchy(), m_view_frustum(), m_render_items(0), m_potentially_visible_items(0), m_potentially_visible_items_counter(0) 64 | {} 65 | 66 | uint32_t retro3d::RenderSystem::GetRenderItemCount( void ) const 67 | { 68 | return m_render_items; 69 | } 70 | 71 | uint32_t retro3d::RenderSystem::GetPotentiallyVisibleCount( void ) const 72 | { 73 | return m_potentially_visible_items; 74 | } 75 | -------------------------------------------------------------------------------- /serial/retro_reader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../common/MiniLib/MML/mmlMath.h" 3 | #include "retro_reader.h" 4 | #include 5 | 6 | void retro3d::Reader::UpdatePath(const std::string &file) 7 | { 8 | m_file = file; 9 | 10 | size_t dir_sep1 = file.find_last_of('\\'); 11 | size_t dir_sep2 = file.find_last_of('/'); 12 | size_t dir_sep = mmlMax(dir_sep1, dir_sep2); 13 | if (dir_sep == std::string::npos) { 14 | dir_sep = mmlMin(dir_sep1, dir_sep2); 15 | } 16 | m_path = (dir_sep != std::string::npos) ? file.substr(0, dir_sep + 1) : ""; 17 | } 18 | 19 | retro3d::Reader::Reader( void ) : m_in(nullptr), m_file(""), m_path(""), m_is_open(false) 20 | {} 21 | 22 | retro3d::Reader::~Reader( void ) 23 | { 24 | delete m_in; 25 | } 26 | 27 | bool retro3d::Reader::ReadFromFile(const std::string &file) 28 | { 29 | UpdatePath(file); 30 | delete m_in; 31 | std::ifstream *fin = new std::ifstream; 32 | fin->open(file.c_str()); 33 | m_in = fin; 34 | m_is_open = (fin->is_open() == true); 35 | if (m_is_open == false) { 36 | delete m_in; 37 | m_in = nullptr; 38 | } 39 | return m_is_open; 40 | } 41 | 42 | void retro3d::Reader::ReadFromMemory(const char *buf, uint64_t byte_count, const std::string &virtual_file) 43 | { 44 | UpdatePath(virtual_file); 45 | delete m_in; 46 | std::istringstream *sin = new std::istringstream; 47 | sin->str() = std::string(buf, byte_count); 48 | m_in = sin; 49 | m_is_open = true; 50 | } 51 | 52 | void retro3d::Reader::Close( void ) 53 | { 54 | delete m_in; 55 | m_in = nullptr; 56 | m_file = ""; 57 | m_path = ""; 58 | m_is_open = false; 59 | } 60 | 61 | uint64_t retro3d::Reader::ReadBin(char *out, uint64_t byte_count) 62 | { 63 | if (m_in == nullptr) { return 0; } 64 | const bool readstate = m_in->read(out, uint32_t(byte_count)) ? true : false; 65 | return readstate == true ? byte_count : (IsEnd() ? uint64_t(m_in->gcount()) : 0); 66 | } 67 | 68 | bool retro3d::Reader::ReadLine(std::string &out) 69 | { 70 | if (m_in == nullptr) { return false; } 71 | return std::getline(*m_in, out) ? true : false; 72 | } 73 | 74 | bool retro3d::Reader::ReadWord(std::string &out) 75 | { 76 | if (m_in == nullptr) { return false; } 77 | return ((*m_in) >> out) ? true : false; 78 | } 79 | 80 | bool retro3d::Reader::ReadChar(char &out) 81 | { 82 | if (m_in == nullptr) { return false; } 83 | return ((*m_in) >> out) ? true : false; 84 | } 85 | 86 | bool retro3d::Reader::IsOpen( void ) const 87 | { 88 | return m_is_open; 89 | } 90 | 91 | bool retro3d::Reader::IsEnd( void ) const 92 | { 93 | return m_in != nullptr ? m_in->eof() : true; 94 | } 95 | 96 | const std::string &retro3d::Reader::GetFile( void ) const 97 | { 98 | return m_file; 99 | } 100 | 101 | const std::string &retro3d::Reader::GetPath( void ) const 102 | { 103 | return m_path; 104 | } 105 | -------------------------------------------------------------------------------- /common/retro_assets.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_ASSETS_H 2 | #define RETRO_ASSETS_H 3 | 4 | #include 5 | #include "MiniLib/MTL/mtlAsset.h" 6 | #include "MiniLib/MTL/mtlStringMap.h" 7 | #include "../serial/retro_serialize.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | template < typename type_t > class Asset; 13 | 14 | template < typename type_t > 15 | class AssetLib 16 | { 17 | private: 18 | mtlStringMap< mtlShared > m_lib; 19 | mtlShared m_fallback; 20 | 21 | public: 22 | bool Exists(const mtlChars &id) const 23 | { 24 | return m_lib.GetEntry(id) != nullptr; 25 | } 26 | 27 | bool Exists(const mtlChars &id, mtlShared &out) 28 | { 29 | mtlShared *r = m_lib.GetEntry(id); 30 | if (r == nullptr) { 31 | out = mtlShared(); 32 | return false; 33 | } 34 | out = *r; 35 | return true; 36 | } 37 | 38 | void SetFallback(mtlShared fallback) 39 | { 40 | m_fallback = fallback; 41 | } 42 | 43 | mtlShared Fetch(const mtlChars &id) 44 | { 45 | mtlShared *r = m_lib.GetEntry(id); 46 | if (r == nullptr) { 47 | std::cout << "Error: Asset \""; 48 | for (int i = 0; i < id.GetSize(); ++i) { std::cout << id[i]; } 49 | std::cout << "\" not available (return fallback). "; 50 | mtlShared fallback; 51 | fallback.New(); 52 | *fallback.GetShared() = *m_fallback.GetShared(); 53 | return fallback; 54 | } 55 | return *r; 56 | } 57 | 58 | mtlShared FetchCopy(const mtlChars &id) 59 | { 60 | mtlShared *r = m_lib.GetEntry(id); 61 | if (r == nullptr) { 62 | std::cout << "Error: Asset \""; 63 | for (int i = 0; i < id.GetSize(); ++i) { std::cout << id[i]; } 64 | std::cout << "\" not available (return fallback). "; 65 | mtlShared fallback; 66 | fallback.New(); 67 | *fallback.GetShared() = *m_fallback.GetShared(); 68 | return fallback; 69 | } else { 70 | mtlShared c; 71 | c.New(); 72 | *c.GetShared() = *r->GetShared(); 73 | *r = c; 74 | } 75 | return *r; 76 | } 77 | 78 | void Store(const type_t &asset, const mtlChars &id) 79 | { 80 | mtlShared *new_entry = m_lib.CreateEntry(id); 81 | if (new_entry != nullptr) { 82 | mtlShared ref; 83 | ref.New(); 84 | *ref.GetShared() = asset; 85 | *new_entry = ref; 86 | } 87 | } 88 | 89 | void Store(mtlShared &asset, const mtlChars &id) 90 | { 91 | mtlShared *new_entry = m_lib.CreateEntry(id); 92 | if (new_entry != nullptr) { 93 | *new_entry = asset; 94 | } 95 | } 96 | }; 97 | 98 | template < typename type_t > 99 | class Asset : public retro3d::Serializeable 100 | { 101 | public: 102 | static AssetLib Library; 103 | }; 104 | 105 | } 106 | 107 | template < typename type_t > retro3d::AssetLib retro3d::Asset::Library; 108 | 109 | #endif // RETRO_ASSETS_H 110 | -------------------------------------------------------------------------------- /graphics/retro_light.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_LIGHT_H 2 | #define RETRO_LIGHT_H 3 | 4 | #include "retro_model.h" 5 | #include "../common/MiniLib/MML/mmlVector.h" 6 | #include "../common/retro_geom.h" 7 | #include "../common/retro_transform.h" 8 | #include "../physics/retro_collider.h" 9 | 10 | namespace retro3d 11 | { 12 | 13 | struct Light 14 | { 15 | enum FalloffMode { 16 | None, // no falloff 17 | Linear, // 1 at d=0, 0 at d=radius 18 | Distance, // semi-realistic light falloff (1/d) 19 | SquareDistance // realistic light falloff (1/d^2) 20 | }; 21 | 22 | enum Type { 23 | Ambient, 24 | Direction, 25 | Point, 26 | Spot 27 | }; 28 | 29 | mmlVector<3> origin = mmlVector<3>::Fill(0.0f); 30 | mmlVector<3> direction = retro3d::Transform::GetWorldForward(); 31 | mmlVector<3> color = mmlVector<3>::Fill(0.5f); 32 | float radius = 20.0f; 33 | float aperture = 1.0f; 34 | retro3d::AABB activation_aabb = { mmlVector<3>::Fill(0.0f), mmlVector<3>::Fill(20.0f) }; 35 | Type type = Light::Ambient; 36 | FalloffMode falloff = Light::None; 37 | 38 | float CalculateIntensityAtVertex(const mmlVector<3> &point, const mmlVector<3> &normal) const; 39 | mmlVector<3> GetLightDirection(const mmlVector<3> &point) const; 40 | retro3d::Light ApplyTransform(const retro3d::Transform &transform) const; 41 | }; 42 | 43 | class LightScene 44 | { 45 | private: 46 | struct TargetModel 47 | { 48 | const retro3d::Array< mmlVector<3> > *verts; 49 | const retro3d::Array< mmlVector<2> > *lightmap_uvs; 50 | const retro3d::Array< mmlVector<3> > *normals; 51 | const retro3d::Array< retro3d::FaceIndex > *faces; 52 | retro3d::PolyCollider collider; 53 | retro3d::Transform transform; 54 | }; 55 | 56 | struct Vertex 57 | { 58 | mmlVector<3> v; 59 | mmlVector<2> t; 60 | mmlVector<3> n; 61 | }; 62 | 63 | private: 64 | TargetModel m_target; 65 | mtlList< PolyCollider > m_geometry; 66 | mtlList< retro3d::Light > m_lights; 67 | float m_bias; 68 | bool m_has_target; 69 | bool m_use_dither; 70 | 71 | private: 72 | Vertex ToVertex(const retro3d::IndexVTN &i, float u_scale, float v_scale) const; 73 | bool IsIn(const mmlVector<3> &bcoord) const; 74 | 75 | public: 76 | LightScene( void ); 77 | 78 | void AddLight(const retro3d::Light &world_light); 79 | void AddGeometry(const retro3d::Array< mmlVector<3> > &v, const retro3d::Array< retro3d::FaceIndex > &f, const retro3d::Transform &obj_to_world); 80 | void SetTargetGeometry(const retro3d::Array< mmlVector<3> > *v, const retro3d::Array< mmlVector<2> > *t, const retro3d::Array< mmlVector<3> > *n, const retro3d::Array< retro3d::FaceIndex > *f, const retro3d::Transform &obj_to_world); 81 | 82 | void RenderLightmap(tiny3d::Image &out) const; 83 | void ClearScene( void ); 84 | 85 | void SetShadowBias(float bias); 86 | bool DitheringEnabled( void ) const; 87 | void ToggleDithering( void ); 88 | }; 89 | 90 | } 91 | 92 | #endif // RETRO_LIGHT_H 93 | -------------------------------------------------------------------------------- /serial/retro_config.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_CONFIG_H 2 | #define RETRO_CONFIG_H 3 | 4 | #include "../common/MiniLib/MTL/mtlParser.h" 5 | #include "../common/MiniLib/MTL/mtlStringMap.h" 6 | #include "retro_serialize.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | template < typename type_t > 12 | struct ParseValue 13 | { 14 | type_t value; 15 | bool success; 16 | operator bool( void ) const { return success; } 17 | }; 18 | 19 | template < typename type_t > 20 | ParseValue FromString(const mtlChars &str) 21 | { 22 | ParseValue o; 23 | o.success = o.value.Deserialize(str); 24 | return o; 25 | } 26 | 27 | template <> 28 | ParseValue FromString(const mtlChars &str) 29 | { 30 | ParseValue o; 31 | o.success = true; 32 | o.value = str; 33 | return o; 34 | } 35 | 36 | template <> 37 | ParseValue FromString(const mtlChars &str) 38 | { 39 | ParseValue o; 40 | o.success = str.ToInt(o.value); 41 | return o; 42 | } 43 | 44 | template <> 45 | ParseValue FromString(const mtlChars &str) 46 | { 47 | ParseValue o; 48 | o.success = str.ToFloat(o.value); 49 | return o; 50 | } 51 | 52 | template <> 53 | ParseValue FromString(const mtlChars &str) 54 | { 55 | ParseValue o; 56 | o.success = str.ToBool(o.value); 57 | return o; 58 | } 59 | 60 | class Configs 61 | { 62 | private: 63 | class Config 64 | { 65 | private: 66 | mtlStringMap m_map; 67 | 68 | public: 69 | template < typename type_t > ParseValue Get(const mtlChars &name) const; 70 | void Set(const mtlChars &name, const mtlChars &value); 71 | }; 72 | 73 | private: 74 | mtlString m_buffer; 75 | mtlStringMap m_map; 76 | 77 | public: 78 | template < typename type_t > ParseValue Get(const mtlChars &name) const; 79 | void Set(mtlChars name, mtlChars value); 80 | bool Read(const mtlChars &filename); 81 | bool Read(const mtlChars &filename, const mtlChars §ion); 82 | bool Write(const mtlChars &filename); 83 | void Clear( void ); 84 | }; 85 | 86 | template < typename type_t > 87 | ParseValue retro3d::Configs::Config::Get(const mtlChars &name) const 88 | { 89 | auto *e = m_map.GetEntry(name); 90 | return e != nullptr ? 91 | FromString(*e) : 92 | ParseValue{ type_t(), false }; 93 | } 94 | 95 | template < typename type_t > 96 | ParseValue retro3d::Configs::Get(const mtlChars &name) const 97 | { 98 | mtlSyntaxParser p; 99 | p.SetBuffer(name); 100 | mtlArray m; 101 | switch (p.Match("%s.%S %| %S", m)) { 102 | case 0: { 103 | m[0] = m[0].GetTrimmed(); 104 | m[1] = m[1].GetTrimmed(); 105 | auto *e = m_map.GetEntry(m[0].GetSize() > 0 ? m[0] : "global"); 106 | return e != nullptr ? e->Get(m[1]) : ParseValue{ type_t(), false }; 107 | } 108 | case 1: { 109 | m[0] = m[0].GetTrimmed(); 110 | auto *e = m_map.GetEntry("global"); 111 | return e != nullptr ? e->Get(m[0]) : ParseValue{ type_t(), false }; 112 | } 113 | } 114 | return ParseValue{ type_t(), false }; 115 | } 116 | 117 | } 118 | 119 | #endif // RETRO_CONFIG_H 120 | -------------------------------------------------------------------------------- /common/retro_transform.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_TRANSFORM_H 2 | #define RETRO_TRANSFORM_H 3 | 4 | #include 5 | #include "MiniLib/MML/mmlVector.h" 6 | #include "MiniLib/MML/mmlMatrix.h" 7 | #include "MiniLib/MTL/mtlPointer.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | class Transform : public mmlMatrix<4,4> 13 | { 14 | public: 15 | enum Space 16 | { 17 | Space_Object, 18 | Space_World, 19 | Space_View, 20 | Space_Screen, 21 | Space_Tangent 22 | }; 23 | 24 | private: 25 | mtlShared m_parent; 26 | mutable mmlMatrix<4,4> m_inv; 27 | mutable mmlMatrix<3,3> m_rot; 28 | uint32_t m_space_from; 29 | uint32_t m_space_to; // Spaces can be used to determine if matrix operations are formally correct 30 | mutable bool m_inv_updated; 31 | mutable bool m_rot_updated; 32 | 33 | private: 34 | bool SelfRef(const retro3d::Transform *t) const; 35 | 36 | public: 37 | static mmlVector<3> GetWorldRight( void ); 38 | static mmlVector<3> GetWorldUp( void ); 39 | static mmlVector<3> GetWorldForward( void ); 40 | static mmlVector<3> GetWorldAxis(int axis_index); 41 | static std::string GetWorldAxisName(int axis_index); 42 | 43 | public: 44 | Transform(uint32_t space_from = Space_Object, uint32_t space_to = Space_World); 45 | Transform(const mmlMatrix<3,3> &basis, const mmlVector<3> &position); 46 | Transform(const mmlMatrix<4,4> &transform); 47 | Transform &operator=(const retro3d::Transform &transform) = default; 48 | Transform &operator=(const mmlMatrix<4,4> &transform); 49 | 50 | void SetParent(mtlShared parent); 51 | void OrphanTransform( void ); 52 | 53 | void SetTransform(const mmlMatrix<3,3> &basis, const mmlVector<3> &position); 54 | void SetTransform(const mmlMatrix<4,4> &transform); 55 | 56 | void SetRotation(const mmlMatrix<3,3> &rotation); 57 | void SetBasis(const mmlMatrix<3,3> &basis); 58 | void SetPosition(const mmlVector<3> &position); 59 | 60 | void NormalizeScale( void ); 61 | void SetScale(const mmlVector<3> &xyz); 62 | void SetScale(float scale); 63 | 64 | mmlMatrix<4,4> GetMatrix( void ) const; 65 | mmlMatrix<4,4> GetInvMatrix( void ) const; 66 | mmlMatrix<3,3> GetRotation( void ) const; 67 | mmlMatrix<3,3> GetBasis( void ) const; 68 | mmlVector<3> GetPosition( void ) const; 69 | mmlVector<3> GetScale( void ) const; 70 | mmlVector<3> GetRight( void ) const; 71 | mmlVector<3> GetUp( void ) const; 72 | mmlVector<3> GetForward( void ) const; 73 | retro3d::Transform GetInvTransform( void ) const; 74 | 75 | mmlMatrix<4,4> GetFinalMatrix( void ) const; 76 | 77 | mmlVector<3> TransformPoint(const mmlVector<3> &point) const; 78 | mmlVector<3> TransformVector(const mmlVector<3> &vec) const; 79 | mmlVector<3> TransformNormal(const mmlVector<3> &normal) const; 80 | 81 | mmlVector<3> InverseTransformPoint(const mmlVector<3> &point) const; 82 | mmlVector<3> InverseTransformVector(const mmlVector<3> &vec) const; 83 | mmlVector<3> InverseTransformNormal(const mmlVector<3> &normal) const; 84 | 85 | // LookAt 86 | }; 87 | 88 | typedef mtlShared< retro3d::Transform > SharedTransform; 89 | 90 | } 91 | 92 | #endif // RETRO_TRANSFORM_H 93 | -------------------------------------------------------------------------------- /ecs/components/retro_audio_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_audio_component.h" 2 | #include "../../retro3d.h" 3 | #include "../components/retro_transform_component.h" 4 | 5 | namespace retro3d { retro_register_component(AudioComponent) } 6 | 7 | void retro3d::AudioComponent::OnUpdate( void ) 8 | { 9 | if (IsPlaying() == true) { 10 | m_time_stamp += GetObject()->DeltaTime(); // NOTE BUG: This is completely inaccurate for time scaled objects, i.e. sound needs to play slower or faster depending on scale 11 | if (m_time_stamp > double(m_voice.GetSound()->GetDuration())) { 12 | const int32_t remaining_loops = m_loops - 1; 13 | Stop(); 14 | if (remaining_loops < 0) { 15 | Play(-1); 16 | } else { 17 | Play(remaining_loops); 18 | } 19 | } 20 | } 21 | } 22 | 23 | void retro3d::AudioComponent::OnDestroy( void ) 24 | { 25 | Pause(); 26 | } 27 | 28 | void retro3d::AudioComponent::SetAudioIndex(int32_t audio_index) 29 | { 30 | m_audio_index = audio_index; 31 | } 32 | 33 | int32_t retro3d::AudioComponent::GetAudioIndex( void ) const 34 | { 35 | return m_audio_index; 36 | } 37 | 38 | void retro3d::AudioComponent::Unlock( void ) 39 | { 40 | m_audio_index = -1; 41 | } 42 | 43 | bool retro3d::AudioComponent::IsLocked( void ) const 44 | { 45 | return m_audio_index > -1; 46 | } 47 | 48 | retro3d::AudioComponent::AudioComponent( void ) : mtlInherit(this), m_time_stamp(0.0), m_synthed(), m_audio_index(-1), m_loops(0), m_playing(false), m_moving_emitter(false) 49 | {} 50 | 51 | void retro3d::AudioComponent::Play(int32_t times) 52 | { 53 | if (times == 0) { 54 | if (IsPlaying() == true) { 55 | Stop(); 56 | } 57 | return; 58 | } 59 | 60 | retro3d::TransformComponent *t = GetObject()->GetComponent(); 61 | if (t == nullptr) { 62 | SetAudioIndex(GetEngine()->GetSoundDevice()->Play(m_voice, mmlMatrix<4,4>::Identity(), m_time_stamp)); 63 | } else if (m_moving_emitter == true) { 64 | SetAudioIndex(GetEngine()->GetSoundDevice()->Play(m_voice, t->GetTransform(), m_time_stamp)); 65 | } else { 66 | SetAudioIndex(GetEngine()->GetSoundDevice()->Play(m_voice, t->GetTransform()->GetFinalMatrix(), m_time_stamp)); 67 | } 68 | m_playing = IsLocked(); 69 | m_loops = (IsPlaying() == true) ? times : 0; 70 | } 71 | 72 | void retro3d::AudioComponent::Reset(double to_time) 73 | { 74 | m_time_stamp = to_time; 75 | } 76 | 77 | void retro3d::AudioComponent::Pause( void ) 78 | { 79 | m_playing = false; 80 | GetEngine()->GetSoundDevice()->Kill(m_audio_index); 81 | Unlock(); 82 | } 83 | 84 | void retro3d::AudioComponent::Stop( void ) 85 | { 86 | Pause(); 87 | m_time_stamp = 0.0; 88 | m_loops = 0; 89 | } 90 | 91 | bool retro3d::AudioComponent::IsPlaying( void ) const 92 | { 93 | return m_playing; 94 | } 95 | 96 | retro3d::Voice &retro3d::AudioComponent::GetVoice( void ) 97 | { 98 | return m_voice; 99 | } 100 | 101 | const retro3d::Voice &retro3d::AudioComponent::GetVoice( void ) const 102 | { 103 | return m_voice; 104 | } 105 | 106 | bool retro3d::AudioComponent::IsMovingEmitter( void ) const 107 | { 108 | return m_moving_emitter; 109 | } 110 | 111 | void retro3d::AudioComponent::ToggleMovingEmitter( void ) 112 | { 113 | m_moving_emitter = !m_moving_emitter; 114 | } 115 | -------------------------------------------------------------------------------- /ecs/retro_component.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_COMPONENT_H 2 | #define RETRO_COMPONENT_H 3 | 4 | #include 5 | #include "../serial/retro_serialize.h" 6 | #include "../common/retro_factory.h" 7 | #include "../common/retro_containers.h" 8 | 9 | namespace retro3d 10 | { 11 | 12 | class Entity; 13 | class Engine; 14 | class RenderDevice; 15 | class SoundDevice; 16 | class InputDevice; 17 | 18 | class Component : public mtlInherit 19 | { 20 | friend class Engine; 21 | 22 | private: 23 | retro3d::Entity *m_object; 24 | int32_t m_is_active; 25 | bool m_should_destroy; 26 | 27 | protected: 28 | virtual void OnSpawn( void ); 29 | virtual void OnUpdate( void ); 30 | virtual void OnCollision(retro3d::Entity&); 31 | virtual void OnDestroy( void ); 32 | 33 | public: 34 | Component( void ); 35 | virtual ~Component( void ); 36 | 37 | Component(const Component&) = delete; 38 | Component &operator=(const Component&) = delete; 39 | 40 | void Destroy( void ); 41 | bool IsDestroyed( void ) const; 42 | 43 | bool IsActive( void ) const; 44 | void Deactivate( void ); 45 | void Activate( void ); 46 | 47 | retro3d::Entity *GetObject( void ); 48 | const retro3d::Entity *GetObject( void ) const; 49 | 50 | retro3d::Engine *GetEngine( void ); 51 | const retro3d::Engine *GetEngine( void ) const; 52 | 53 | retro3d::RenderDevice *GetRenderer( void ); 54 | const retro3d::RenderDevice *GetRenderer( void ) const; 55 | retro3d::SoundDevice *GetSoundDevice( void ); 56 | const retro3d::SoundDevice *GetSoundDevice( void ) const; 57 | retro3d::InputDevice *GetInput( void ); 58 | const retro3d::InputDevice *GetInput( void ) const; 59 | 60 | // template < typename component_t > component_t *AddComponent( void ); 61 | // template < typename component_t > void RemoveComponent( void ); 62 | // template < typename component_t > component_t *GetComponent( void ); 63 | // template < typename component_t > const component_t *GetComponent( void ) const; 64 | }; 65 | 66 | } 67 | 68 | // Recursive dependency makes this impossible without refactoring... 69 | /*#include "retro_entity.h" 70 | 71 | template < typename component_t > 72 | component_t *retro3d::Component::AddComponent( void ) 73 | { 74 | return GetObject()->AddComponent(); 75 | } 76 | 77 | template < typename component_t > 78 | void retro3d::Component::RemoveComponent( void ) 79 | { 80 | return GetObject()->RemoveComponent(); 81 | } 82 | 83 | template < typename component_t > 84 | component_t *retro3d::Component::GetComponent( void ) 85 | { 86 | return GetObject()->GetComponent(); 87 | } 88 | 89 | template < typename component_t > 90 | const component_t *retro3d::Component::GetComponent( void ) const 91 | { 92 | return GetObject()->GetComponent(); 93 | }*/ 94 | 95 | #define retro_component(component_class_name) class component_class_name : public mtlInherit< retro3d::Component, component_class_name > 96 | #define retro_register_component(component_class_name) \ 97 | retro3d::Component *Alloc_##component_class_name( void ) { return new component_class_name; } \ 98 | static const bool is_##component_class_name##_added = retro3d::Singleton< retro3d::Factory< retro3d::Component > >::Instance().AddSchematic(#component_class_name, Alloc_##component_class_name); \ 99 | 100 | #endif // RETRO_COMPONENT_H 101 | -------------------------------------------------------------------------------- /common/retro_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_DEFS_H 2 | #define RETRO_DEFS_H 3 | 4 | #include 5 | #include "MiniLib/MML/mmlMath.h" 6 | #include "MiniLib/MTL/mtlPointer.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | template < typename num_t, typename real_t > 12 | num_t Cyclerp(const num_t &a, const num_t &b, const real_t &x) 13 | { 14 | return mmlLerp( 15 | a, b, 16 | real_t(1.0) - (mmlCos(x * mmlPI) * real_t(0.5) + real_t(0.5)) 17 | ); 18 | } 19 | 20 | template < typename num_t, typename real_t > 21 | num_t Accelerp(const num_t &a, const num_t &b, const real_t &x) 22 | { 23 | return Cyclerp( 24 | a, b, 25 | mmlClamp(real_t(0.0), x, real_t(1.0)) 26 | ); 27 | } 28 | 29 | template < typename num_t, typename real_t > 30 | num_t Sigmoid(const num_t &a, const num_t &b, const real_t &x) 31 | { 32 | return mmlLerp(a, b, x / (real_t(1.0) + mmlAbs(x))); 33 | } 34 | 35 | template < typename real_t > 36 | real_t Sigmoid(const real_t &x) 37 | { 38 | return Sigmoid(real_t(0.0), real_t(1.0), x); 39 | } 40 | 41 | template < typename num_t, typename real_t > 42 | num_t Jerklerp(const num_t &a, const num_t &b, const real_t &x) 43 | { 44 | return Accelerp(b, a, x); 45 | } 46 | 47 | template < typename num_t, typename real_t > 48 | num_t Berp(const num_t &a, const num_t &b, const num_t &c, const real_t &x) 49 | { 50 | return mmlLerp(mmlLerp(a, c), mmlLerp(c, b), x); 51 | } 52 | 53 | template < typename type_t > 54 | using Schematic = type_t (*)(void); 55 | 56 | class IProcedure 57 | { 58 | public: 59 | virtual bool IsNull( void ) const = 0; 60 | virtual void operator()( void ) = 0; 61 | }; 62 | 63 | class Procedure : public IProcedure 64 | { 65 | public: 66 | typedef void (*Function)(void); 67 | 68 | private: 69 | Function m_fn; 70 | 71 | public: 72 | Procedure( void ) : m_fn(nullptr) {} 73 | Procedure(Function fn) : m_fn(fn) {} 74 | Procedure(const Procedure&) = default; 75 | Procedure &operator=(const Procedure&) = default; 76 | 77 | bool IsNull( void ) const { return m_fn == nullptr; } 78 | void operator()( void ) { if (m_fn != nullptr) { m_fn(); } } 79 | }; 80 | 81 | template < typename class_t > 82 | class ClassProcedure : public IProcedure 83 | { 84 | public: 85 | typedef void (class_t::*MemberFunction)(void); 86 | 87 | private: 88 | class_t *m_this; 89 | MemberFunction m_fn; 90 | 91 | public: 92 | ClassProcedure( void ) : m_this(nullptr), m_fn(nullptr) {} 93 | ClassProcedure(class_t object, MemberFunction fn) : m_this(object), m_fn(fn) {} 94 | ClassProcedure(const ClassProcedure&) = default; 95 | ClassProcedure &operator=(const ClassProcedure&) = default; 96 | 97 | bool IsNull( void ) const { return m_this == nullptr || m_fn == nullptr; } 98 | void operator()( void ) { if (m_this != nullptr && m_fn != nullptr) { (m_this->*m_fn)(); } } 99 | }; 100 | 101 | inline mtlShared CreateProcedure(retro3d::Procedure::Function fn) 102 | { 103 | auto proc = mtlShared::Create(); 104 | *proc.GetShared() = retro3d::Procedure(fn); 105 | return proc; 106 | } 107 | 108 | template < typename class_t > 109 | inline mtlShared CreateProcedure(class_t *object, typename retro3d::ClassProcedure::MemberFunction fn) 110 | { 111 | auto proc = mtlShared< retro3d::ClassProcedure >::Create(); 112 | *proc.GetShared() = retro3d::ClassProcedure(object, fn); 113 | return proc; 114 | } 115 | 116 | } 117 | 118 | #endif // RETRO_DEFS_H 119 | -------------------------------------------------------------------------------- /frontend/retro_input_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_INPUT_DEVICE_H 2 | #define RETRO_INPUT_DEVICE_H 3 | 4 | #include 5 | #include "retro_device.h" 6 | #include "../common/MiniLib/MTL/mtlArray.h" 7 | #include "../common/MiniLib/MTL/mtlStringMap.h" 8 | #include "../api/tiny3d/tiny_system.h" 9 | #include "../common/retro_time.h" 10 | 11 | namespace retro3d 12 | { 13 | 14 | class InputMap 15 | { 16 | private: 17 | mtlStringMap m_binds; 18 | 19 | public: 20 | void Bind(const mtlChars &action, uint64_t input_code); 21 | void Unbind(const mtlChars &action); 22 | void UnbindAll( void ); 23 | const uint64_t *GetInput(const mtlChars &action) const; 24 | }; 25 | 26 | class InputDevice : public retro3d::Device 27 | { 28 | public: 29 | struct Input 30 | { 31 | float activation; // usually 0.0 - 1.0, although an axis would probably give -1.0 - 1.0 32 | float delta; // the difference in activation since last update 33 | double time; // the amount of time the state has been non-zero or zero (changes reset timer) 34 | bool awoken; // 1 on the frame when inactive input becomes active, 0 all other times 35 | }; 36 | 37 | private: 38 | const InputMap *m_binds; 39 | 40 | protected: 41 | mtlArray m_state; // fixed length, number of inputs on the device 42 | mtlArray m_delta; // all changes in input, in order (replaces m_state?) 43 | 44 | protected: 45 | void CreateStateTable(uint64_t size); 46 | 47 | public: 48 | InputDevice( void ); 49 | virtual ~InputDevice( void ); 50 | 51 | virtual bool Init( void ) = 0; 52 | 53 | virtual bool UserQuit( void ) const = 0; 54 | virtual uint64_t GetRealTimeMS( void ) const = 0; 55 | virtual uint64_t GetProgramTimeMS( void ) const = 0; 56 | virtual void Sleep(retro3d::Time time) const = 0; 57 | virtual void ToggleMouseCursorLock( void ) = 0; 58 | virtual bool IsMouseCursorLocked( void ) const = 0; 59 | virtual void ToggleMouseCursorVisibility( void ) = 0; 60 | virtual bool IsMouseCursorVisible( void ) const = 0; 61 | virtual void Update( void ) = 0; 62 | 63 | void SetInputMap(const retro3d::InputMap *binds); 64 | Input GetState(const mtlChars &action) const; 65 | }; 66 | 67 | 68 | 69 | struct Keyboard 70 | { 71 | static constexpr uint64_t FIRST = 0; 72 | enum Input 73 | { 74 | A = Keyboard::FIRST,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z, 75 | KP0,KP1,KP2,KP3,KP4,KP5,KP6,KP7,KP8,KP9, 76 | NP0,NP1,NP2,NP3,NP4,NP5,NP6,NP7,NP8,NP9,NPPlus,NPMinus,NPMul,NPDiv,NPEnter, 77 | F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12, 78 | Space,Enter,Escape,Backspace,LShift,RShift,LControl,RControl,LAlt,RAlt, 79 | Up,Down,Left,Right, 80 | Tab, 81 | LAST 82 | }; 83 | static constexpr uint64_t COUNT = LAST - FIRST + 1; 84 | }; 85 | 86 | struct Mouse 87 | { 88 | static constexpr uint64_t FIRST = Keyboard::LAST; 89 | enum Input 90 | { 91 | Left = Mouse::FIRST, Right, Mid, 92 | WheelUp, WheelDown, 93 | MoveX, MoveY, 94 | LAST 95 | }; 96 | static constexpr uint64_t COUNT = LAST - FIRST + 1; 97 | }; 98 | 99 | struct Controller 100 | { 101 | static constexpr uint64_t FIRST = Mouse::LAST; 102 | enum Input 103 | { 104 | A = Controller::FIRST, B, X, Y, 105 | LTrigger, RTrigger, 106 | LBumper, RBumper, 107 | LStickX, LStickY, 108 | RStickX, RStickY, 109 | Up, Down, Left, Right, 110 | GyroX, GyroY, GyroZ, 111 | Start, Select, 112 | LAST 113 | }; 114 | static constexpr uint64_t COUNT = LAST - FIRST + 1; 115 | }; 116 | 117 | static constexpr uint64_t INPUT_COUNT = retro3d::Keyboard::COUNT + retro3d::Mouse::COUNT + retro3d::Controller::COUNT; 118 | 119 | } 120 | 121 | #endif // RETRO_INPUT_DEVICE_H 122 | -------------------------------------------------------------------------------- /ecs/retro_system.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SYSTEM_H 2 | #define RETRO_SYSTEM_H 3 | 4 | #include 5 | #include "../common/MiniLib/MTL/mtlType.h" 6 | #include "retro_component.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | class Engine; 12 | 13 | class ISystem : public mtlBase 14 | { 15 | friend class Engine; 16 | 17 | private: 18 | retro3d::Engine *m_engine; 19 | int32_t m_is_active; 20 | bool m_should_destroy; 21 | 22 | protected: 23 | virtual void OnSpawn( void ) = 0; 24 | virtual void OnUpdate( void ) = 0; 25 | virtual void OnDestroy( void ) = 0; 26 | 27 | virtual void OnSpawn(retro3d::Component *c) = 0; 28 | virtual void OnUpdate(retro3d::Component *c) = 0; 29 | virtual void OnDestroy(retro3d::Component *c) = 0; 30 | 31 | public: 32 | ISystem( void ); 33 | virtual ~ISystem( void ); 34 | 35 | ISystem(const ISystem&) = delete; 36 | ISystem &operator=(const ISystem&) = delete; 37 | 38 | void Destroy( void ); 39 | bool IsDestroyed( void ) const; 40 | 41 | bool IsActive( void ) const; 42 | void Deactivate( void ); 43 | void Activate( void ); 44 | 45 | retro3d::Engine *GetEngine( void ); 46 | const retro3d::Engine *GetEngine( void ) const; 47 | 48 | virtual uint64_t GetComponentClassType( void ) const = 0; 49 | }; 50 | 51 | template < typename component_t > 52 | class System : public mtlInherit< ISystem, System > 53 | { 54 | protected: 55 | void OnSpawn( void ) override; 56 | void OnUpdate( void ) override; 57 | void OnDestroy( void ) override; 58 | 59 | void OnSpawn(retro3d::Component *c) override; 60 | void OnUpdate(retro3d::Component *c) override; 61 | void OnDestroy(retro3d::Component *c) override; 62 | 63 | virtual void OnSpawn(component_t &c); 64 | virtual void OnUpdate(component_t &c); 65 | virtual void OnDestroy(component_t &c); 66 | 67 | public: 68 | System( void ); 69 | 70 | uint64_t GetComponentClassType( void ) const override; 71 | }; 72 | 73 | template < typename component_t > 74 | retro3d::System::System( void ) : 75 | mtlInherit< ISystem, System >(this) 76 | {} 77 | 78 | template < typename component_t > 79 | void retro3d::System::OnSpawn( void ) 80 | {} 81 | 82 | template < typename component_t > 83 | void retro3d::System::OnUpdate( void ) 84 | {} 85 | 86 | template < typename component_t > 87 | void retro3d::System::OnDestroy( void ) 88 | {} 89 | 90 | template < typename component_t > 91 | void retro3d::System::OnSpawn(retro3d::Component *c) 92 | { 93 | OnSpawn(*mtlCast(c)); 94 | } 95 | 96 | template < typename component_t > 97 | void retro3d::System::OnUpdate(retro3d::Component *c) 98 | { 99 | OnUpdate(*mtlCast(c)); 100 | } 101 | 102 | template < typename component_t > 103 | void retro3d::System::OnDestroy(retro3d::Component *c) 104 | { 105 | OnDestroy(*mtlCast(c)); 106 | } 107 | 108 | template < typename component_t > 109 | void retro3d::System::OnSpawn(component_t&) 110 | {} 111 | 112 | template < typename component_t > 113 | void retro3d::System::OnUpdate(component_t&) 114 | {} 115 | 116 | template < typename component_t > 117 | void retro3d::System::OnDestroy(component_t&) 118 | {} 119 | 120 | template < typename component_t > 121 | uint64_t retro3d::System::GetComponentClassType( void ) const 122 | { 123 | return component_t::GetClassType(); 124 | } 125 | 126 | } 127 | 128 | #define retro_system(system_class_name, component_class_name) class system_class_name : public mtlInherit< retro3d::System, system_class_name > 129 | 130 | #endif // RETRO_SYSTEM_H 131 | -------------------------------------------------------------------------------- /backend/null_render_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_NULL_RENDER_H 2 | #define RETRO_NULL_RENDER_H 3 | 4 | #include "../frontend/retro_render_device.h" 5 | 6 | namespace platform 7 | { 8 | 9 | class NullRenderDevice : public retro3d::RenderDevice 10 | { 11 | public: 12 | bool Init( void ) override { return true; } 13 | 14 | void SetDepthClip(float, float, float) override {} 15 | bool CreateRenderSurface(uint32_t, uint32_t) override { return true; } 16 | void DestroyRenderSurface( void ) override {} 17 | void SetViewTransform(const mmlMatrix<4,4>&) override {} 18 | void SetViewTransform(const mmlMatrix<4,4>*) override {} 19 | void SetViewTransform(const retro3d::Camera&) override {} 20 | mmlMatrix<4,4> GetViewTransform( void ) const override { return mmlMatrix<4,4>::Identity(); } 21 | mmlMatrix<4,4> GetInverseViewTransform( void ) const override { return mmlMatrix<4,4>::Identity(); } 22 | void RenderModel(const retro3d::Model&, const mmlMatrix<4,4>&, LightMode, RenderMode) override {} 23 | void RenderModel(const retro3d::Model&, const mmlMatrix<4,4>*, LightMode, RenderMode) override {} 24 | void RenderDisplayModel(const retro3d::DisplayModel&, const mmlMatrix<4,4>&, LightMode, RenderMode) override {} 25 | void RenderSpritePlane(const retro3d::Model&, const mmlMatrix<4,4>&, LightMode, RenderMode) override {} 26 | void RenderSpritePlane(const retro3d::Model&, const mmlMatrix<4,4>*, LightMode, RenderMode) override {} 27 | void RenderLight(const retro3d::Light&) override {} 28 | void RenderAABB(const retro3d::AABB&, const mmlMatrix<4,4>&, const mmlVector<3>&, bool) override {} 29 | void RenderAABB(const retro3d::AABB&, const mmlMatrix<4,4>*, const mmlVector<3>&, bool) override {} 30 | void RenderViewFrustum(const retro3d::Frustum&, const mmlMatrix<4,4>&, const mmlVector<3>&) override {} 31 | void RenderViewFrustum(const retro3d::Frustum&, const mmlMatrix<4,4>*, const mmlVector<3>&) override {} 32 | void RenderOverlay(const tiny3d::Overlay&, const retro3d::Rect&, const retro3d::Rect&) override {} 33 | RenderDevice &RenderText(const std::string&, const mmlVector<3>&) override { return *this; } 34 | RenderDevice &RenderText(int64_t, const mmlVector<3>&) override { return *this; } 35 | RenderDevice &RenderText(uint64_t, const mmlVector<3>&) override { return *this; } 36 | RenderDevice &RenderText(double, const mmlVector<3>&) override { return *this; } 37 | RenderDevice &RenderText(const std::string&, tiny3d::Point, uint32_t, const mmlVector<3>&) override { return *this; } 38 | RenderDevice &RenderText(int64_t, tiny3d::Point, uint32_t, const mmlVector<3>&) override { return *this; } 39 | RenderDevice &RenderText(uint64_t, tiny3d::Point, uint32_t, const mmlVector<3>&) override { return *this; } 40 | RenderDevice &RenderText(double, tiny3d::Point, uint32_t, const mmlVector<3>&) override { return *this; } 41 | void FinishRender(bool = true) override {} 42 | void ToggleDepthView( void ) override {} 43 | bool DepthViewEnabled() const override { return false; } 44 | uint32_t GetRenderWidth( void ) const override { return 0; } 45 | uint32_t GetRenderHeight( void ) const override { return 0; } 46 | bool ToTexture(retro3d::Texture&) const override { return false; } 47 | bool SetSkyBox(const tiny3d::Image&, const tiny3d::Image&, const tiny3d::Image&, const tiny3d::Image&, const tiny3d::Image&, const tiny3d::Image&) override { return false; } 48 | void ToggleSkybox( void ) override {} 49 | bool SkyboxEnabled( void ) const override { return false; } 50 | float GetHorizontalFieldOfView( void ) const override { return 0.0f; } 51 | float GetVerticalFieldOfView( void ) const override { return 0.0f; } 52 | void SetHorizontalFieldOfView(float) override {} 53 | retro3d::Frustum GetViewFrustum( void ) const override { return retro3d::Frustum(); } 54 | 55 | void Debug_RenderTriangle(const retro3d::Vertex&, const retro3d::Vertex&, const retro3d::Vertex&, const mmlMatrix<4,4>&, const mmlMatrix<4,4>&, const retro3d::Texture*, LightMode) override {}; 56 | }; 57 | 58 | } 59 | 60 | #endif // RETRO_NULL_RENDER_H 61 | -------------------------------------------------------------------------------- /audio/retro_sound.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_SOUND_H 2 | #define RETRO_SOUND_H 3 | 4 | #include 5 | #include "../common/retro_assets.h" 6 | #include "../common/retro_containers.h" 7 | 8 | namespace retro3d 9 | { 10 | 11 | //class SoundSection {}; // class for representing a timed section of a sound (think mtlChars and mtlString) 12 | 13 | class Sound : public retro3d::Asset< retro3d::Sound > 14 | { 15 | public: 16 | enum SampleFormat 17 | { 18 | SampleFormat_UINT8 = sizeof(uint8_t) * CHAR_BIT, 19 | SampleFormat_INT16 = sizeof(int16_t) * CHAR_BIT 20 | }; 21 | 22 | enum Channels 23 | { 24 | Channels_Mono = 1, 25 | Channels_Stereo = 2 26 | }; // Number of output channels 27 | 28 | struct Format 29 | { 30 | Channels num_channels; 31 | uint32_t sample_rate; // samples per second 32 | SampleFormat sample_format; 33 | }; 34 | 35 | union Sample 36 | { 37 | enum Channels 38 | { 39 | Left, 40 | Right, 41 | ChannelCount 42 | }; 43 | float channels[ChannelCount]; // -1.0 - 1.0 44 | struct { 45 | float left, right; 46 | } channel; 47 | }; 48 | 49 | struct Debug_Sample 50 | { 51 | int16_t left; 52 | int16_t right; 53 | }; 54 | 55 | union SampleDataPointer 56 | { 57 | uint8_t *u8; 58 | int16_t *i16; 59 | }; 60 | 61 | private: 62 | retro3d::Array< uint8_t > m_samples; // uncompressed PCM samples 63 | SampleDataPointer m_sample_ptr; 64 | Format m_format; 65 | 66 | private: 67 | Sample DecodeU8(uint32_t sample_index) const; 68 | Sample DecodeI16(uint32_t sample_index) const; 69 | uint8_t EncodeU8(float channel) const; 70 | int16_t EncodeI16(float channel) const; 71 | 72 | public: 73 | Sound( void ); 74 | Sound(uint32_t num_samples, const Sound::Format &format); 75 | Sound(double duration, const Sound::Format &format); 76 | explicit Sound(uint32_t num_samples); 77 | explicit Sound(double duration); 78 | Sound(const Sound &s); 79 | Sound &operator=(const Sound &s); 80 | 81 | SampleDataPointer GetSampleData( void ) const; 82 | uint32_t GetSampleCount( void ) const; 83 | uint32_t GetRawByteCount( void ) const; 84 | Sample GetSampleFromIndex(uint32_t sample_index) const; 85 | Sample GetSampleFromTime(double timestamp) const; 86 | uint32_t GetChannelCount( void ) const; 87 | uint32_t GetSampleRate( void ) const; 88 | uint32_t GetBitRate( void ) const; 89 | uint32_t GetBitsPerSample( void ) const; 90 | double GetDuration( void ) const; 91 | uint32_t GetBytesPerChannel( void ) const; 92 | uint32_t GetBytesPerSample( void ) const; // Same as GetBlockAlign 93 | uint32_t GetByteRate( void ) const; 94 | 95 | uint32_t GetBitsPerSecond( void ) const; // Same as GetBitRate 96 | uint32_t GetBytesPerSecond( void ) const; // Same as GetByteRate 97 | uint32_t GetSamplesPerSecond( void ) const; // Same as GetSampleRate 98 | 99 | void CreateDuration(double duration, const Sound::Format &format); 100 | void CreateSamples(uint32_t num_samples, const Sound::Format &format); 101 | void CreateDuration(double duration); 102 | void CreateSamples(uint32_t num_samples); 103 | void Destroy( void ); 104 | void SetSample(uint32_t sample_index, const Sound::Sample &sample); 105 | 106 | void Copy(const Sound &s); 107 | 108 | uint32_t GetSampleIndex(double timestamp) const; 109 | double GetTimeStamp(uint32_t sample_index) const; 110 | 111 | // void Mix(const Sound &sample); 112 | void Scale(double duration_scalar); // BUG: Does not work. 113 | void MirrorChannels( void ); 114 | // void Render(float from_time, float to_time, float l_vol, float r_vol, retro3d::Sound &dst); // renders a stretched time interval with the given parameters to dst (in the format of dst) 115 | 116 | static void Convert(const Sound &src, Sound &dst, const Sound::Format &target_format); 117 | void Convert(const Sound::Format &target_format); 118 | 119 | Debug_Sample Debug_GetSample(uint32_t sample_index) const; 120 | }; 121 | 122 | } 123 | 124 | #endif // RETRO_SOUND_H 125 | -------------------------------------------------------------------------------- /serial/retro_import.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_LOADERS_H 2 | #define RETRO_LOADERS_H 3 | 4 | #include 5 | #include "../common/MiniLib/MTL/mtlArray.h" 6 | #include "../common/MiniLib/MTL/mtlStringMap.h" 7 | #include "../common/MiniLib/MML/mmlVector.h" 8 | #include "../api/tiny3d/tiny_image.h" 9 | #include "../api/tiny3d/tiny_texture.h" 10 | #include "../graphics/retro_model.h" 11 | #include "../common/retro_containers.h" 12 | #include "../audio/retro_sound.h" 13 | #include "retro_reader.h" 14 | 15 | namespace retro3d 16 | { 17 | 18 | std::string GetDirectory(const std::string &path); 19 | std::string GetFileName(const std::string &path); 20 | std::string GetFileNameWithExtension(const std::string &path); 21 | std::string GetFileExtension(const std::string &dir); 22 | 23 | void CreateDefaultImage(tiny3d::Image &img); 24 | void CreateDefaultModel(retro3d::Array< mmlVector<3> > *v, retro3d::Array< mmlVector<2> > *t, retro3d::Array< mmlVector<3> > *n, retro3d::Array *m); 25 | void CreateDefaultSound(retro3d::Sound &sfx); 26 | 27 | bool FileExists(const std::string &file); 28 | 29 | struct MTL_Meta 30 | { 31 | std::string name; 32 | std::string map_Kd; 33 | mmlVector<3> Kd; 34 | }; 35 | 36 | // bool LoadMTL(const std::string &file, MTL_Meta &mtl); 37 | 38 | struct OBJ_Meta 39 | { 40 | struct Object 41 | { 42 | std::string name; 43 | uint32_t f_count; 44 | }; 45 | retro3d::Array o; 46 | uint32_t v_count; 47 | uint32_t t_count; 48 | uint32_t n_count; 49 | uint32_t f_count; 50 | }; 51 | bool LoadOBJMeta(retro3d::Reader &reader, retro3d::OBJ_Meta &obj); 52 | bool LoadOBJMeta(const std::string &file, retro3d::OBJ_Meta &obj); 53 | bool LoadOBJ(retro3d::Reader &reader, retro3d::Array< mmlVector<3> > *v, retro3d::Array< mmlVector<2> > *t, retro3d::Array< mmlVector<3> > *n, retro3d::Array *m); 54 | bool LoadOBJ(const std::string &file, retro3d::Array< mmlVector<3> > *v, retro3d::Array< mmlVector<2> > *t, retro3d::Array< mmlVector<3> > *n, retro3d::Array *m); 55 | bool SaveOBJ(const std::string &file, const retro3d::Array< mmlVector<3> > &v, const retro3d::Array< mmlVector<2> > *t, const retro3d::Array< mmlVector<3> > *n, const retro3d::Array &m); 56 | 57 | bool LoadBMP(const std::string &file, tiny3d::Image &img, bool improve_gradients = true); 58 | 59 | //struct TGA_Header { width, height, bpp, etc... }; 60 | 61 | //bool LoadTGAHeader(const std::string &file, retro3d::TGA_Header &header); 62 | bool LoadTGA(retro3d::Reader &reader, tiny3d::Image &img, bool improve_gradients = true); 63 | bool LoadTGA(const std::string &file, tiny3d::Image &img, bool improve_gradients = true); 64 | bool SaveTGA(const std::string &file, const tiny3d::Image &img); 65 | 66 | struct WAV_Header 67 | { 68 | struct Descriptor 69 | { 70 | char chunk_id[4]; // "RIFF" 71 | uint32_t chunk_size; // 36 + sub_chunk_1_size, i.e. 4 + (8 + sub_chunk_1_size) + (8 + sub_chunk_2_size) 72 | char format[4]; // "WAVE" 73 | }; 74 | 75 | struct Format 76 | { 77 | char sub_chunk_1_id[4]; // "fmt " 78 | uint32_t sub_chunk_1_size; // 16 = PCM 79 | uint16_t audio_format; // 1 = PCM, other values = some form of compression 80 | uint16_t num_channels; // 1 = mono, 2 = stereo, etc. 81 | uint32_t sample_rate; // 8000, 22050, 44100, etc. 82 | uint32_t byte_rate; // sample_rate * num_channels * bits_per_sample / 8 83 | uint16_t block_align; // num_channels * bits_per_sample / 8 84 | uint16_t bits_per_sample; // 8 = uint8_t, 16 = int16_t 85 | // NOTE: if 'audio_format' is other than 1, then more data follows here (we only support audio_format=1 though) 86 | }; 87 | 88 | struct Data 89 | { 90 | char sub_chunk_2_id[4]; // "data" 91 | uint32_t sub_chunk_2_size; // num_samples * num_channels * bits_per_sample / 8 92 | }; 93 | 94 | Descriptor descriptor; 95 | Format format; 96 | Data data; 97 | }; 98 | 99 | bool LoadWAVHeader(retro3d::Reader &reader, retro3d::WAV_Header &header); 100 | int32_t VerifyWAVHeader(const retro3d::WAV_Header &header); 101 | bool LoadWAVBuffer(retro3d::Reader &reader, retro3d::Sound &sfx_buffer); 102 | bool LoadWAV(retro3d::Reader &reader, retro3d::Sound &sfx); 103 | bool LoadWAV(const std::string &file, retro3d::Sound &sfx); 104 | 105 | } 106 | 107 | #endif // RETRO_LOADERS_H 108 | -------------------------------------------------------------------------------- /graphics/retro_camera.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_camera.h" 2 | #include "../common/retro_transform.h" 3 | 4 | mmlVector<3> retro3d::Camera::GlobalUp( void ) 5 | { 6 | return retro3d::Transform::GetWorldUp(); 7 | } 8 | 9 | mmlVector<3> retro3d::Camera::GlobalRight( void ) 10 | { 11 | return retro3d::Transform::GetWorldRight(); 12 | } 13 | 14 | mmlVector<3> retro3d::Camera::GlobalForward( void ) 15 | { 16 | return retro3d::Transform::GetWorldForward(); 17 | } 18 | 19 | retro3d::Camera::Camera( void ) : m_head(0.0f), m_pitch(0.0f), m_roll(0.0f), m_rx(mmlMatrix<3,3>::Identity()), m_ry(mmlMatrix<3,3>::Identity()), m_rz(mmlMatrix<3,3>::Identity()), m_pos(mmlVector<3>::Fill(0.0f)), m_view_to_world() 20 | { 21 | m_view_to_world.New(); 22 | } 23 | 24 | retro3d::Camera::Camera(const retro3d::Camera &c) : m_head(c.m_head), m_pitch(c.m_pitch), m_roll(c.m_roll), m_rx(c.m_rx), m_ry(c.m_ry), m_rz(c.m_rz), m_pos(c.m_pos) 25 | { 26 | m_view_to_world.New(); 27 | // there is no need to copy m_view_to_world since it depends on other values anyway 28 | } 29 | 30 | retro3d::Camera &retro3d::Camera::operator=(const retro3d::Camera &c) 31 | { 32 | if (&c != this) { 33 | m_head = c.m_head; 34 | m_pitch = c.m_pitch; 35 | m_roll = c.m_roll; 36 | m_rx = c.m_rx; 37 | m_ry = c.m_ry; 38 | m_rz = c.m_rz; 39 | m_pos = c.m_pos; 40 | 41 | // don't need to do anything with m_view_to_world 42 | } 43 | return *this; 44 | } 45 | 46 | mmlVector<3> retro3d::Camera::GroundedForward( void ) const 47 | { 48 | return GlobalForward() * m_ry; 49 | } 50 | 51 | mmlVector<3> retro3d::Camera::GroundedUp( void ) const 52 | { 53 | return GlobalUp() * m_ry; 54 | } 55 | 56 | mmlVector<3> retro3d::Camera::GroundedRight( void ) const 57 | { 58 | return GlobalRight() * m_ry; 59 | } 60 | 61 | mmlVector<3> retro3d::Camera::Forward( void ) const 62 | { 63 | return GlobalForward() * (m_ry * m_rx); 64 | } 65 | 66 | mmlVector<3> retro3d::Camera::Up( void ) const 67 | { 68 | return GlobalUp() * (m_ry * m_rx); 69 | } 70 | 71 | mmlVector<3> retro3d::Camera::Right( void ) const 72 | { 73 | return GlobalRight() * (m_ry * m_rx); 74 | } 75 | 76 | const mmlVector<3> &retro3d::Camera::GetPosition( void ) const 77 | { 78 | return m_pos; 79 | } 80 | 81 | void retro3d::Camera::SetPosition(const mmlVector<3> &pos) 82 | { 83 | m_pos = pos; 84 | m_view_to_world->SetPosition(m_pos); 85 | } 86 | 87 | void retro3d::Camera::Move(const mmlVector<3> &move) 88 | { 89 | SetPosition(m_pos + move); 90 | } 91 | 92 | void retro3d::Camera::LocalMove(const mmlVector<3> &move) 93 | { 94 | Move(move[0] * GroundedRight() + move[1] * GroundedUp() + move[2] * GroundedForward()); 95 | } 96 | 97 | void retro3d::Camera::LocalFly(const mmlVector<3> &move) 98 | { 99 | Move(move[0] * GroundedRight() + move[1] * GroundedUp() + move[2] * Forward()); 100 | } 101 | 102 | const retro3d::SharedTransform retro3d::Camera::GetTransform( void ) const 103 | { 104 | return m_view_to_world; 105 | } 106 | 107 | retro3d::Transform retro3d::Camera::GetViewTransform( void ) const 108 | { 109 | retro3d::Transform inv_view = m_view_to_world->GetInvTransform(); 110 | return inv_view; 111 | } 112 | 113 | float retro3d::Camera::GetHeadAngle( void ) const 114 | { 115 | return m_head; 116 | } 117 | 118 | float retro3d::Camera::GetPitchAngle( void ) const 119 | { 120 | return m_pitch; 121 | } 122 | 123 | float retro3d::Camera::GetRollAngle( void ) const 124 | { 125 | return m_roll; 126 | } 127 | 128 | void retro3d::Camera::SetRotation(float x_head, float y_pitch, float z_roll) 129 | { 130 | constexpr float TAU = mmlPI*2.0f; 131 | constexpr float HPI = (mmlPI / 2) - 0.01f; // subtract a small amount 132 | constexpr float NHPI = -HPI; 133 | 134 | m_head = mmlWrap(0.0f, x_head, TAU); 135 | m_pitch = mmlClamp(NHPI, y_pitch, HPI); 136 | m_roll = mmlWrap(0.0f, z_roll, TAU); 137 | 138 | m_ry = mmlRotateY(m_head); 139 | m_rx = mmlRotateX(m_pitch); 140 | m_rz = mmlRotateZ(m_roll); 141 | 142 | *m_view_to_world.GetShared() = mmlTransform(m_ry * m_rx * m_rz, m_pos); 143 | } 144 | 145 | void retro3d::Camera::Rotate(float x_head, float y_pitch, float z_roll) 146 | { 147 | SetRotation(m_head + x_head, m_pitch + y_pitch, m_roll + z_roll); 148 | } 149 | 150 | mmlMatrix<3,3> retro3d::Camera::GetRX( void ) const 151 | { 152 | return m_rx; 153 | } 154 | 155 | mmlMatrix<3,3> retro3d::Camera::GetRY( void ) const 156 | { 157 | return m_ry; 158 | } 159 | 160 | mmlMatrix<3,3> retro3d::Camera::GetRZ( void ) const 161 | { 162 | return m_rz; 163 | } 164 | -------------------------------------------------------------------------------- /ecs/entities/retro_tween.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_TWEEN_H 2 | #define RETRO_TWEEN_H 3 | 4 | #include "../retro_entity.h" 5 | #include "../../common/retro_defs.h" 6 | 7 | namespace retro3d 8 | { 9 | 10 | // A generic interface for an interpolation process (tween). 11 | class ITween : public mtlInherit< retro3d::Entity, ITween > 12 | { 13 | public: 14 | // The mode in which to tween the object. 15 | enum Mode 16 | { 17 | MODE_REL_LERP, // Relative linear interpolation. Relative does not lock target into place if other processes are manipulating the object, but may miss the destination. 18 | MODE_REL_SLERP, // Relative spherical interpolation. Relative does not lock target into place if other processes are manipulating the object, but may miss the destination. 19 | MODE_REL_QLERP, // Relative quaternion interpolation. Relative does not lock target into place if other processes are manipulating the object, but may miss the destination. 20 | MODE_ABS_LERP, // Absolute linear interpolation. Absolute locks target into place regardless if other processes are manipulating the object, but will hit destination. 21 | MODE_ABS_SLERP, // Absolute spherical interpolation. Absolute locks target into place regardless if other processes are manipulating the object, but will hit destination. 22 | MODE_ABS_QLERP // Absolute quaternion interpolation. Absolute locks target into place regardless if other processes are manipulating the object, but will hit destination. 23 | }; 24 | 25 | protected: 26 | Mode m_mode; 27 | retro3d::Time m_duration; 28 | retro3d::TimerType m_timer_type; 29 | 30 | public: 31 | // Construction 32 | ITween( void ); 33 | 34 | // Sets the mode in which to tween. 35 | void SetProperties(Mode mode, retro3d::Time duration, retro3d::TimerType timer_type = retro3d::TIMER_GAME); 36 | 37 | // Forces the tween to finish 38 | virtual void Finish( void ) = 0; 39 | 40 | // Stops the tweening process cold. 41 | void Cancel( void ); 42 | }; 43 | 44 | template < typename type_t > 45 | class Tween : public mtlInherit< ITween, Tween > 46 | { 47 | private: 48 | type_t *x; 49 | type_t x0; 50 | type_t a; 51 | type_t b; 52 | 53 | protected: 54 | // Tweens the target and calls user-defined OnUpdate. 55 | void OnUpdate( void ) override; 56 | 57 | public: 58 | // Construction. 59 | Tween( void ) = delete; 60 | Tween(type_t &from, const type_t &to, ITween::Mode mode, retro3d::Time duration, retro3d::TimerType timer_type = retro3d::TIMER_GAME); 61 | 62 | // Forces the tween to finish. 63 | void Finish( void ) override; 64 | }; 65 | 66 | } 67 | 68 | template < typename type_t > 69 | void retro3d::Tween::OnUpdate( void ) 70 | { 71 | const float d = mmlClamp(0.0f, float((Entity::LifeTime(ITween::m_timer_type) / ITween::m_duration).GetFloatSeconds()), 1.0f); 72 | const type_t y = x0; 73 | 74 | if (x != nullptr) { 75 | switch (ITween::m_mode) { 76 | case ITween::MODE_REL_LERP: 77 | x0 = mmlLerp(a, b, d); 78 | *x += (x0 - y); 79 | break; 80 | case ITween::MODE_REL_SLERP: 81 | x0 = mmlSlerp(a, b, d); 82 | *x += (x0 - y); 83 | break; 84 | case ITween::MODE_REL_QLERP: 85 | x0 = mmlQlerp(a, b, d); 86 | *x += (x0 - y); 87 | break; 88 | case ITween::MODE_ABS_LERP: 89 | *x = mmlLerp(a, b, d); 90 | x0 = x; 91 | break; 92 | case ITween::MODE_ABS_SLERP: 93 | *x = mmlSlerp(a, b, d); 94 | x0 = x; 95 | break; 96 | case ITween::MODE_ABS_QLERP: 97 | *x = mmlQlerp(a, b, d); 98 | x0 = x; 99 | break; 100 | } 101 | } 102 | 103 | if (d >= 1.0f) { 104 | Entity::Destroy(); 105 | } 106 | } 107 | 108 | template < typename type_t > 109 | retro3d::Tween::Tween(type_t &from, const type_t &to, retro3d::ITween::Mode mode, retro3d::Time duration, retro3d::TimerType timer_type) : mtlInherit< ITween,Tween >(this), x(&from), x0(from), a(from), b(to) 110 | { 111 | ITween::SetProperties(mode, duration, timer_type); 112 | } 113 | 114 | template < typename type_t > 115 | void retro3d::Tween::Finish( void ) 116 | { 117 | if (x != nullptr) { 118 | const type_t y = x0; 119 | 120 | switch (ITween::m_mode) { 121 | case ITween::MODE_REL_LERP: 122 | case ITween::MODE_REL_SLERP: 123 | case ITween::MODE_REL_QLERP: 124 | x0 = b; 125 | *x += (x0 - y); 126 | break; 127 | case ITween::MODE_ABS_LERP: 128 | case ITween::MODE_ABS_SLERP: 129 | case ITween::MODE_ABS_QLERP: 130 | *x = b; 131 | x0 = b; 132 | break; 133 | } 134 | } 135 | Entity::Destroy(); 136 | } 137 | 138 | #endif // RETRO_TWEEN_H 139 | -------------------------------------------------------------------------------- /physics/retro_physics.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_PHYSICS_H 2 | #define RETRO_PHYSICS_H 3 | 4 | #include "../common/MiniLib/MML/mmlMatrix.h" 5 | #include "../common/MiniLib/MML/mmlVector.h" 6 | #include "../common/MiniLib/MTL/mtlPointer.h" 7 | #include "../common/MiniLib/MML/mmlQuaternion.h" 8 | #include "../common/retro_transform.h" 9 | #include "retro_collider.h" 10 | 11 | // https://www.gamasutra.com/view/feature/131761/c_data_structures_for_rigidbody_.php?page=5 12 | 13 | namespace retro3d 14 | { 15 | 16 | class PhysicsProperties 17 | { 18 | private: 19 | retro3d::SharedTransform m_transform; 20 | mmlVector<3> m_center_of_mass_offset; 21 | mmlVector<3> m_linear_velocity; 22 | mmlVector<3> m_angular_velocity; // unit is axis, length is speed 23 | mmlMatrix<3,3> m_inv_inertia_tensor; 24 | float m_mass; 25 | float m_inv_mass; 26 | float m_friction_static; 27 | float m_friction_kinetic; 28 | float m_restitution; 29 | 30 | public: 31 | PhysicsProperties( void ); 32 | 33 | void UpdateInertiaTensor(const mmlVector<3> &rigidbody_halfextents); 34 | 35 | void AttachTransform(retro3d::SharedTransform t); 36 | void SetTransform(const retro3d::Transform &transform); 37 | const retro3d::Transform &GetTransform( void ) const; 38 | retro3d::Transform &GetTransform( void ); 39 | retro3d::SharedTransform GetSharedTransform( void ) const; 40 | 41 | void ApplyLinearImpulse(const mmlVector<3> &impulse); 42 | void ApplyForce(const mmlVector<3> &world_impact_point, mmlVector<3> world_force_direction, float force_magnitude); 43 | 44 | void NullifyVelocity( void ); 45 | void NullifyLinearVelocity( void ); 46 | void NullifyAngularVelocity( void ); 47 | 48 | mmlVector<3> GetVelocity(const mmlVector<3> &world_point) const; 49 | mmlVector<3> GetLinearVelocity( void ) const; 50 | mmlVector<3> GetAngularVelocity( void ) const; 51 | 52 | mmlVector<3> GetMomentum(const mmlVector<3> &world_point) const; 53 | mmlVector<3> GetLinearMomentum( void ) const; 54 | mmlVector<3> GetAngularMomentum( void ) const; 55 | 56 | void SetMass(float mass); 57 | float GetMass( void ) const; 58 | float GetInverseMass( void ) const; 59 | 60 | mmlVector<3> GetCenterOfMass( void ) const; 61 | 62 | void StepSimulation(float time_delta); 63 | }; 64 | 65 | struct RigidBody 66 | { 67 | float mass = 1.0f; 68 | float inv_mass = 1.0f; 69 | mmlMatrix<3,3> inv_body_inertia_tensor = mmlMatrix<3,3>::Identity(); // prevents bodies with irregular shape to rotate freely. must be calculated based on shape. 70 | float restitution_coef = 1.0f; 71 | 72 | uint32_t number_of_bounding_vertices; 73 | enum { MaxNumberOfBoundingVertices = 20 }; 74 | mmlVector<3> body_bounding_verts[MaxNumberOfBoundingVertices]; 75 | 76 | enum { NumberOfConfigurations = 2 }; 77 | 78 | struct Configuration 79 | { 80 | mmlVector<3> cm_position = mmlVector<3>::Fill(0.0f); 81 | mmlMatrix<3,3> orientation = mmlMatrix<3,3>::Identity(); 82 | 83 | mmlVector<3> cm_velocity = mmlVector<3>::Fill(0.0f); 84 | mmlVector<3> angular_momentum = mmlVector<3>::Fill(0.0f); 85 | 86 | mmlVector<3> cm_force = mmlVector<3>::Fill(0.0f); 87 | mmlVector<3> torque = mmlVector<3>::Fill(0.0f); 88 | 89 | mmlMatrix<3,3> inv_world_inertia_tensor = mmlMatrix<3,3>::Identity(); 90 | mmlVector<3> angular_velocity = mmlVector<3>::Fill(0.0f); 91 | 92 | mmlVector<3> bounding_verts[MaxNumberOfBoundingVertices]; 93 | 94 | // don't need bounding vertices... 95 | } configs[NumberOfConfigurations]; 96 | 97 | // TODO: something to calculate inertia tensor 98 | }; 99 | 100 | class PhysicsIntegrator 101 | { 102 | private: 103 | enum CollisionState 104 | { 105 | Penetrating, 106 | Colliding, 107 | Clear 108 | } collision_state; 109 | 110 | mmlVector<3> collision_normal; 111 | int32_t colliding_body_index; 112 | int32_t colliding_corner_index; 113 | int32_t source_config_index; 114 | int32_t target_config_index; 115 | 116 | enum { NumberOfWalls = 6 }; 117 | struct Wall 118 | { 119 | mmlVector<3> normal; 120 | float d; 121 | }; 122 | Wall walls[NumberOfWalls]; 123 | 124 | enum { NumberOfBodies = 6 }; 125 | retro3d::RigidBody bodies[NumberOfBodies]; 126 | 127 | void Initialize( void ); 128 | void ComputeForces(int32_t config_index); 129 | void Integrate(float delta_time); 130 | CollisionState CheckForCollisions(int32_t config_index); 131 | void ResolveCollisions(int32_t config_index); 132 | void CalculateVertices(int32_t config_index); 133 | 134 | public: 135 | PhysicsIntegrator(float world_x, float world_y, float world_z); 136 | 137 | void Simulate(float delta_time); 138 | }; 139 | 140 | } 141 | 142 | #endif // RETRO_PHYSICS_H 143 | -------------------------------------------------------------------------------- /graphics/retro_texture.cpp: -------------------------------------------------------------------------------- 1 | #include "../common/MiniLib/MML/mmlMath.h" 2 | #include "../common/MiniLib/MML/mmlVector.h" 3 | #include "retro_texture.h" 4 | #include "../serial/retro_import.h" 5 | 6 | void retro3d::Texture::CreateErrorTexture( void ) 7 | { 8 | tiny3d::Image i; 9 | retro3d::CreateDefaultImage(i); 10 | FromImage(i); 11 | } 12 | 13 | void retro3d::Texture::BuildRefs( void ) 14 | { 15 | tiny3d::Texture *t = &m_mip_data[0]; 16 | for (tiny3d::UInt i = 0; i < RETRO3D_MIP_COUNT; ++i) { 17 | m_mip_refs[i] = t; 18 | if (i < RETRO3D_MIP_COUNT - 1 && t[1].GetWidth() > 0) { 19 | ++t; 20 | } 21 | } 22 | } 23 | 24 | retro3d::Texture::Texture( void ) 25 | { 26 | for (tiny3d::UInt i = 0; i < RETRO3D_MIP_COUNT; ++i) { 27 | m_mip_refs[i] = nullptr; 28 | } 29 | } 30 | 31 | retro3d::Texture::Texture(const retro3d::Texture &mips) : Texture() 32 | { 33 | Copy(mips); 34 | } 35 | 36 | retro3d::Texture::Texture(const tiny3d::Image &img) : Texture() 37 | { 38 | FromImage(img); 39 | } 40 | 41 | bool retro3d::Texture::FromImage(const tiny3d::Image &img) 42 | { 43 | Destroy(); 44 | 45 | tiny3d::Image a_img = img; 46 | tiny3d::Image b_img; 47 | tiny3d::Image *a = &a_img; 48 | tiny3d::Image *b = &b_img; 49 | 50 | for (tiny3d::UInt i = 0; i < RETRO3D_MIP_COUNT; ++i) { 51 | 52 | if (!m_mip_data[i].FromImage(*a)) { 53 | CreateErrorTexture(); 54 | return false; 55 | } 56 | 57 | if (i < RETRO3D_MIP_COUNT - 1) { 58 | tiny3d::UInt w = a->GetWidth() >> 1; 59 | tiny3d::UInt h = a->GetHeight() >> 1; 60 | if (w < tiny3d::Texture::MinDimension() || h < tiny3d::Texture::MinDimension()) { 61 | break; 62 | } 63 | if (b->Create(w, h) == true) { 64 | for (tiny3d::UInt y = 0; y < h; ++y) { 65 | for (tiny3d::UInt x = 0; x < w; ++x) { 66 | tiny3d::Color c00 = a->GetColor({ x*2, y*2 }); 67 | tiny3d::Color c10 = a->GetColor({ x*2 + 1, y*2 }); 68 | tiny3d::Color c01 = a->GetColor({ x*2, y*2 + 1 }); 69 | tiny3d::Color c11 = a->GetColor({ x*2 + 1, y*2 + 1 }); 70 | mmlVector<4> v00 = mmlVector<4>( double(c00.r), double(c00.g), double(c00.b), double(c00.blend) ); 71 | mmlVector<4> v10 = mmlVector<4>( double(c10.r), double(c10.g), double(c10.b), double(c10.blend) ); 72 | mmlVector<4> v01 = mmlVector<4>( double(c01.r), double(c01.g), double(c01.b), double(c01.blend) ); 73 | mmlVector<4> v11 = mmlVector<4>( double(c11.r), double(c11.g), double(c11.b), double(c11.blend) ); 74 | mmlVector<4> vx = (v00 + v10 + v01 + v11) / 4.0f; 75 | b->SetColor({ x, y }, tiny3d::Color{ tiny3d::Byte(vx[0]), tiny3d::Byte(vx[1]), tiny3d::Byte(vx[2]), tiny3d::Byte(vx[3] >= 2.0f ? tiny3d::Color::Solid : tiny3d::Color::Transparent) }); 76 | } 77 | } 78 | } else { 79 | CreateErrorTexture(); 80 | return false; 81 | } 82 | 83 | mmlSwap(a, b); 84 | } 85 | } 86 | BuildRefs(); 87 | return true; 88 | } 89 | 90 | void retro3d::Texture::Copy(const retro3d::Texture &mips) 91 | { 92 | if (this == &mips) { return; } 93 | for (tiny3d::UInt i = 0; i < RETRO3D_MIP_COUNT; ++i) { 94 | m_mip_data[i].Copy(mips.m_mip_data[i]); 95 | } 96 | BuildRefs(); 97 | } 98 | 99 | void retro3d::Texture::Destroy( void ) 100 | { 101 | for (tiny3d::UInt i = 0; i < RETRO3D_MIP_COUNT; ++i) { 102 | m_mip_data[i].Destroy(); 103 | m_mip_refs[i] = nullptr; 104 | } 105 | } 106 | 107 | void retro3d::Texture::SetBlendMode1(tiny3d::Color::BlendMode blend_mode) 108 | { 109 | for (tiny3d::UInt i = 0; i < RETRO3D_MIP_COUNT; ++i) { 110 | m_mip_data[i].SetBlendMode1(blend_mode); 111 | } 112 | } 113 | 114 | void retro3d::Texture::SetBlendMode2(tiny3d::Color::BlendMode blend_mode) 115 | { 116 | for (tiny3d::UInt i = 0; i < RETRO3D_MIP_COUNT; ++i) { 117 | m_mip_data[i].SetBlendMode2(blend_mode); 118 | } 119 | } 120 | 121 | void retro3d::Texture::SetBlendModes(tiny3d::Color::BlendMode mode_1, tiny3d::Color::BlendMode mode_2) 122 | { 123 | SetBlendMode1(mode_1); 124 | SetBlendMode2(mode_2); 125 | } 126 | 127 | void retro3d::Texture::ResetBlendMode1( void ) 128 | { 129 | SetBlendMode1(tiny3d::Color::Transparent); 130 | } 131 | 132 | void retro3d::Texture::ResetBlendMode2( void ) 133 | { 134 | SetBlendMode2(tiny3d::Color::Solid); 135 | } 136 | 137 | void retro3d::Texture::ResetBlendModes( void ) 138 | { 139 | ResetBlendMode1(); 140 | ResetBlendMode2(); 141 | } 142 | 143 | const tiny3d::Texture *retro3d::Texture::operator[](tiny3d::UInt level) const 144 | { 145 | return m_mip_refs[mmlMin(level, tiny3d::UInt(RETRO3D_MIP_COUNT - 1))]; 146 | } 147 | 148 | retro3d::Texture &retro3d::Texture::operator=(const retro3d::Texture &mips) 149 | { 150 | Copy(mips); 151 | return *this; 152 | } 153 | 154 | const tiny3d::Texture *retro3d::Texture::GetHighestQuality( void ) const 155 | { 156 | return m_mip_refs[0]; 157 | } 158 | 159 | const tiny3d::Texture *retro3d::Texture::GetLowestQuality( void ) const 160 | { 161 | return m_mip_refs[RETRO3D_MIP_COUNT - 1]; 162 | } 163 | -------------------------------------------------------------------------------- /ecs/retro_entity.cpp: -------------------------------------------------------------------------------- 1 | #include "../common/MiniLib/MML/mmlMath.h" 2 | #include "retro_entity.h" 3 | 4 | void retro3d::Entity::OnSpawn( void ) 5 | {} 6 | 7 | void retro3d::Entity::OnUpdate( void ) 8 | {} 9 | 10 | void retro3d::Entity::OnCollision(retro3d::Entity&) 11 | {} 12 | 13 | void retro3d::Entity::OnDestroy( void ) 14 | {} 15 | 16 | retro3d::Entity::Entity( void ) : 17 | mtlInherit(this), 18 | m_tag("entity"), m_filter_flags(1), m_uuid(reinterpret_cast(this)), 19 | m_engine(nullptr), 20 | m_game_timer(1, 1_s), 21 | m_delta_time(0.0), 22 | m_is_active(1), m_should_destroy(false) 23 | { 24 | m_game_timer.Start(); 25 | } 26 | 27 | void retro3d::Entity::Destroy( void ) 28 | { 29 | m_should_destroy = true; 30 | } 31 | 32 | bool retro3d::Entity::IsDestroyed( void ) const 33 | { 34 | return m_should_destroy; 35 | } 36 | 37 | bool retro3d::Entity::IsActive( void ) const 38 | { 39 | return !IsDestroyed() && m_is_active > 0; 40 | } 41 | 42 | void retro3d::Entity::Deactivate( void ) 43 | { 44 | --m_is_active; 45 | m_game_timer.Pause(); 46 | } 47 | 48 | void retro3d::Entity::Activate( void ) 49 | { 50 | m_is_active = mmlMin(1, m_is_active + 1); 51 | if (m_is_active > 0) { 52 | m_game_timer.Start(); 53 | } 54 | } 55 | 56 | uint64_t retro3d::Entity::GetUUID( void ) const 57 | { 58 | return m_uuid; 59 | } 60 | 61 | const retro3d::Engine *retro3d::Entity::GetEngine( void ) const 62 | { 63 | return m_engine; 64 | } 65 | 66 | retro3d::Engine *retro3d::Entity::GetEngine( void ) 67 | { 68 | return m_engine; 69 | } 70 | 71 | retro3d::RenderDevice *retro3d::Entity::GetRenderer( void ) 72 | { 73 | return m_engine->GetRenderer(); 74 | } 75 | 76 | const retro3d::RenderDevice *retro3d::Entity::GetRenderer( void ) const 77 | { 78 | return m_engine->GetRenderer(); 79 | } 80 | 81 | retro3d::SoundDevice *retro3d::Entity::GetSoundDevice( void ) 82 | { 83 | return m_engine->GetSoundDevice(); 84 | } 85 | 86 | const retro3d::SoundDevice *retro3d::Entity::GetSoundDevice( void ) const 87 | { 88 | return m_engine->GetSoundDevice(); 89 | } 90 | 91 | retro3d::InputDevice *retro3d::Entity::GetInput( void ) 92 | { 93 | return m_engine->GetInput(); 94 | } 95 | 96 | const retro3d::InputDevice *retro3d::Entity::GetInput( void ) const 97 | { 98 | return m_engine->GetInput(); 99 | } 100 | 101 | const std::string &retro3d::Entity::GetTag( void ) const 102 | { 103 | return m_tag; 104 | } 105 | 106 | void retro3d::Entity::SetTag(const std::string &tag) 107 | { 108 | m_tag = tag; 109 | } 110 | 111 | retro3d::Time retro3d::Entity::RealLifeTime( void ) const 112 | { 113 | return GetEngine()->RealTime() - m_real_time_spawn; 114 | } 115 | 116 | retro3d::Time retro3d::Entity::SimulationLifeTime( void ) const 117 | { 118 | return GetEngine()->SimulationTime() - m_sim_time_spawn; 119 | } 120 | 121 | retro3d::Time retro3d::Entity::GameLifeTime( void ) const 122 | { 123 | return m_game_time; 124 | } 125 | 126 | retro3d::Time retro3d::Entity::LifeTime(retro3d::TimerType type) const 127 | { 128 | switch (type) { 129 | case TIMER_REAL: return RealLifeTime(); 130 | case TIMER_SIM: return SimulationLifeTime(); 131 | case TIMER_GAME: return GameLifeTime(); 132 | } 133 | return retro3d::Time(); 134 | } 135 | 136 | double retro3d::Entity::DeltaTime( void ) const 137 | { 138 | return m_delta_time; 139 | } 140 | 141 | void retro3d::Entity::SetTimeScale(double time_scale) 142 | { 143 | m_game_timer.SetTickRate(1, retro3d::Time::FloatSeconds(1.0 / time_scale), false); 144 | } 145 | 146 | double retro3d::Entity::GetTimeScale( void ) const 147 | { 148 | return 1.0 / m_game_timer.GetTimePerTick().GetFloatSeconds(); 149 | } 150 | 151 | retro3d::RealTimeTimer retro3d::Entity::CreateGameTimer(uint32_t num_ticks, retro3d::Time over_time) const 152 | { 153 | return m_game_timer.SpawnChild(num_ticks, over_time); 154 | } 155 | 156 | retro3d::RealTimeTimer retro3d::Entity::CreateTimer(retro3d::TimerType type, uint32_t num_ticks, retro3d::Time over_time) const 157 | { 158 | switch (type) { 159 | case TIMER_REAL: return retro3d::RealTimeTimer(num_ticks, over_time); 160 | case TIMER_SIM: return GetEngine()->CreateSimulationTimer(num_ticks, over_time); 161 | case TIMER_GAME: return CreateGameTimer(num_ticks, over_time); 162 | } 163 | return retro3d::RealTimeTimer(num_ticks, over_time); 164 | } 165 | 166 | uint64_t retro3d::Entity::GetFilterFlags( void ) const 167 | { 168 | return m_filter_flags; 169 | } 170 | 171 | bool retro3d::Entity::GetFilterFlag(uint32_t flag_index) const 172 | { 173 | return (m_filter_flags & (uint64_t(1) << flag_index)) != 0; 174 | } 175 | 176 | void retro3d::Entity::SetFilterFlags(uint64_t filter_flags) 177 | { 178 | m_filter_flags = filter_flags; 179 | } 180 | 181 | void retro3d::Entity::SetFilterFlag(uint32_t flag_index, bool state) 182 | { 183 | if (state == true) { 184 | m_filter_flags |= (uint64_t(1) << flag_index); 185 | } else { 186 | m_filter_flags &= ~(uint64_t(1) << flag_index); 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /ecs/systems/retro_collision_system.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_collision_system.h" 2 | #include "../../ecs/components/retro_physics_component.h" 3 | #include "../../retro3d.h" 4 | 5 | void retro3d::CollisionSystem::OnSpawn(retro3d::ColliderComponent &c) 6 | { 7 | // Add component to collider tree 8 | m_collider_tree.Insert(c.GetObject(), &c.GetCollider(), c.IsStatic(), c.GetFilterFlags()); 9 | if (c.ShouldReinsert() == true) { 10 | c.ToggleReinsert(); 11 | } 12 | } 13 | 14 | void retro3d::CollisionSystem::OnUpdate(retro3d::ColliderComponent &c) 15 | { 16 | // Check if the collider needs to update its representation inside the tree 17 | if (c.ShouldReinsert() == true) { 18 | m_collider_tree.Remove(c.GetObject()); 19 | m_collider_tree.Insert(c.GetObject(), &c.GetCollider(), c.IsStatic(), c.GetFilterFlags()); 20 | c.ToggleReinsert(); 21 | } 22 | } 23 | 24 | void retro3d::CollisionSystem::OnDestroy(retro3d::ColliderComponent &c) 25 | { 26 | // Remove component from collider tree 27 | m_collider_tree.Remove(c.GetObject()); 28 | } 29 | 30 | void SwapCollisionInfo(retro3d::ColliderTree::Contact &c, retro3d::Collider::Contact &c_info) 31 | { 32 | mmlSwap(c.a, c.b); 33 | mmlSwap(c.a_is_static, c.b_is_static); 34 | mmlSwap(c.a_filter_flags, c.b_filter_flags); 35 | c_info.normal = -c_info.normal; 36 | } 37 | 38 | void retro3d::CollisionSystem::OnUpdate( void ) 39 | { 40 | // Detect actual collisions from a list of potential collisions and resolve 41 | auto *c_iter = m_collider_tree.GetPotentialContacts().GetFirst(); 42 | while (c_iter != nullptr) { 43 | auto c = c_iter->GetItem(); 44 | retro3d::Collider::Contact c_info; 45 | if (c.a.collider->IsColliding(*c.b.collider, &c_info) == true) { 46 | ResolveContactA(c, c_info); 47 | SwapCollisionInfo(c, c_info); // Collider A and B have switched place, and collsion normal is flipped. 48 | ResolveContactA(c, c_info); 49 | } 50 | c_iter = c_iter->GetNext(); 51 | } 52 | 53 | // Update tree 54 | m_collider_tree.Update(); 55 | } 56 | 57 | void retro3d::CollisionSystem::ResolveContactA(const retro3d::ColliderTree::Contact &contact_pair, const retro3d::Collider::Contact &contact_info) const 58 | { 59 | if (contact_pair.a_is_static == false) { 60 | // ONLY resolve and apply forces to A. 61 | // B is read-only. 62 | 63 | retro3d::PhysicsComponent *ap = contact_pair.a.user_data->GetComponent(); 64 | const retro3d::PhysicsComponent *bp = contact_pair.b.user_data->GetComponent(); 65 | 66 | float resolve_ratio = 1.0f; 67 | if (ap != nullptr) { 68 | mmlVector<3> mov = ap->GetMomentum(contact_info.point); 69 | if (contact_pair.b_is_static == false && bp != nullptr) { 70 | resolve_ratio = ap->GetMass() / (ap->GetMass() + bp->GetMass()); 71 | mov -= bp->GetMomentum(contact_info.point); 72 | } 73 | ap->ApplyForce(contact_info.point, contact_info.normal, mov.Len()); 74 | } 75 | 76 | contact_pair.a.collider->GetTransform().SetPosition(contact_pair.a.collider->GetTransform().GetPosition() + contact_info.normal * contact_info.depth * resolve_ratio); 77 | } 78 | } 79 | 80 | retro3d::CollisionSystem::CollisionSystem( void ) : mtlInherit(this) 81 | {} 82 | 83 | retro3d::Entity *retro3d::CollisionSystem::CastRay(const retro3d::Ray &world_ray, uint64_t filter_flags, retro3d::Ray::Contact *contact_info) const 84 | { 85 | return m_collider_tree.CastRay(world_ray, filter_flags, contact_info); 86 | } 87 | 88 | bool retro3d::CollisionSystem::Contains(const mmlVector<3> &world_point, uint64_t filter_flags, mtlList *colliders) 89 | { 90 | return m_collider_tree.Contains(world_point, filter_flags, colliders); 91 | } 92 | 93 | retro3d::Entity *retro3d::CollisionSystem::ApplyForce(const retro3d::Ray &world_force, float force_magnitude, uint64_t filter_flags, retro3d::Ray::Contact *contact_info) 94 | { 95 | retro3d::Ray::Contact temp; 96 | retro3d::Ray::Contact *ct = contact_info != nullptr ? contact_info : &temp; 97 | retro3d::Entity *e = CastRay(world_force, filter_flags, ct); 98 | if (e != nullptr && e->GetComponent()->IsStatic() == false) { 99 | retro3d::PhysicsComponent *pc = e->GetComponent(); 100 | if (pc != nullptr) { 101 | pc->ApplyForce(world_force.origin, world_force.direction, force_magnitude); 102 | } 103 | } 104 | return e; 105 | } 106 | 107 | void retro3d::CollisionSystem::Debug_PrintTree( void ) const 108 | { 109 | m_collider_tree.Debug_PrintTree(); 110 | } 111 | 112 | void retro3d::CollisionSystem::Debug_RenderTree( void ) 113 | { 114 | std::queue::Debug_AABB> q = m_collider_tree.Debug_GetTree(); 115 | while (q.empty() == false) { 116 | mmlVector<3> c = mmlVector<3>::Fill(0.0f); 117 | switch (q.front().type) { 118 | case retro3d::ColliderTree::Debug_AABB::Node_Dynamic: 119 | c[2] = 1.0f; 120 | break; 121 | case retro3d::ColliderTree::Debug_AABB::Node_Static: 122 | c[0] = 1.0f; 123 | c[1] = 1.0f; 124 | break; 125 | case retro3d::ColliderTree::Debug_AABB::Leaf_Dynamic: 126 | c[1] = 1.0f; 127 | break; 128 | case retro3d::ColliderTree::Debug_AABB::Leaf_Static: 129 | c[0] = 1.0f; 130 | break; 131 | } 132 | GetEngine()->GetRenderer()->RenderAABB(q.front(), mmlMatrix<4,4>::Identity(), c); 133 | q.pop(); 134 | } 135 | } 136 | 137 | const retro3d::ColliderTree::Contacts &retro3d::CollisionSystem::Debug_GetPotentialContacts( void ) const 138 | { 139 | return m_collider_tree.GetPotentialContacts(); 140 | } 141 | -------------------------------------------------------------------------------- /frontend/retro_render_device.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_RENDER_DEVICE_H 2 | #define RETRO_RENDER_DEVICE_H 3 | 4 | #include "../api/tiny3d/tiny3d.h" 5 | 6 | #include "retro_device.h" 7 | #include "../common/MiniLib/MML/mmlVector.h" 8 | #include "../common/MiniLib/MML/mmlMatrix.h" 9 | #include "../graphics/retro_model.h" 10 | #include "../common/retro_geom.h" 11 | #include "../graphics/retro_light.h" 12 | #include "../graphics/retro_camera.h" 13 | 14 | #define retro_text_std(msg) (msg), mmlVector<3>::Fill(1.0f) 15 | #define retro_text_warn(msg) (msg), mmlVector<3>(1.0, 1.0, 0.0) 16 | #define retro_text_val(msg) (msg), mmlVector<3>(0.0, 1.0, 1.0) 17 | #define retro_text_err(msg) (msg), mmlVector<3>(1.0, 0.0, 0.0) 18 | 19 | namespace retro3d 20 | { 21 | 22 | class RenderDevice : public retro3d::Device 23 | { 24 | public: 25 | enum RenderMode 26 | { 27 | RenderMode_Points, 28 | RenderMode_Lines, 29 | RenderMode_Polygons 30 | }; 31 | 32 | enum LightMode 33 | { 34 | LightMode_Fullbright, // All lights = (1,1,1) 35 | LightMode_Dynamic, // All vertices are processed by all intersecting lights 36 | LightMode_NormalsAsColor, // Normal channel is interpreted as color channel 37 | LightMode_Lightmap // Fullbright + lightmap 38 | }; 39 | 40 | public: 41 | virtual ~RenderDevice( void ); 42 | 43 | virtual bool Init( void ) = 0; 44 | 45 | virtual void SetDepthClip(float near_z, float far_z, float hori_fov) = 0; 46 | virtual bool CreateRenderSurface(uint32_t width, uint32_t height) = 0; 47 | virtual void DestroyRenderSurface( void ) = 0; 48 | virtual void SetViewTransform(const mmlMatrix<4,4> &world_to_view) = 0; 49 | virtual void SetViewTransform(const mmlMatrix<4,4> *world_to_view) = 0; 50 | virtual void SetViewTransform(const retro3d::Camera &camera) = 0; 51 | virtual mmlMatrix<4,4> GetViewTransform( void ) const = 0; 52 | virtual mmlMatrix<4,4> GetInverseViewTransform( void ) const = 0; 53 | virtual void RenderModel(const retro3d::Model &model, const mmlMatrix<4,4> &obj_to_world, LightMode light_mode, RenderMode render_mode = RenderMode_Polygons) = 0; 54 | virtual void RenderModel(const retro3d::Model &model, const mmlMatrix<4,4> *obj_to_world, LightMode light_mode, RenderMode render_mode = RenderMode_Polygons) = 0; 55 | virtual void RenderDisplayModel(const retro3d::DisplayModel &model, const mmlMatrix<4,4> &obj_to_world, LightMode light_mode, RenderMode render_mode = RenderMode_Polygons) = 0; 56 | virtual void RenderSpritePlane(const retro3d::Model &sprite_plane, const mmlMatrix<4,4> &obj_to_world, LightMode light_mode, RenderMode render_mode = RenderMode_Polygons) = 0; 57 | virtual void RenderSpritePlane(const retro3d::Model &sprite_plane, const mmlMatrix<4,4> *obj_to_world, LightMode light_mode, RenderMode render_mode = RenderMode_Polygons) = 0; 58 | virtual void RenderLight(const retro3d::Light &light) = 0; 59 | virtual void RenderAABB(const retro3d::AABB &aabb, const mmlMatrix<4,4> &obj_to_world, const mmlVector<3> &color = mmlVector<3>(0.0, 1.0, 0.0), bool world_axis_aligned = true) = 0; 60 | virtual void RenderAABB(const retro3d::AABB &aabb, const mmlMatrix<4,4> *obj_to_world, const mmlVector<3> &color = mmlVector<3>(0.0, 1.0, 0.0), bool world_axis_aligned = true) = 0; 61 | virtual void RenderViewFrustum(const retro3d::Frustum &frustum, const mmlMatrix<4,4> &obj_to_world, const mmlVector<3> &color = mmlVector<3>::Fill(0.5f)) = 0; 62 | virtual void RenderViewFrustum(const retro3d::Frustum &frustum, const mmlMatrix<4,4> *obj_to_world, const mmlVector<3> &color = mmlVector<3>::Fill(0.5f)) = 0; 63 | virtual void RenderOverlay(const tiny3d::Overlay &overlay, const retro3d::Rect &src_region, const retro3d::Rect &dst_region) = 0; 64 | virtual RenderDevice &RenderText(const std::string &str, const mmlVector<3> &color = mmlVector<3>::Fill(1.0f)) = 0; 65 | virtual RenderDevice &RenderText(int64_t n, const mmlVector<3> &color = mmlVector<3>::Fill(1.0f)) = 0; 66 | virtual RenderDevice &RenderText(uint64_t n, const mmlVector<3> &color = mmlVector<3>::Fill(1.0f)) = 0; 67 | virtual RenderDevice &RenderText(double n, const mmlVector<3> &color = mmlVector<3>::Fill(1.0f)) = 0; 68 | virtual RenderDevice &RenderText(const std::string &str, tiny3d::Point xy, uint32_t scale, const mmlVector<3> &color) = 0; 69 | virtual RenderDevice &RenderText(int64_t n, tiny3d::Point xy, uint32_t scale, const mmlVector<3> &color) = 0; 70 | virtual RenderDevice &RenderText(uint64_t n, tiny3d::Point xy, uint32_t scale, const mmlVector<3> &color) = 0; 71 | virtual RenderDevice &RenderText(double n, tiny3d::Point xy, uint32_t scale, const mmlVector<3> &color) = 0; 72 | virtual void FinishRender(bool update_video_out = true) = 0; 73 | virtual void ToggleDepthView( void ) = 0; 74 | virtual bool DepthViewEnabled( void ) const = 0; 75 | virtual uint32_t GetRenderWidth( void ) const = 0; 76 | virtual uint32_t GetRenderHeight( void ) const = 0; 77 | virtual bool ToTexture(retro3d::Texture &tex) const = 0; 78 | virtual bool SetSkyBox(const tiny3d::Image &left, const tiny3d::Image &right, const tiny3d::Image &up, const tiny3d::Image &down, const tiny3d::Image &front, const tiny3d::Image &back) = 0; 79 | virtual void ToggleSkybox( void ) = 0; 80 | virtual bool SkyboxEnabled( void ) const = 0; 81 | virtual float GetHorizontalFieldOfView( void ) const = 0; 82 | virtual float GetVerticalFieldOfView( void ) const = 0; 83 | virtual void SetHorizontalFieldOfView(float hori_fov) = 0; 84 | virtual retro3d::Frustum GetViewFrustum( void ) const = 0; 85 | 86 | virtual void Debug_RenderTriangle(const retro3d::Vertex &a, const retro3d::Vertex &b, const retro3d::Vertex &c, const mmlMatrix<4,4> &obj_to_world, const mmlMatrix<4,4> &world_to_view, const retro3d::Texture *texture, LightMode light_mode) = 0; 87 | }; 88 | 89 | } 90 | 91 | #endif // RETRO_RENDERDEVICE_H 92 | -------------------------------------------------------------------------------- /common/md5_old/md5.cpp: -------------------------------------------------------------------------------- 1 | // md5.cpp 2 | // github.com/SirJonthe 3 | // 2019 4 | 5 | // Public domain 6 | 7 | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 8 | // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 9 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 10 | 11 | #include "md5.h" 12 | 13 | std::string md5(const std::string &message) 14 | { 15 | return md5sum(message).hex(); 16 | } 17 | 18 | md5sum::md5sum( void ) 19 | { 20 | for (uint32_t i = 0; i < 16; ++i) { 21 | m_digest[i] = 0; 22 | } 23 | } 24 | 25 | md5sum::md5sum(const std::string &message) 26 | { 27 | calc_sum(message); 28 | } 29 | 30 | md5sum::md5sum(const char *message, uint64_t byte_size) 31 | { 32 | calc_sum(message, byte_size); 33 | } 34 | 35 | md5sum &md5sum::operator=(const std::string &message) 36 | { 37 | calc_sum(message); 38 | return *this; 39 | } 40 | 41 | uint32_t md5sum::leftrotate(uint32_t x, uint32_t c) 42 | { 43 | return (x << c) | (x >> (32 - c)); 44 | } 45 | 46 | void md5sum::calc_sum(std::string message) 47 | { 48 | constexpr uint32_t CHUNK_BYTESIZE = 512 / CHAR_BIT; 49 | 50 | // Table of shift offsets 51 | constexpr uint32_t ShiftTable[CHUNK_BYTESIZE] = { 52 | 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 53 | 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 54 | 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 55 | 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 56 | }; 57 | 58 | // Precomputed table of integer sines (in radians) 59 | constexpr uint32_t SineTable[CHUNK_BYTESIZE] = { 60 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 61 | 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 62 | 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 63 | 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 64 | 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 65 | 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 66 | 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 67 | 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 68 | 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 69 | 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 70 | 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 71 | 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 72 | 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 73 | 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 74 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 75 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 76 | }; 77 | 78 | // Initialization 79 | uint32_t *X = reinterpret_cast(m_digest); 80 | enum {a0,b0,c0,d0}; 81 | X[a0] = 0x67452301; // A 82 | X[b0] = 0xefcdab89; // B 83 | X[c0] = 0x98badcfe; // C 84 | X[d0] = 0x10325476; // D 85 | 86 | // Compute padding. 87 | const uint64_t OriginalMessageSize = message.size(); 88 | uint32_t PaddingSize = CHUNK_BYTESIZE - (OriginalMessageSize % CHUNK_BYTESIZE); 89 | if (PaddingSize < sizeof(uint64_t)) { // Padding must at least fit 64-bit number of bits of input message 90 | PaddingSize += CHUNK_BYTESIZE; 91 | } 92 | const uint64_t MessageSize = OriginalMessageSize + PaddingSize; 93 | 94 | // Resize the message if needed, all trailing zeroes. 95 | message.resize(MessageSize, 0); 96 | 97 | // If message is padded, add a first '1' to the padding. 98 | if (PaddingSize > 0) { 99 | message[OriginalMessageSize] = 0x80; 100 | } 101 | 102 | // Store size (64 bits) of original message in bits at the end of the message 103 | const uint64_t OriginalMessageBitSize = (OriginalMessageSize * CHAR_BIT); 104 | for (uint32_t i = 0; i < sizeof(uint64_t); ++i) { 105 | message[MessageSize - sizeof(uint64_t) + i] = reinterpret_cast(&OriginalMessageBitSize)[i]; 106 | } 107 | 108 | // Process every 512-bit chunk 109 | for (uint32_t chunk = 0; chunk < message.size(); chunk += CHUNK_BYTESIZE) { 110 | const uint32_t *M = reinterpret_cast(message.c_str() + chunk); 111 | 112 | uint32_t A = X[a0]; 113 | uint32_t B = X[b0]; 114 | uint32_t C = X[c0]; 115 | uint32_t D = X[d0]; 116 | 117 | // Process every 64 bytes in chunk 118 | for (uint32_t i = 0; i < CHUNK_BYTESIZE; ++i) { 119 | uint32_t F = 0; 120 | uint32_t g = 0; 121 | if (i < 16) { 122 | F = (B & C) | ((~B) & D); 123 | g = i; 124 | } else if (i < 32) { 125 | F = (D & B) | ((~D) & C); 126 | g = (5*i + 1) % 16; 127 | } else if (i < 48) { 128 | F = B ^ C ^ D; 129 | g = (3*i + 5) % 16; 130 | } else { 131 | F = C ^ (B | (~D)); 132 | g = (7*i) % 16; 133 | } 134 | 135 | F = F + A + SineTable[i] + M[g]; 136 | A = D; 137 | D = C; 138 | C = B; 139 | B += leftrotate(F, ShiftTable[i]); 140 | } 141 | 142 | // Add to result 143 | X[a0] += A; 144 | X[b0] += B; 145 | X[c0] += C; 146 | X[d0] += D; 147 | } 148 | } 149 | 150 | void md5sum::calc_sum(const char *message, uint64_t byte_size) 151 | { 152 | calc_sum(std::string(message, size_t(byte_size))); 153 | } 154 | 155 | std::string md5sum::hex( void ) const 156 | { 157 | char out[33]; 158 | for (uint32_t i = 0; i < 16; ++i) { 159 | sprintf(out + (i*2), "%02x", m_digest[i]); 160 | } 161 | out[32] = '\0'; 162 | return std::string(out); 163 | } 164 | 165 | bool md5sum::operator==(const md5sum &r) const 166 | { 167 | for (uint32_t i = 0; i < 16; ++i) { 168 | if (m_digest[i] != r.m_digest[i]) { return false; } 169 | } 170 | return true; 171 | } 172 | 173 | bool md5sum::operator!=(const md5sum &r) const 174 | { 175 | for (uint32_t i = 0; i < 16; ++i) { 176 | if (m_digest[i] == r.m_digest[i]) { return false; } 177 | } 178 | return true; 179 | } 180 | 181 | md5sum::operator const uint8_t*( void ) const 182 | { 183 | return m_digest; 184 | } 185 | 186 | -------------------------------------------------------------------------------- /physics/retro_collider.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_COLLIDER_H 2 | #define RETRO_COLLIDER_H 3 | 4 | #include "../common/MiniLib/MML/mmlVector.h" 5 | #include "../common/MiniLib/MML/mmlMatrix.h" 6 | #include "../common/MiniLib/MGL/mglCollision.h" 7 | #include "../graphics/retro_model.h" 8 | #include "../common/retro_transform.h" 9 | 10 | // https://gamedev.stackexchange.com/questions/25950/how-do-i-make-a-collision-between-aabbs-slide 11 | 12 | // For basic collision resolution 13 | // http://noonat.github.io/intersect/ 14 | 15 | namespace retro3d 16 | { 17 | 18 | class AABBCollider; 19 | class PolyCollider; 20 | 21 | struct Ray 22 | { 23 | mmlVector<3> origin; 24 | mmlVector<3> direction; 25 | float length; 26 | 27 | typedef mglRayCollision3D Contact; 28 | 29 | Ray( void ); 30 | Ray(const mmlVector<3> &p_origin, const mmlVector<3> &p_direction, float p_length = -1.0f); 31 | 32 | Ray ApplyTransform(const retro3d::Transform &transform) const; 33 | }; 34 | 35 | class Collider 36 | { 37 | friend class AABBCollider; 38 | friend class PolyCollider; 39 | 40 | public: 41 | class Contact 42 | { 43 | public: 44 | mmlVector<3> point = mmlVector<3>::Fill(0.0f); 45 | mmlVector<3> normal = mmlVector<3>::Fill(0.0f); 46 | float depth = 0.0f; 47 | 48 | private: 49 | struct Cache 50 | { 51 | // information about the last collision 52 | // used to speed up subsequent tests between the same collider pairs 53 | }; 54 | 55 | Cache m_cache; 56 | }; 57 | 58 | protected: 59 | retro3d::SharedTransform m_transform; // from object to world space 60 | retro3d::AABB m_obj_aabb; // object space AABB 61 | 62 | protected: // double dispatch functions 63 | virtual bool DD_IsColliding(const retro3d::AABBCollider &c, retro3d::Collider::Contact *out) const = 0; 64 | virtual bool DD_IsColliding(const retro3d::PolyCollider &c, retro3d::Collider::Contact *out) const = 0; 65 | 66 | public: 67 | static bool AABB_DetectCollision(const retro3d::Collider &a, const retro3d::Ray &r, retro3d::Ray::Contact *contact_info = nullptr); 68 | static bool AABB_DetectCollision(const retro3d::Collider &a, const retro3d::Collider &b); 69 | static bool GJK_DetectCollision(const retro3d::Collider &a, const retro3d::Collider &b, retro3d::Collider::Contact *contact_info = nullptr); // Slower than specialized functions, but works for *all* shapes that implement FindExtremePoint, avoiding a n² coding problem between contacts between two types of colliders. 70 | 71 | public: 72 | Collider( void ); 73 | virtual ~Collider( void ); 74 | 75 | void AttachTransform(retro3d::SharedTransform transform); 76 | void SetTransform(const retro3d::Transform &transform); 77 | const retro3d::Transform &GetTransform( void ) const; 78 | retro3d::Transform &GetTransform( void ); 79 | retro3d::SharedTransform GetSharedTransform( void ) const; 80 | retro3d::AABB GetLocalAABB( void ) const; 81 | void SetLocalAABB(const retro3d::AABB &obj_aabb); 82 | retro3d::AABB GetAABB( void ) const; 83 | 84 | // single dispatch 85 | virtual bool IsColliding(const retro3d::Ray &world_ray, retro3d::Ray::Contact *out) const = 0; 86 | // double dispatch 87 | virtual bool IsColliding(const retro3d::Collider &c, retro3d::Collider::Contact *out) const = 0; 88 | 89 | virtual mmlVector<3> FindExtremePoint(const mmlVector<3> &world_search_direction) const = 0; 90 | }; 91 | 92 | class AABBCollider : public Collider 93 | { 94 | protected: // double dispatch functions 95 | bool DD_IsColliding(const retro3d::AABBCollider &c, retro3d::Collider::Contact *out) const override; 96 | bool DD_IsColliding(const retro3d::PolyCollider &c, retro3d::Collider::Contact *out) const override; 97 | 98 | public: 99 | // single dispatch 100 | bool IsColliding(const retro3d::Ray &world_ray, retro3d::Ray::Contact *out) const override; 101 | // double dispatch 102 | bool IsColliding(const retro3d::Collider &c, retro3d::Collider::Contact *out) const override; 103 | 104 | mmlVector<3> FindExtremePoint(const mmlVector<3> &world_search_direction) const override; 105 | }; 106 | 107 | // class SphereCollider : public Collider 108 | // {}; 109 | 110 | // class PlaneCollider : public Collider 111 | // {}; 112 | 113 | // class PointCollider : public Collider 114 | // {}; 115 | 116 | // class OBBCollider : public Collider 117 | // {}; 118 | 119 | class PolyCollider : public Collider 120 | { 121 | protected: 122 | retro3d::Array< mmlVector<3> > m_vert; 123 | retro3d::Array< retro3d::FaceIndexV > m_face; 124 | 125 | private: 126 | bool IsCollidingRay(const retro3d::Ray &world_ray, retro3d::Ray::Contact *out) const; 127 | 128 | protected: // double dispatch functions 129 | bool DD_IsColliding(const retro3d::AABBCollider &c, retro3d::Collider::Contact *out) const override; 130 | bool DD_IsColliding(const retro3d::PolyCollider &c, retro3d::Collider::Contact *out) const override; 131 | 132 | public: 133 | // single dispatch 134 | bool IsColliding(const retro3d::Ray &world_ray, retro3d::Ray::Contact *out) const override; 135 | // double dispatch 136 | bool IsColliding(const retro3d::Collider &c, retro3d::Collider::Contact *out) const override; 137 | 138 | void SetGeometry(const retro3d::Array< mmlVector<3> > &vert, const retro3d::Array< retro3d::FaceIndexV > &faces); 139 | void SetGeometry(const retro3d::Array< mmlVector<3> > &vert, const retro3d::Array< retro3d::FaceIndexVN > &faces); 140 | void SetGeometry(const retro3d::Array< mmlVector<3> > &vert, const retro3d::Array< retro3d::FaceIndex > &faces); 141 | 142 | mmlVector<3> FindExtremePoint(const mmlVector<3> &world_search_direction) const override; 143 | }; 144 | 145 | } 146 | 147 | #endif // RETRO_COLLIDER_H 148 | -------------------------------------------------------------------------------- /ecs/retro_entity.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_ENTITY_H 2 | #define RETRO_ENTITY_H 3 | 4 | #include 5 | #include 6 | #include "../common/retro_time.h" 7 | #include "../common/MiniLib/MTL/mtlPointer.h" 8 | #include "../serial/retro_serialize.h" 9 | 10 | namespace retro3d 11 | { 12 | 13 | class Engine; 14 | class RenderDevice; 15 | class SoundDevice; 16 | class InputDevice; 17 | 18 | class Entity : public mtlInherit< retro3d::Serializeable, Entity > 19 | { 20 | friend class Engine; 21 | 22 | private: 23 | std::string m_tag; 24 | uint64_t m_filter_flags; 25 | const uint64_t m_uuid; 26 | Engine *m_engine; 27 | retro3d::RealTimeTimer m_game_timer; 28 | retro3d::Time m_real_time_spawn; 29 | retro3d::Time m_sim_time_spawn; 30 | retro3d::Time m_game_time; 31 | double m_delta_time; 32 | int32_t m_is_active; 33 | bool m_should_destroy; 34 | 35 | protected: 36 | // Called immediately after the engine has initialized the entity. 37 | virtual void OnSpawn( void ); 38 | 39 | // Called periodically every engine loop. 40 | virtual void OnUpdate( void ); 41 | 42 | // Called when two objects with collider components overlap. 43 | virtual void OnCollision(retro3d::Entity&); 44 | 45 | // Called on the engine's discretion when the engine destroys an entity marked for destruction. 46 | virtual void OnDestroy( void ); 47 | 48 | public: 49 | // Construction. 50 | Entity( void ); 51 | Entity(const Entity&) = delete; 52 | Entity &operator=(const Entity&) = delete; 53 | 54 | // Marks the object (and all its components) for destruction. Engine decides when to actually free up the memory and invalidate references. 55 | void Destroy( void ); 56 | 57 | // Determines if the entity is marked for destruction. 58 | bool IsDestroyed( void ) const; 59 | 60 | // Determines if the entity is active. 61 | bool IsActive( void ) const; 62 | 63 | // Recursively deactivates entity. 64 | void Deactivate( void ); 65 | 66 | // Recursively activates entity. 67 | void Activate( void ); 68 | 69 | // Returns this entity's unique instance ID. 70 | uint64_t GetUUID( void ) const; 71 | 72 | // Gets the parent engine. 73 | const retro3d::Engine *GetEngine( void ) const; 74 | retro3d::Engine *GetEngine( void ); 75 | 76 | // Gets the parent renderer. 77 | retro3d::RenderDevice *GetRenderer( void ); 78 | const retro3d::RenderDevice *GetRenderer( void ) const; 79 | 80 | // Gets the parent sound device. 81 | retro3d::SoundDevice *GetSoundDevice( void ); 82 | const retro3d::SoundDevice *GetSoundDevice( void ) const; 83 | 84 | // Gets the parent input device. 85 | retro3d::InputDevice *GetInput( void ); 86 | const retro3d::InputDevice *GetInput( void ) const; 87 | 88 | // Get and set the customized tag of the entity. 89 | const std::string &GetTag( void ) const; 90 | void SetTag(const std::string &name); 91 | 92 | // Returns the unscaled lifetime this object has existed. 93 | retro3d::Time RealLifeTime( void ) const; 94 | 95 | // Returns the scaled simulated lifetime this object has existed. 96 | retro3d::Time SimulationLifeTime( void ) const; 97 | 98 | // Returns the user-scaled time this object has existed. 99 | retro3d::Time GameLifeTime( void ) const; 100 | 101 | // Returns the specified type of time. 102 | retro3d::Time LifeTime(retro3d::TimerType type) const; 103 | 104 | // Returns the scaled time delta (in seconds) since last update. 105 | double DeltaTime( void ) const; 106 | 107 | // Get and set the time scale for this object. 108 | void SetTimeScale(double time_scale); 109 | double GetTimeScale( void ) const; 110 | 111 | // Creates a child timer of the entity game timer. 112 | retro3d::RealTimeTimer CreateGameTimer(uint32_t num_ticks = 1, retro3d::Time over_time = 1_s) const; 113 | 114 | // Creates a child timer of the specified type. 115 | retro3d::RealTimeTimer CreateTimer(retro3d::TimerType type, uint32_t num_ticks = 1, retro3d::Time over_time = 1_s) const; 116 | 117 | // Return the filter flags for the entity. 118 | uint64_t GetFilterFlags( void ) const; 119 | 120 | // Return the state of a single filter flag of the entity. 121 | bool GetFilterFlag(uint32_t flag_index) const; 122 | 123 | // Set the complete state of the filter flags of the entity. 124 | void SetFilterFlags(uint64_t filter_flags); 125 | 126 | // Set the state of a single filter flag of the entity. 127 | void SetFilterFlag(uint32_t flag_index, bool state); 128 | 129 | // Adds a component to the entity and returns it. 130 | template < typename component_t, typename... Args > component_t *AddComponent(Args&&... args); 131 | 132 | // Removes a component from the entity. 133 | template < typename component_t > void RemoveComponent( void ); 134 | 135 | // Get an existing component. Null if component was never added to the object (or has since been removed). 136 | template < typename component_t > component_t *GetComponent( void ); 137 | template < typename component_t > const component_t *GetComponent( void ) const; 138 | }; 139 | 140 | } 141 | 142 | #include "../retro3d.h" 143 | 144 | template < typename component_t, typename... Args > 145 | component_t *retro3d::Entity::AddComponent(Args&&... args) 146 | { 147 | return m_engine->AddComponent(*this, std::forward(args)...); 148 | } 149 | 150 | template < typename component_t > 151 | void retro3d::Entity::RemoveComponent( void ) 152 | { 153 | m_engine->RemoveComponent(*this); 154 | } 155 | 156 | template < typename component_t > 157 | component_t *retro3d::Entity::GetComponent( void ) 158 | { 159 | return m_engine->GetComponent(*this); 160 | } 161 | 162 | template < typename component_t > 163 | const component_t *retro3d::Entity::GetComponent( void ) const 164 | { 165 | return m_engine->GetComponent(*this); 166 | } 167 | 168 | #endif // RETRO_ENTITY_H 169 | -------------------------------------------------------------------------------- /ecs/components/retro_render_component.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_render_component.h" 2 | #include "retro_transform_component.h" 3 | #include "../retro_entity.h" 4 | #include "../../common/MiniLib/MML/mmlMath.h" 5 | 6 | namespace retro3d { retro_register_component(RenderComponent) } 7 | 8 | void retro3d::RenderComponent::OnSpawn( void ) 9 | { 10 | m_transform = GetObject()->AddComponent()->GetTransform(); 11 | m_occlusion_collider.AttachTransform(m_transform); 12 | if (m_current_animation == nullptr) { 13 | SetAnimation("idle"); 14 | } 15 | } 16 | 17 | void retro3d::RenderComponent::OnUpdate( void ) 18 | { 19 | if (m_current_animation != nullptr) { 20 | float delta_time = float(GetObject()->DeltaTime()) * m_animation_speed_scale; 21 | m_current_frame_countdown -= delta_time; 22 | while (m_current_frame_countdown <= 0.0f) { 23 | m_frame_index = (m_frame_index + 1) % uint32_t(m_current_animation->frames.GetSize()); 24 | float new_duration = m_current_animation->frames[m_frame_index].display_time; 25 | m_current_frame_countdown += new_duration > 0.0f ? new_duration : delta_time; 26 | } 27 | } 28 | } 29 | 30 | retro3d::RenderComponent::RenderComponent( void ) : 31 | mtlInherit(this), 32 | m_transform(), 33 | m_animations(), m_first_animation(nullptr), m_current_animation(nullptr), 34 | m_frame_index(0), m_current_frame_countdown(0.0f), 35 | m_biggest_aabb(), 36 | m_occlusion_collider(), 37 | m_light_mode(retro3d::RenderDevice::LightMode_Dynamic), 38 | m_animation_speed_scale(1.0f) 39 | { 40 | CreateAnimation("idle", 1); 41 | } 42 | 43 | mtlShared retro3d::RenderComponent::GetModel( void ) 44 | { 45 | return m_current_animation != nullptr ? m_current_animation->frames[m_frame_index].model : mtlShared(); 46 | } 47 | 48 | const mtlShared retro3d::RenderComponent::GetModel( void ) const 49 | { 50 | return m_current_animation != nullptr ? m_current_animation->frames[m_frame_index].model : mtlShared(); 51 | } 52 | 53 | void retro3d::RenderComponent::SetFrame(const mtlShared< retro3d::Model > &model, float display_time) 54 | { 55 | if (m_current_animation != nullptr) { 56 | m_current_animation->frames[m_frame_index].model = model; 57 | m_current_animation->frames[m_frame_index].display_time = display_time; 58 | m_current_animation->biggest_aabb = m_current_animation->biggest_aabb | model->aabb; 59 | m_biggest_aabb = m_biggest_aabb | m_current_animation->biggest_aabb; 60 | m_occlusion_collider.SetLocalAABB(m_biggest_aabb); 61 | } 62 | } 63 | 64 | retro3d::AABB retro3d::RenderComponent::GetBiggestAnimationAABB( void ) const 65 | { 66 | return m_current_animation != nullptr ? m_current_animation->biggest_aabb : retro3d::AABB(); 67 | } 68 | 69 | retro3d::AABB retro3d::RenderComponent::GetBiggestAABB( void ) const 70 | { 71 | return m_biggest_aabb; 72 | } 73 | 74 | const retro3d::AABBCollider &retro3d::RenderComponent::GetOcclusionCollider( void ) const 75 | { 76 | return m_occlusion_collider; 77 | } 78 | 79 | void retro3d::RenderComponent::CreateAnimation(const mtlChars &animation_name, uint32_t frame_count) 80 | { 81 | Animation *a = m_animations.CreateEntry(animation_name); 82 | 83 | mtlShared default_copy; 84 | default_copy.New(); 85 | *default_copy.GetShared() = *retro3d::Engine::DefaultModel().GetShared(); 86 | 87 | a->frames.Create(mmlMax(1, int(frame_count))); 88 | for (int i = 0; i < a->frames.GetSize(); ++i) { 89 | a->frames[i].model = default_copy; 90 | } 91 | 92 | if (m_current_animation == nullptr) { 93 | m_current_animation = a; 94 | } 95 | if (m_first_animation == nullptr) { 96 | m_first_animation = a; 97 | } 98 | } 99 | 100 | void retro3d::RenderComponent::CreateAnimation(uint32_t frame_count) 101 | { 102 | if (m_current_animation != nullptr) { 103 | mtlShared default_copy; 104 | default_copy.New(); 105 | *default_copy.GetShared() = *retro3d::Engine::DefaultModel().GetShared(); 106 | 107 | m_current_animation->frames.Create(mmlMax(1, int(frame_count))); 108 | for (int i = 0; i < m_current_animation->frames.GetSize(); ++i) { 109 | m_current_animation->frames[i].model = default_copy; 110 | } 111 | } 112 | } 113 | 114 | void retro3d::RenderComponent::SetAnimation(const mtlChars &animation_name) 115 | { 116 | if (m_first_animation == nullptr) { 117 | std::cout << "[Warning] No animations available." << std::endl; 118 | return; 119 | } 120 | 121 | Animation *a = m_animations.GetEntry(animation_name); 122 | if (m_current_animation == a) { return; } 123 | 124 | m_current_animation = a; 125 | 126 | if (m_current_animation == nullptr) { 127 | std::cout << "[Warning] Missing animation \"" << std::string(animation_name.GetChars(), size_t(animation_name.GetSize())) << "\". Defaulting to \"idle\"." << std::endl; 128 | m_current_animation = m_animations.GetEntry("idle"); 129 | if (m_current_animation == nullptr) { 130 | std::cout << "[Warning] Missing animation \"idle\". Defaulting to first animation." << std::endl; 131 | m_current_animation = m_first_animation; 132 | } 133 | } 134 | m_frame_index = 0; 135 | m_current_frame_countdown = m_current_animation->frames[m_frame_index].display_time; 136 | } 137 | 138 | uint32_t retro3d::RenderComponent::GetFrameIndex( void ) const 139 | { 140 | return m_frame_index; 141 | } 142 | 143 | void retro3d::RenderComponent::SetFrameIndex(uint32_t i) 144 | { 145 | if (m_current_animation != nullptr) { 146 | m_frame_index = (i % uint32_t(m_current_animation->frames.GetSize())); 147 | } 148 | } 149 | 150 | uint32_t retro3d::RenderComponent::GetAnimationFrameCount( void ) const 151 | { 152 | return m_current_animation != nullptr ? uint32_t(m_current_animation->frames.GetSize()) : 0; 153 | } 154 | 155 | mmlMatrix<4,4> retro3d::RenderComponent::GetTransformMatrix( void ) const 156 | { 157 | const retro3d::TransformComponent *t = GetObject()->GetComponent(); 158 | return t != nullptr ? t->GetTransform()->GetFinalMatrix() : mmlMatrix<4,4>::Identity(); 159 | } 160 | 161 | retro3d::RenderDevice::LightMode retro3d::RenderComponent::GetLightMode( void ) const 162 | { 163 | return m_light_mode; 164 | } 165 | 166 | void retro3d::RenderComponent::SetLightMode(retro3d::RenderDevice::LightMode light_mode) 167 | { 168 | m_light_mode = light_mode; 169 | } 170 | 171 | float retro3d::RenderComponent::GetAnimationSpeedScale( void ) const 172 | { 173 | return m_animation_speed_scale; 174 | } 175 | 176 | void retro3d::RenderComponent::SetAnimationSpeedScale(float scale) 177 | { 178 | m_animation_speed_scale = scale; 179 | } 180 | -------------------------------------------------------------------------------- /backend/sdl_video_device.cpp: -------------------------------------------------------------------------------- 1 | #include "sdl_video_device.h" 2 | 3 | #ifdef RETRO3D_USE_SDL1 4 | #include 5 | #define SDL_STR "SDL1" 6 | #elif defined(RETRO3D_USE_SDL2) 7 | #include 8 | #define SDL_STR "SDL2" 9 | #endif 10 | 11 | #ifdef RETRO3D_USE_SDL2 12 | static SDL_Renderer *Renderer = nullptr; 13 | static SDL_Window *Window = nullptr; 14 | static SDL_Surface *Surface = nullptr; 15 | #endif 16 | 17 | platform::SDLVideoDevice::~SDLVideoDevice( void ) 18 | { 19 | #ifdef RETRO3D_USE_SDL1 20 | SDL_FreeSurface(SDL_GetVideoSurface()); 21 | #elif defined(RETRO3D_USE_SDL2) 22 | SDL_DestroyRenderer(Renderer); 23 | SDL_DestroyWindow(Window); 24 | #endif 25 | std::cout << "[SDLVideoDevice::dtor (" << SDL_STR << ")] Quitting subsystem SDL_VIDEO" << std::endl; 26 | SDL_QuitSubSystem(SDL_INIT_VIDEO); 27 | } 28 | 29 | bool platform::SDLVideoDevice::Init( void ) 30 | { 31 | if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { 32 | std::cout << "[SDLVideoDevice::ctor (" << SDL_STR << ")] " << SDL_GetError() << std::endl; 33 | return false; 34 | } 35 | return true; 36 | } 37 | 38 | bool platform::SDLVideoDevice::CreateWindow(uint32_t width, uint32_t height, bool enable_fullscreen) 39 | { 40 | DestroyWindow(); 41 | 42 | #ifdef RETRO3D_USE_SDL1 43 | SDL_SetVideoMode(width, height, 24, SDL_SWSURFACE|(enable_fullscreen ? SDL_FULLSCREEN : 0)); 44 | if (SDL_GetVideoSurface() == nullptr) { 45 | std::cout << "[SDLVideoDevice::CreateWindow (" << SDL_STR << ")] " << SDL_GetError() << std::endl; 46 | return false; 47 | } 48 | #elif defined(RETRO3D_USE_SDL2) 49 | Window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_SWSURFACE|(enable_fullscreen ? SDL_WINDOW_FULLSCREEN : 0)); 50 | if (Window == nullptr) { 51 | std::cout << "[SDLVideoDevice::CreateWindow (" << SDL_STR << ")] " << SDL_GetError() << std::endl; 52 | return false; 53 | } 54 | Surface = SDL_GetWindowSurface(Window); 55 | if (Surface == nullptr) { 56 | SDL_DestroyWindow(Window); 57 | Window = nullptr; 58 | std::cout << "[SDLVideoDevice::CreateWindow (" << SDL_STR << ")] " << SDL_GetError() << std::endl; 59 | return false; 60 | } 61 | Renderer = SDL_CreateSoftwareRenderer(Surface); 62 | if (Renderer == nullptr) { 63 | SDL_DestroyWindow(Window); 64 | Window = nullptr; 65 | std::cout << "[SDLVideoDevice::CreateWindow (" << SDL_STR << ")] " << SDL_GetError() << std::endl; 66 | return false; 67 | } 68 | #endif 69 | return true; 70 | } 71 | 72 | void platform::SDLVideoDevice::SetWindowCaption(const std::string &caption) 73 | { 74 | #ifdef RETRO3D_USE_SDL1 75 | SDL_WM_SetCaption(caption.c_str(), nullptr); 76 | #elif defined(RETRO3D_USE_SDL2) 77 | SDL_SetWindowTitle(Window, caption.c_str()); 78 | #endif 79 | } 80 | 81 | void platform::SDLVideoDevice::DestroyWindow( void ) 82 | { 83 | #ifdef RETRO3D_USE_SDL1 84 | SDL_FreeSurface(SDL_GetVideoSurface()); 85 | #elif defined(RETRO3D_USE_SDL2) 86 | SDL_DestroyRenderer(Renderer); 87 | SDL_DestroyWindow(Window); 88 | Renderer = nullptr; 89 | Window = nullptr; 90 | Surface = nullptr; 91 | #endif 92 | } 93 | 94 | void platform::SDLVideoDevice::FromImage(const tiny3d::Image &src, const retro3d::URect &dst_rect) 95 | { 96 | // TODO: From a surface that the renderer used to the surface the video uses 97 | // NOTE: Transfers src to video out. 98 | // NOTE: Requires the target and destination buffer to be the same ratio in both dimensions. 99 | 100 | SDL_Surface *video_out = 101 | #ifdef RETRO3D_USE_SDL1 102 | SDL_GetVideoSurface() 103 | #elif defined(RETRO3D_USE_SDL2) 104 | Surface 105 | #endif 106 | ; 107 | 108 | if (video_out == nullptr) { return; } 109 | if (float(src.GetWidth()) / video_out->w != float(src.GetHeight()) / video_out->h) { return; } // NOTE: This enforces that aspect ratio on src has to be the same as dst. 110 | 111 | const tiny3d::UXInt vid_width = tiny3d::UXInt(video_out->w); 112 | const tiny3d::UXInt vid_height = tiny3d::UXInt(video_out->h); 113 | const tiny3d::UXInt x_frac = (tiny3d::UXInt(src.GetWidth()) << 16) / vid_width; 114 | const tiny3d::UXInt y_frac = (tiny3d::UXInt(src.GetHeight()) << 16) / vid_height; 115 | 116 | tiny3d::Byte *pixel_row = reinterpret_cast(video_out->pixels) + dst_rect.a.x * video_out->format->BytesPerPixel + dst_rect.a.y * video_out->pitch; 117 | for (tiny3d::UXInt y = dst_rect.a.y; y < dst_rect.b.y; ++y) { 118 | tiny3d::Byte *pixels = pixel_row; 119 | for (tiny3d::UXInt x = dst_rect.a.x; x < dst_rect.b.x; ++x) { 120 | tiny3d::Color c = src.GetColor({tiny3d::UInt((x * x_frac) >> 16), tiny3d::UInt((y * y_frac) >> 16)}); 121 | pixels[0] = c.b; 122 | pixels[1] = c.g; 123 | pixels[2] = c.r; 124 | pixels += video_out->format->BytesPerPixel; 125 | } 126 | pixel_row += video_out->pitch; 127 | } 128 | } 129 | 130 | retro3d::Point platform::SDLVideoDevice::GetWindowPosition( void ) const 131 | { 132 | retro3d::Point p = { 0, 0 }; 133 | #ifdef RETRO3D_USE_SDL1 134 | // NOTE: There is no way to get window position in SDL1.2, so return 0,0. 135 | #elif defined(RETRO3D_USE_SDL2) 136 | SDL_GetWindowPosition(Window, &p.x, &p.y); 137 | #endif 138 | return p; 139 | } 140 | 141 | void platform::SDLVideoDevice::Display(const retro3d::Rect &rect) 142 | { 143 | SDL_Rect r; 144 | r.x = rect.a.x; 145 | r.y = rect.a.y; 146 | r.w = rect.b.x - rect.a.x; 147 | r.h = rect.b.y - rect.a.y; 148 | 149 | #ifdef RETRO3D_USE_SDL1 150 | SDL_UpdateRect(SDL_GetVideoSurface(), r.x, r.y, r.w, r.h); 151 | #elif defined(RETRO3D_USE_SDL2) 152 | SDL_UpdateWindowSurfaceRects(Window, &r, 1); 153 | #endif 154 | } 155 | 156 | void platform::SDLVideoDevice::Display( void ) 157 | { 158 | #ifdef RETRO3D_USE_SDL1 159 | SDL_Flip(SDL_GetVideoSurface()); 160 | #elif defined(RETRO3D_USE_SDL2) 161 | SDL_UpdateWindowSurface(Window); 162 | #endif 163 | } 164 | 165 | uint32_t platform::SDLVideoDevice::GetWindowWidth( void ) const 166 | { 167 | #ifdef RETRO3D_USE_SDL1 168 | return uint32_t(SDL_GetVideoSurface()->w); 169 | #elif defined(RETRO3D_USE_SDL2) 170 | return uint32_t(Surface->w); 171 | #endif 172 | } 173 | 174 | uint32_t platform::SDLVideoDevice::GetWindowHeight( void ) const 175 | { 176 | #ifdef RETRO3D_USE_SDL1 177 | return uint32_t(SDL_GetVideoSurface()->h); 178 | #elif defined(RETRO3D_USE_SDL2) 179 | return uint32_t(Surface->h); 180 | #endif 181 | } 182 | 183 | std::string platform::SDLVideoDevice::GetWindowCaption( void ) const 184 | { 185 | #ifdef RETRO3D_USE_SDL1 186 | char *caption; 187 | SDL_WM_GetCaption(&caption, nullptr); 188 | return std::string(caption); 189 | #elif defined(RETRO3D_USE_SDL2) 190 | return std::string(SDL_GetWindowTitle(Window)); 191 | #endif 192 | } 193 | -------------------------------------------------------------------------------- /common/retro_transform.cpp: -------------------------------------------------------------------------------- 1 | #include "retro_transform.h" 2 | 3 | bool retro3d::Transform::SelfRef(const retro3d::Transform *t) const 4 | { 5 | return t == this || (m_parent.IsNull() == false ? m_parent->SelfRef(t) : false); 6 | } 7 | 8 | mmlVector<3> retro3d::Transform::GetWorldRight( void ) 9 | { 10 | mmlVector<3> x; 11 | x[0] = 1.0f; 12 | x[1] = 0.0f; 13 | x[2] = 0.0f; 14 | return x; 15 | } 16 | 17 | mmlVector<3> retro3d::Transform::GetWorldUp( void ) 18 | { 19 | mmlVector<3> y; 20 | y[0] = 0.0f; 21 | y[1] = 1.0f; 22 | y[2] = 0.0f; 23 | return y; 24 | } 25 | 26 | mmlVector<3> retro3d::Transform::GetWorldForward( void ) 27 | { 28 | mmlVector<3> z; 29 | z[0] = 0.0f; 30 | z[1] = 0.0f; 31 | z[2] = 1.0f; 32 | return z; 33 | } 34 | 35 | mmlVector<3> retro3d::Transform::GetWorldAxis(int axis_index) 36 | { 37 | switch (axis_index) { 38 | case 0: return GetWorldRight(); 39 | case 1: return GetWorldUp(); 40 | case 2: return GetWorldForward(); 41 | } 42 | return mmlVector<3>::Fill(0.0f); 43 | } 44 | 45 | std::string retro3d::Transform::GetWorldAxisName(int axis_index) 46 | { 47 | switch (axis_index) { 48 | case 0: return "Right"; 49 | case 1: return "Up"; 50 | case 2: return "Forward"; 51 | } 52 | return "Error"; 53 | } 54 | 55 | retro3d::Transform::Transform(uint32_t space_from, uint32_t space_to) : mmlMatrix<4,4>(mmlMatrix<4,4>::Identity()), m_parent(), m_inv(mmlMatrix<4,4>::Identity()), m_rot(mmlMatrix<3,3>::Identity()), m_space_from(space_from), m_space_to(space_to), m_inv_updated(true), m_rot_updated(true) 56 | {} 57 | 58 | retro3d::Transform::Transform(const mmlMatrix<3,3> &basis, const mmlVector<3> &position) : Transform() 59 | { 60 | SetTransform(basis, position); 61 | } 62 | 63 | retro3d::Transform::Transform(const mmlMatrix<4,4> &transform) : mmlMatrix<4,4>(transform), m_parent(), m_inv(mmlMatrix<4,4>::Identity()), m_rot(mmlMatrix<3,3>::Identity()), m_space_from(Space_Object), m_space_to(Space_World), m_inv_updated(false), m_rot_updated(false) 64 | {} 65 | 66 | retro3d::Transform &retro3d::Transform::operator=(const mmlMatrix<4,4> &transform) 67 | { 68 | SetTransform(transform); 69 | return *this; 70 | } 71 | 72 | void retro3d::Transform::SetParent(mtlShared parent) 73 | { 74 | if (parent.IsNull() == false && SelfRef(parent.GetShared()) == false) { 75 | m_parent = parent; 76 | } else { 77 | OrphanTransform(); 78 | } 79 | } 80 | 81 | void retro3d::Transform::OrphanTransform( void ) 82 | { 83 | m_parent.Delete(); 84 | } 85 | 86 | void retro3d::Transform::SetTransform(const mmlMatrix<3,3> &basis, const mmlVector<3> &position) 87 | { 88 | SetTransform(mmlTransform(basis, position)); 89 | } 90 | 91 | void retro3d::Transform::SetTransform(const mmlMatrix<4,4> &transform) 92 | { 93 | for (int i = 0; i < 4; ++i) { 94 | for (int j = 0; j < 4; ++j) { 95 | (*this)[i][j] = transform[i][j]; 96 | } 97 | } 98 | m_rot_updated = false; 99 | m_inv_updated = false; 100 | } 101 | 102 | void retro3d::Transform::SetRotation(const mmlMatrix<3,3> &rotation) 103 | { 104 | const mmlVector<3> S = GetScale(); 105 | for (int i = 0; i < 3; ++i) { 106 | const mmlVector<3> row = mmlNormalize(rotation[i]) * S[i]; 107 | for (int j = 0; j < 3; ++j) { 108 | (*this)[i][j] = row[j]; 109 | } 110 | } 111 | m_inv_updated = false; 112 | m_rot_updated = false; 113 | } 114 | 115 | void retro3d::Transform::SetBasis(const mmlMatrix<3,3> &basis) 116 | { 117 | for (int i = 0; i < 3; ++i) { 118 | for (int j = 0; j < 3; ++j) { 119 | (*this)[i][j] = basis[i][j]; 120 | } 121 | } 122 | m_inv_updated = false; 123 | m_rot_updated = false; 124 | } 125 | 126 | void retro3d::Transform::SetPosition(const mmlVector<3> &position) 127 | { 128 | for (int i = 0; i < 3; ++i) { 129 | (*this)[i][3] = position[i]; 130 | } 131 | m_inv_updated = false; 132 | // does not affect rotation 133 | } 134 | 135 | void retro3d::Transform::NormalizeScale( void ) 136 | { 137 | mmlMatrix<3,3> rot = GetRotation(); 138 | for (int i = 0; i < 3; ++i) { 139 | for (int j = 0; j < 3; ++j) { 140 | (*this)[i][j] = rot[i][j]; 141 | } 142 | } 143 | m_inv_updated = false; 144 | // does not affect rotation 145 | } 146 | 147 | void retro3d::Transform::SetScale(const mmlVector<3> &xyz) 148 | { 149 | NormalizeScale(); 150 | for (int i = 0; i < Rows - 1; ++i) { 151 | for (int j = 0; j < Columns - 1; ++j) { 152 | (*this)[i][j] *= xyz[i]; 153 | } 154 | } 155 | m_inv_updated = false; 156 | // does not affect rotation 157 | } 158 | 159 | void retro3d::Transform::SetScale(float s) 160 | { 161 | SetScale(mmlVector<3>::Fill(s)); 162 | } 163 | 164 | mmlMatrix<4,4> retro3d::Transform::GetMatrix( void ) const 165 | { 166 | return *this; 167 | } 168 | 169 | mmlMatrix<4,4> retro3d::Transform::GetInvMatrix( void ) const 170 | { 171 | if (m_inv_updated == false) { 172 | m_inv = mmlInv(*this); 173 | m_inv_updated = true; 174 | } 175 | return m_inv; 176 | } 177 | 178 | mmlMatrix<3,3> retro3d::Transform::GetRotation( void ) const 179 | { 180 | if (m_rot_updated == false) { 181 | const mmlVector<3> S = GetScale(); 182 | for (int i = 0; i < 3; ++i) { 183 | m_rot[i] = mmlVector<3>((*this)[i]) / S[i]; 184 | } 185 | m_rot_updated = true; 186 | } 187 | return m_rot; 188 | } 189 | 190 | mmlMatrix<3,3> retro3d::Transform::GetBasis( void ) const 191 | { 192 | return mmlBasis(*this); 193 | } 194 | 195 | mmlVector<3> retro3d::Transform::GetPosition( void ) const 196 | { 197 | return mmlTranslation(*this); 198 | } 199 | 200 | mmlVector<3> retro3d::Transform::GetScale( void ) const 201 | { 202 | mmlVector<3> s; 203 | for (int i = 0; i < 3; ++i) { 204 | s[i] = mmlVector<3>((*this)[i]).Len(); 205 | } 206 | return s; 207 | } 208 | 209 | mmlVector<3> retro3d::Transform::GetRight( void ) const 210 | { 211 | return GetWorldRight() * GetRotation(); 212 | } 213 | 214 | mmlVector<3> retro3d::Transform::GetUp( void ) const 215 | { 216 | return GetWorldUp() * GetRotation(); 217 | } 218 | 219 | mmlVector<3> retro3d::Transform::GetForward( void ) const 220 | { 221 | return GetWorldForward() * GetRotation(); 222 | } 223 | 224 | retro3d::Transform retro3d::Transform::GetInvTransform( void ) const 225 | { 226 | Transform t; 227 | t = GetInvMatrix(); 228 | t.m_inv = *this; 229 | t.m_inv_updated = true; 230 | t.m_rot_updated = false; 231 | return t; 232 | } 233 | 234 | mmlMatrix<4,4> retro3d::Transform::GetFinalMatrix( void ) const 235 | { 236 | if (m_parent.IsNull() == true) { 237 | return *this; 238 | } 239 | return m_parent->GetFinalMatrix() * (*this); 240 | } 241 | 242 | mmlVector<3> retro3d::Transform::TransformPoint(const mmlVector<3> &point) const 243 | { 244 | return point * GetFinalMatrix(); 245 | } 246 | 247 | mmlVector<3> retro3d::Transform::TransformVector(const mmlVector<3> &vec) const 248 | { 249 | return vec * mmlBasis(GetFinalMatrix()); 250 | } 251 | 252 | mmlVector<3> retro3d::Transform::TransformNormal(const mmlVector<3> &normal) const 253 | { 254 | mmlVector<3> n = normal * mmlRotation(GetFinalMatrix()); 255 | n.NormalizeIf(); 256 | return n; 257 | } 258 | 259 | mmlVector<3> retro3d::Transform::InverseTransformPoint(const mmlVector<3> &point) const 260 | { 261 | return point * mmlInv(GetFinalMatrix()); 262 | } 263 | 264 | mmlVector<3> retro3d::Transform::InverseTransformVector(const mmlVector<3> &vec) const 265 | { 266 | return vec * mmlInv(mmlBasis(GetFinalMatrix())); 267 | } 268 | 269 | mmlVector<3> retro3d::Transform::InverseTransformNormal(const mmlVector<3> &normal) const 270 | { 271 | return normal * mmlInv(mmlRotation(GetFinalMatrix())); 272 | } 273 | -------------------------------------------------------------------------------- /backend/sdl_sound_device.cpp: -------------------------------------------------------------------------------- 1 | #ifdef RETRO3D_USE_SDL1 2 | #ifndef RETRO3D_MACOS 3 | #include 4 | #else 5 | #include 6 | #endif 7 | #include 8 | #define SDL_STR "SDL1" 9 | #elif defined(RETRO3D_USE_SDL2) 10 | #ifndef RETRO3D_MACOS 11 | #include 12 | #else 13 | #include 14 | #endif 15 | #include 16 | #define SDL_STR "SDL2" 17 | #endif 18 | #include "sdl_sound_device.h" 19 | 20 | void platform::SDLSoundDevice::UpdateAABB(platform::SDLSoundDevice::PlaybackJob &j) 21 | { 22 | const double r = double(j.radius); 23 | j.world_aabb = retro3d::AABB(mmlTranslation(j.world_transform->GetFinalMatrix()), mmlVector<3>(r, r, r)); 24 | } 25 | 26 | void platform::SDLSoundDevice::UpdateVolume(platform::SDLSoundDevice::PlaybackJob &j) 27 | { 28 | float vol = j.volume; 29 | switch (j.type) { 30 | case retro3d::Voice::Ambient: 31 | vol = j.volume; 32 | break; 33 | case retro3d::Voice::Point: 34 | { 35 | const mmlVector<3> sfx_vec = retro3d::VectorFromAToB(mmlTranslation(j.world_transform->GetFinalMatrix()), mmlTranslation(m_world_transform->GetFinalMatrix())); 36 | const float d = sfx_vec.Len(); 37 | vol = mmlIsApproxEqual(d, 0.0f) == false ? mmlMin(1.0f, j.volume / d) : 1.0f; 38 | // set panning 39 | // const mmlVector<3> right_normal = m_world_transform->GetRight(); 40 | // const mmlVector<3> left_normal = -right_normal; 41 | // std::cout << right_normal[0] << "," << right_normal[1] << "," << right_normal[2] << std::endl; 42 | // std::cout << left_normal[0] << "," << left_normal[1] << "," << left_normal[2] << std::endl; 43 | // uint32_t left_channel = mmlClamp(Uint8(127), Uint8(mmlDot(sfx_vec, left_normal) * 255.0f), Uint8(255)); 44 | // uint32_t right_channel = mmlClamp(Uint8(127), Uint8(mmlDot(sfx_vec, right_normal) * 255.0f), Uint8(255)); 45 | // std::cout << j.channel << "(" << left_channel << "," << right_channel << ")" << std::endl; 46 | // Mix_SetPanning(j.channel, mmlClamp(Uint8(127), Uint8(mmlDot(sfx_vec, left_normal) * 255.0f), Uint8(255)), mmlClamp(Uint8(127), Uint8(mmlDot(sfx_vec, right_normal) * 255.0f), Uint8(255))); 47 | // There seems to be an issue with Mix_SetPanning with default drivers (program halts, fucks up audio for other processes) 48 | } 49 | break; 50 | default: break; 51 | } 52 | Mix_VolumeChunk(reinterpret_cast(j.api_data), int(vol * MIX_MAX_VOLUME)); 53 | } 54 | 55 | platform::SDLSoundDevice::SDLSoundDevice( void ) : 56 | m_internal_transform_copy(retro3d::SharedTransform::Create()), 57 | m_world_transform(m_internal_transform_copy), 58 | m_format{ retro3d::Sound::Channels_Mono, 0, retro3d::Sound::SampleFormat_UINT8 }, 59 | m_audio_count(0) 60 | {} 61 | 62 | platform::SDLSoundDevice::~SDLSoundDevice( void ) 63 | { 64 | std::cout << "[SDLSoundDevice::dtor (" << SDL_STR << ")] Quitting subsystem SDL_mixer" << std::endl; 65 | Mix_CloseAudio(); 66 | Mix_Quit(); 67 | std::cout << "[SDLSoundDevice::dtor (" << SDL_STR << ")] Quitting subsystem SDL_AUDIO" << std::endl; 68 | SDL_QuitSubSystem(SDL_INIT_AUDIO); 69 | m_format.sample_rate = 0; 70 | } 71 | 72 | bool platform::SDLSoundDevice::Init(const retro3d::Sound::Format &format) 73 | { 74 | if (m_format.sample_rate != 0) { return false; } 75 | 76 | int freq = 0, chan = 0; 77 | Uint16 fmt = 0; 78 | 79 | if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) { 80 | std::cout << "[SDLSoundDevice::Init (" << SDL_STR << ")] " << SDL_GetError() << std::endl; 81 | return false; 82 | } 83 | 84 | bool result = 85 | // Mix_Init(MIX_INIT_OGG|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_FLAC) && // only needed when support for OGG, MOD, MP3, and FLAC is needed. WAV supported by default. 86 | Mix_OpenAudio(int(format.sample_rate), format.sample_format == retro3d::Sound::SampleFormat_INT16 ? AUDIO_S16LSB : AUDIO_U8, format.num_channels, 4096) == 0 && 87 | Mix_QuerySpec(&freq, &fmt, &chan) != 0; 88 | 89 | if (result == true) { 90 | m_format.sample_rate = uint32_t(freq); 91 | m_format.sample_format = fmt == AUDIO_S16LSB ? retro3d::Sound::SampleFormat_INT16 : retro3d::Sound::SampleFormat_UINT8; 92 | m_format.num_channels = chan == 1 ? retro3d::Sound::Channels_Mono : retro3d::Sound::Channels_Stereo; 93 | } else { 94 | std::cout << "[SDLSoundDevice::Init (" << SDL_STR << ")] " << Mix_GetError() << std::endl; 95 | m_format.sample_rate = 0; 96 | m_format.sample_format = retro3d::Sound::SampleFormat_UINT8; 97 | m_format.num_channels = retro3d::Sound::Channels_Mono; 98 | Mix_CloseAudio(); 99 | Mix_Quit(); 100 | SDL_QuitSubSystem(SDL_INIT_AUDIO); 101 | return false; 102 | } 103 | 104 | if ( (fmt != AUDIO_S16LSB && fmt == AUDIO_U8) || (chan != 1 && chan != 2) ) { 105 | std::cout << "[SDLSoundDevice::Init (" << SDL_STR << ")] Failed to initialize to requested format." << std::endl; 106 | return false; 107 | } 108 | 109 | return true; 110 | } 111 | 112 | void platform::SDLSoundDevice::SetReceiverTransform(const retro3d::SharedTransform &world_transform) 113 | { 114 | if (world_transform.IsNull() == false) { 115 | m_world_transform = world_transform; 116 | } else { 117 | *m_internal_transform_copy.GetShared() = mmlMatrix<4,4>::Identity(); 118 | m_world_transform = m_internal_transform_copy; 119 | } 120 | } 121 | 122 | void platform::SDLSoundDevice::SetReceiverTransform(const retro3d::Transform &world_transform) 123 | { 124 | *m_internal_transform_copy.GetShared() = world_transform; 125 | m_world_transform = m_internal_transform_copy; 126 | } 127 | 128 | retro3d::Transform platform::SDLSoundDevice::GetReceiverTransform( void ) const 129 | { 130 | return *m_world_transform.GetShared(); 131 | } 132 | 133 | retro3d::Sound::Format platform::SDLSoundDevice::GetFormat( void ) const 134 | { 135 | return m_format; 136 | } 137 | 138 | int32_t platform::SDLSoundDevice::Play(const retro3d::Voice &voice, const retro3d::SharedTransform &world_transform, double time_stamp) 139 | { 140 | if (m_format.sample_rate == 0) { return -1; } // the device has failed to initialize 141 | 142 | PlaybackJob j; 143 | j.sound = voice.GetSound(); 144 | retro3d::Sound *sfx = j.sound.GetShared(); 145 | if (sfx != nullptr && sfx->GetSampleCount() > 0) { 146 | 147 | if (m_format.sample_rate != sfx->GetSampleRate() || m_format.num_channels != sfx->GetChannelCount() || uint32_t(m_format.sample_format) != sfx->GetBitsPerSample()) { 148 | return -1; 149 | } 150 | 151 | uint32_t start_sample_index = sfx->GetSampleIndex(time_stamp); 152 | if (start_sample_index > sfx->GetSampleCount()) { return -1; } 153 | start_sample_index = start_sample_index * sfx->GetBytesPerSample(); 154 | 155 | j.world_transform = world_transform; 156 | j.radius = voice.GetRangeRadius(); 157 | UpdateAABB(j); 158 | j.type = voice.GetType(); 159 | j.volume = voice.GetVolume(); 160 | j.api_data = new Mix_Chunk; 161 | Mix_Chunk *chunk = reinterpret_cast(j.api_data); 162 | chunk->allocated = 0; 163 | chunk->abuf = sfx->GetSampleData().u8 + start_sample_index; 164 | chunk->alen = sfx->GetRawByteCount() - start_sample_index; 165 | UpdateVolume(j); 166 | j.channel = Mix_PlayChannel(-1, chunk, 0); 167 | int32_t index = m_audio_count++; 168 | 169 | if (j.channel != -1) { 170 | m_playback_jobs[index] = j; 171 | } 172 | 173 | return j.channel != -1 ? index : -1; 174 | } 175 | 176 | return -1; 177 | } 178 | 179 | int32_t platform::SDLSoundDevice::Play(const retro3d::Voice &voice, const retro3d::Transform &world_transform, double time_stamp) 180 | { 181 | retro3d::SharedTransform shared; 182 | shared.New(); 183 | *shared.GetShared() = world_transform; 184 | return Play(voice, shared, time_stamp); 185 | } 186 | 187 | void platform::SDLSoundDevice::Kill(int32_t audio_index) 188 | { 189 | if (audio_index < 0) { return; } 190 | 191 | Mix_FreeChunk(reinterpret_cast(m_playback_jobs[audio_index].api_data)); 192 | m_playback_jobs.erase(audio_index); 193 | } 194 | 195 | void platform::SDLSoundDevice::Update( void ) 196 | { 197 | for (PlaybackJobs::iterator i = m_playback_jobs.begin(); i != m_playback_jobs.end(); ++i) { 198 | UpdateAABB(i->second); 199 | UpdateVolume(i->second); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /common/retro_time.h: -------------------------------------------------------------------------------- 1 | #ifndef RETRO_TIME_H 2 | #define RETRO_TIME_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace retro3d 9 | { 10 | 11 | class RealTimeTimer; 12 | 13 | // A time class that measures time in fixed-point arithmetic. Mainly used to measure smaller (0 - MAX_TIME_MS) time spans. 14 | class Time 15 | { 16 | friend class RealTimeTimer; 17 | 18 | private: 19 | static constexpr uint64_t NUM_BITS = sizeof(uint64_t) * CHAR_BIT; 20 | static constexpr uint64_t SCALAR = NUM_BITS >> 1; 21 | static constexpr uint64_t PRECISION_MASK = (uint64_t(1) << SCALAR) - 1; 22 | static constexpr uint64_t RANGE_MASK = ~PRECISION_MASK; 23 | 24 | private: 25 | // Time in milliseconds. 26 | uint64_t time; 27 | 28 | public: 29 | // Construction. 30 | explicit Time(uint32_t ms = 0); 31 | Time(const Time&) = default; 32 | Time &operator=(const Time&) = default; 33 | 34 | // Useful constants. 35 | static constexpr uint64_t MAX_TIME_MS = std::numeric_limits::max() >> SCALAR; 36 | static constexpr uint64_t MAX_TIME_S = MAX_TIME_MS / 1000; 37 | static constexpr uint64_t MAX_TIME_M = MAX_TIME_S / 60; 38 | static constexpr uint64_t MAX_TIME_H = MAX_TIME_M / 60; 39 | static constexpr uint64_t MAX_TIME_D = MAX_TIME_H / 24; 40 | static constexpr uint64_t MAX_TIME_W = MAX_TIME_D / 7; 41 | 42 | // Convert seconds (in floating point format) to Time. 43 | static Time FloatSeconds(double s); 44 | 45 | // Converts seconds to Time. 46 | static Time Seconds(uint32_t s); 47 | 48 | // Converts minutes to Time. 49 | static Time Minutes(uint32_t m); 50 | 51 | // Converts hours to Time. 52 | static Time Hours(uint32_t h); 53 | 54 | // Converts days to Time. 55 | static Time Days(uint32_t d); 56 | 57 | // Converts weeks to Time. 58 | static Time Weeks(uint32_t w); 59 | 60 | // Returns the current time in milliseconds since the turn of the year 1900. 61 | static uint64_t Now( void ); 62 | 63 | // Returns the time of day in 0-23 hours, 0-59 minutes, 0-59 seconds (no milliseconds). 64 | static Time TimeOfDay( void ); 65 | 66 | // Returns the current year as an integer. 67 | static uint32_t CurrentYear( void ); 68 | 69 | // Returns the current week day as an integer 0-6. 70 | static uint32_t CurrentWeekDay( void ); 71 | 72 | // Returns the current month day as an integer 0-30. 73 | static uint32_t CurrentMonthDay( void ); 74 | 75 | // Returns the current year day as an integer 0-365. 76 | static uint32_t CurrentYearDay( void ); 77 | 78 | // Returns the current month as an integer 0-11. 79 | static uint32_t CurrentMonth( void ); 80 | 81 | // Returns the total amount of milliseconds. 82 | uint32_t GetTotalMS( void ) const; 83 | 84 | // Returns the total amount of seconds. 85 | uint32_t GetTotalSeconds( void ) const; 86 | 87 | // Returns the total amount of minutes. 88 | uint32_t GetTotalMinutes( void ) const; 89 | 90 | // Returns the total amount of hours. 91 | uint32_t GetTotalHours( void ) const; 92 | 93 | // Returns the total amount of days. 94 | uint32_t GetTotalDays( void ) const; 95 | 96 | // Returns the total amount of weeks. 97 | uint32_t GetTotalWeeks( void ) const; 98 | 99 | // Returns the part amount of milliseconds (0-999). 100 | uint32_t GetPartMS( void ) const; 101 | 102 | // Returns the part amount of seconds (0-59). 103 | uint32_t GetPartSeconds( void ) const; 104 | 105 | // Returns the part amount of minutes (0-59). 106 | uint32_t GetPartMinutes( void ) const; 107 | 108 | // Returns the part amount of hours (0-23). 109 | uint32_t GetPartHours( void ) const; 110 | 111 | // Returns the part amount of days (0-6). 112 | uint32_t GetPartDays( void ) const; 113 | 114 | // Returns the part amount of weeks (0-x). 115 | uint32_t GetPartWeeks( void ) const; 116 | 117 | // Returns the total amount of seconds as real numbers. 118 | double GetFloatSeconds( void ) const; 119 | 120 | // Same as GetFloatSeconds(), but less confusingly named when used for in RealTimeTimer and scaled times (which formally measures in "ticks" which correspond to seconds). 121 | double ToFloat( void ) const; 122 | 123 | // Returns status of internal bit representation of time (since there is no way to retrieve e.g. nanoseconds etc.). 124 | bool IsZero( void ) const; 125 | 126 | // Basic arithmetic. 127 | Time &operator+=(const Time &r); 128 | Time &operator-=(const Time &r); 129 | Time &operator*=(const Time &r); 130 | Time &operator/=(const Time &r); 131 | 132 | // Time comparisons. 133 | bool operator==(const Time &r) const; 134 | bool operator!=(const Time &r) const; 135 | bool operator<(const Time &r) const; 136 | bool operator>(const Time &r) const; 137 | bool operator<=(const Time &r) const; 138 | bool operator>=(const Time &r) const; 139 | }; 140 | 141 | } 142 | 143 | retro3d::Time operator+(retro3d::Time l, const retro3d::Time &r); 144 | retro3d::Time operator-(retro3d::Time l, const retro3d::Time &r); 145 | retro3d::Time operator*(retro3d::Time l, const retro3d::Time &r); 146 | retro3d::Time operator/(retro3d::Time l, const retro3d::Time &r); 147 | 148 | retro3d::Time operator "" _ms(unsigned long long int ms); 149 | retro3d::Time operator "" _s(unsigned long long int s); 150 | retro3d::Time operator "" _m(unsigned long long int m); 151 | retro3d::Time operator "" _h(unsigned long long int h); 152 | retro3d::Time operator "" _d(unsigned long long int d); 153 | retro3d::Time operator "" _w(unsigned long long int w); 154 | 155 | namespace retro3d 156 | { 157 | 158 | 159 | // A scaled timer that can be used to track time in other than seconds (called "ticks"). Updates as you look at the time. 160 | class RealTimeTimer 161 | { 162 | private: 163 | const RealTimeTimer *m_parent; 164 | retro3d::Time m_time_scale; 165 | retro3d::Time m_origin_time; 166 | retro3d::Time m_accum_ticks; 167 | bool m_ticking; 168 | 169 | private: 170 | // Returns the current time scale including parent time scales. 171 | retro3d::Time GetTimeScale( void ) const; 172 | 173 | // Returns the scaled time since last UpdateTimer. 174 | retro3d::Time TimeDelta( void ) const; 175 | 176 | public: 177 | // Constructs a timer with properties. Does not start it. 178 | RealTimeTimer(uint32_t num_ticks = 1, retro3d::Time over_time = 1_s); 179 | 180 | // Default 181 | RealTimeTimer(const RealTimeTimer&) = default; 182 | RealTimeTimer &operator=(const RealTimeTimer&) = default; 183 | 184 | // Updates the internal timer. The user only needs to call this manually immediately before a parent timer is changing time scale. 185 | retro3d::Time UpdateTimer( void ); 186 | 187 | // Changes the tick rate. Can be called while timer is ticking and only affect the time added to the clock *after* the call is made. 1 ms granularity. 188 | void SetTickRate(uint32_t num_ticks, retro3d::Time over_time = 1_s, bool accumulate_time = true); 189 | 190 | // Changes the tick rate based off of another timer's tick rate properties. 191 | void SetTickRate(const retro3d::RealTimeTimer &timer, bool accumulate_time = true); 192 | 193 | // Sets the time_scale directly. 194 | void SetTimeScale(retro3d::Time time_scale, bool accumulate_time = true); 195 | 196 | // Returns the current tick rate. 197 | retro3d::Time GetTimePerTick( void ) const; 198 | 199 | // Starts the timer. 200 | void Start( void ); 201 | 202 | // Stops the timer. Does not reset the time on the clock. 203 | void Pause( void ); 204 | 205 | // Toggles the timer on and off without resetting the time on the clock. 206 | void Toggle( void ); 207 | 208 | // Resets the time on the clock. 209 | void Reset( void ); 210 | 211 | // Resets the number of ticks elapsed. 212 | void ResetTicks( void ); 213 | 214 | // The status of the timer. 215 | bool IsTicking( void ) const; 216 | 217 | // The status of the timer. 218 | bool IsStopped( void ) const; 219 | 220 | // Returns true if a whole tick has elapsed since last Start or Reset* 221 | bool IsDue( void ) const; 222 | 223 | // Returns time scaled in relation to ticks. 224 | retro3d::Time GetScaledTime( void ) const; 225 | 226 | // Returns the time stamp since last update (UpdateTimer, SetTickRate, Start, Pause, Toggle, Reset, ResetTicks) scaled in relation to ticks. 227 | retro3d::Time GetScaledUpdateTime( void ) const; 228 | 229 | // Returns the number of ticks that have elapsed. Corresponds to the whole part of GetTime(). 230 | uint32_t GetTicks( void ) const; 231 | 232 | // Returns the progress 0-1 between last tick and next beat. Corresponds to the fractional part of GetTime(). 233 | double GetTickProgress( void ) const; 234 | 235 | // Add a timer parent to be used as a parent time scale. Can be called while timer is ticking and only affect the time added to the clock *after* the call is made. 236 | void SetParent(const RealTimeTimer *parent); 237 | 238 | // Creates a new timer with the current timer as parent. The user must decouple parent from child if parent is destroyed. 239 | RealTimeTimer SpawnChild(uint32_t num_ticks = 1, retro3d::Time over_time = 1_s) const; 240 | }; 241 | 242 | // Different types of timers used commonly in the engine. 243 | enum TimerType 244 | { 245 | TIMER_REAL, // Real time. 246 | TIMER_SIM, // Real time, but scaled if game does not hit minimum (frame) rate. 247 | TIMER_GAME // Scaled according to user needs. 248 | }; 249 | 250 | } 251 | 252 | #endif // RETRO_TIME_H 253 | --------------------------------------------------------------------------------