quintessence/AllegroFlare/Prototypes/MindDive/TunnelRenderer.q.yml
@@ -12678,6 +12905,7 @@
Dependents
],
"al_is_acodec_addon_initialized": [
"AllegroFlare/AudioController",
+ "AllegroFlare/Prototypes/MindDive/Hypersync",
"AllegroFlare/Prototypes/MindDive/MindDive"
],
"AllegroFlare/BitmapBin": [
@@ -13255,6 +13483,7 @@
Dependents
"AllegroFlare/Elements/Storyboard",
"AllegroFlare/Elements/StoryboardPages/AdvancingText",
"AllegroFlare/Elements/StoryboardPages/Image",
+ "AllegroFlare/Prototypes/MindDive/Hypersync",
"AllegroFlare/SoftwareKeyboard/SoftwareKeyboard"
],
"AllegroFlare/Elements/Backgrounds/Base": [
@@ -13568,6 +13797,7 @@
Dependents
"AllegroFlare/Elements/Stopwatch",
"AllegroFlare/Elements/Stopwatch",
"AllegroFlare/Prototypes/MindDive/Hud/Hud",
+ "AllegroFlare/Prototypes/MindDive/Hypersync",
"AllegroFlare/Prototypes/MindDive/MindDive"
],
"AllegroFlare/Elements/StoryboardPages/Base": [
@@ -13717,6 +13947,7 @@
Dependents
"nlohmann/json": [
"AllegroFlare/MotionComposer/MessageFactory",
"AllegroFlare/MotionComposer/MessageProcessor",
+ "AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader",
"Tileo/TMJDataLoader",
"Tileo/TMJMeshLoader"
],
@@ -14008,6 +14239,18 @@
Dependents
"AllegroFlare/Camera2D": [
"AllegroFlare/Prototypes/MindDive/Hud/Hud"
],
+ "ALLEGRO_EVENT_QUEUE": [
+ "AllegroFlare/Prototypes/MindDive/Hypersync"
+ ],
+ "ALLEGRO_AUDIO_STREAM": [
+ "AllegroFlare/Prototypes/MindDive/Hypersync"
+ ],
+ "ALLEGRO_VOICE": [
+ "AllegroFlare/Prototypes/MindDive/Hypersync"
+ ],
+ "ALLEGRO_MIXER": [
+ "AllegroFlare/Prototypes/MindDive/Hypersync"
+ ],
"al_is_audio_installed": [
"AllegroFlare/Prototypes/MindDive/MindDive"
],
@@ -14069,9 +14312,20 @@
Dependents
"WickedDemos/TileDemo",
"WickedDemos/TileMaps/Basic2D"
],
+ "AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader": [
+ "AllegroFlare/Prototypes/MindDive/TunnelMeshFactory"
+ ],
"AllegroFlare/Physics/TileMapCollisionStepper": [
"AllegroFlare/Prototypes/MindDive/TunnelMeshSurferCollisionResolver"
],
+ "std/ifstream": [
+ "AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader",
+ "Tileo/TMJDataLoader"
+ ],
+ "std/filesystem/exists": [
+ "AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader",
+ "Tileo/TMJDataLoader"
+ ],
"AllegroFlare/Achievements": [
"AllegroFlare/Screens/Achievements",
"AllegroFlare/Screens/Achievements"
@@ -14251,12 +14505,6 @@
Dependents
"Tileo/Shaders/AllegroDefault",
"Tileo/Shaders/MeshWithNormals"
],
- "std/ifstream": [
- "Tileo/TMJDataLoader"
- ],
- "std/filesystem/exists": [
- "Tileo/TMJDataLoader"
- ],
"ifstream": [
"Tileo/TMJMeshLoader"
],
diff --git a/include/AllegroFlare/Prototypes/MindDive/Hypersync.hpp b/include/AllegroFlare/Prototypes/MindDive/Hypersync.hpp
new file mode 100644
index 000000000..14872040c
--- /dev/null
+++ b/include/AllegroFlare/Prototypes/MindDive/Hypersync.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+
+#include
+#include
+#include
+#include
+
+
+namespace AllegroFlare
+{
+ namespace Prototypes
+ {
+ namespace MindDive
+ {
+ class Hypersync
+ {
+ private:
+ ALLEGRO_EVENT_QUEUE* event_queue;
+ AllegroFlare::Timer timer;
+ ALLEGRO_AUDIO_STREAM* audio_stream;
+ ALLEGRO_VOICE* audio_voice;
+ ALLEGRO_MIXER* audio_mixer;
+ bool initialized;
+ bool stream_is_attached;
+ std::string song_filename;
+ float song_bpm;
+ float latency_sec;
+
+ protected:
+
+
+ public:
+ Hypersync(ALLEGRO_EVENT_QUEUE* event_queue=nullptr);
+ ~Hypersync();
+
+ ALLEGRO_EVENT_QUEUE* get_event_queue() const;
+ void TODO();
+ void set_event_queue(ALLEGRO_EVENT_QUEUE* event_queue=nullptr);
+ float get_timer_seconds();
+ float get_timer_milliseconds();
+ float get_timer_microseconds();
+ int get_beat_num(float seconds=0.0f);
+ int get_measure_num(float seconds=0.0f);
+ std::string build_beat_clock_str();
+ void start();
+ void initialize();
+ void destruct();
+ };
+ }
+ }
+}
+
+
+
diff --git a/include/AllegroFlare/Prototypes/MindDive/MindDive.hpp b/include/AllegroFlare/Prototypes/MindDive/MindDive.hpp
index b98583132..e55d3d210 100644
--- a/include/AllegroFlare/Prototypes/MindDive/MindDive.hpp
+++ b/include/AllegroFlare/Prototypes/MindDive/MindDive.hpp
@@ -35,15 +35,21 @@ namespace AllegroFlare
AllegroFlare::SampleBin* sample_bin;
AllegroFlare::Prototypes::MindDive::TunnelMesh* current_tunnel_mesh;
AllegroFlare::Sound* current_music_track;
+ float current_music_track_bpm;
AllegroFlare::Vec3D surfer_position;
AllegroFlare::Vec3D surfer_velocity;
AllegroFlare::Timer timer;
AllegroFlare::Camera3D camera;
AllegroFlare::Prototypes::MindDive::Hud::Hud hud;
int state;
+ bool surfer_attached_to_playhead;
bool initialized;
+ AllegroFlare::Sound* debug_metronome_sound;
+ float music_started_at;
void start_timer();
void reset_timer();
+ float calculate_current_tunnel_mesh_height();
+ float calculate_current_tunnel_mesh_tile_depth();
void evaluate_surfer_past_goal();
protected:
@@ -67,6 +73,7 @@ namespace AllegroFlare
void pause_timer();
void reset();
void start_racing();
+ void attach_surfer_to_playhead();
void stop_racing_due_to_death();
void surfer_move_right();
void surfer_move_left();
diff --git a/include/AllegroFlare/Prototypes/MindDive/TunnelMesh.hpp b/include/AllegroFlare/Prototypes/MindDive/TunnelMesh.hpp
index e0e6eadb4..f061180b2 100644
--- a/include/AllegroFlare/Prototypes/MindDive/TunnelMesh.hpp
+++ b/include/AllegroFlare/Prototypes/MindDive/TunnelMesh.hpp
@@ -49,6 +49,8 @@ namespace AllegroFlare
float infer_real_height();
float obtain_tile_width();
float obtain_tile_height();
+ float obtain_num_rows();
+ float obtain_num_columns();
void render();
void random_fill();
};
diff --git a/include/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.hpp b/include/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.hpp
index ce97f8e14..6a389440a 100644
--- a/include/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.hpp
+++ b/include/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.hpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include
#include
@@ -30,6 +31,7 @@ namespace AllegroFlare
AllegroFlare::BitmapBin* get_bitmap_bin() const;
AllegroFlare::Prototypes::MindDive::TunnelMesh* create_classic_random();
AllegroFlare::Prototypes::MindDive::TunnelMesh* create_random_with_walls();
+ AllegroFlare::Prototypes::MindDive::TunnelMesh* create_from_tmj(std::string tmj_filename="unset-tmj_filename.tmj");
void random_fill_from(AllegroFlare::Prototypes::MindDive::TunnelMesh* tunnel_mesh=nullptr, std::vector> inclusion_list={});
void random_sparce_placement(AllegroFlare::Prototypes::MindDive::TunnelMesh* tunnel_mesh=nullptr, std::vector> inclusion_list={}, int one_in_chance=2);
void random_fill_excluding(AllegroFlare::Prototypes::MindDive::TunnelMesh* tunnel_mesh=nullptr, std::set exclusion_list={});
diff --git a/include/AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader.hpp b/include/AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader.hpp
new file mode 100644
index 000000000..f864e8c3f
--- /dev/null
+++ b/include/AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+
+#include
+#include
+
+
+namespace AllegroFlare
+{
+ namespace Prototypes
+ {
+ namespace MindDive
+ {
+ class TunnelMeshTMJDataLoader
+ {
+ private:
+ std::string filename;
+ int num_columns;
+ int num_rows;
+ int tile_width;
+ int tile_height;
+ int layer_num_columns;
+ int layer_num_rows;
+ std::vector layer_tile_data;
+ bool loaded;
+ static bool file_exists(std::string filename="[unset-filename]");
+
+ protected:
+
+
+ public:
+ TunnelMeshTMJDataLoader(std::string filename="filename-not-set.tmj");
+ ~TunnelMeshTMJDataLoader();
+
+ bool get_loaded() const;
+ int get_num_columns();
+ int get_num_rows();
+ int get_tile_width();
+ int get_tile_height();
+ int get_layer_num_columns();
+ int get_layer_num_rows();
+ std::vector get_layer_tile_data();
+ bool load();
+ };
+ }
+ }
+}
+
+
+
diff --git a/quintessence/AllegroFlare/Prototypes/MindDive/Hypersync.q.yml b/quintessence/AllegroFlare/Prototypes/MindDive/Hypersync.q.yml
new file mode 100644
index 000000000..4db6cba34
--- /dev/null
+++ b/quintessence/AllegroFlare/Prototypes/MindDive/Hypersync.q.yml
@@ -0,0 +1,213 @@
+properties:
+
+
+ - name: event_queue
+ type: ALLEGRO_EVENT_QUEUE*
+ init_with: nullptr
+ constructor_arg: true
+ getter: true
+ setter: false
+
+ - name: timer
+ type: AllegroFlare::Timer
+ init_with: '{}'
+
+ - name: audio_stream
+ type: ALLEGRO_AUDIO_STREAM*
+ init_with: nullptr
+
+ - name: audio_voice
+ type: ALLEGRO_VOICE*
+ init_with: nullptr
+
+ - name: audio_mixer
+ type: ALLEGRO_MIXER*
+ init_with: nullptr
+
+ - name: initialized
+ type: bool
+ init_with: false
+
+ - name: stream_is_attached
+ type: bool
+ init_with: false
+
+ - name: song_filename
+ type: std::string
+ init_with: '"/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/some-jamzz-04.ogg"'
+
+ - name: song_bpm
+ type: float
+ init_with: 130.0f
+
+ - name: latency_sec
+ type: float
+ init_with: 0.140f
+
+
+functions:
+
+
+ - name: TODO
+ body: |
+ // TODO: investigate calculating the amount of latency needed.
+ // - you might consume stream filling events, size of buffer, etc.
+ return;
+
+
+ - name: set_event_queue
+ parameters:
+ - name: event_queue
+ type: ALLEGRO_EVENT_QUEUE*
+ default_argument: nullptr
+ guards: [ initialized ]
+ body: |
+ this->event_queue = event_queue;
+ return;
+
+
+ - name: get_timer_seconds
+ type: float
+ body: |
+ return get_timer_microseconds() * 0.000001f;
+
+
+ - name: get_timer_milliseconds
+ type: float
+ body: |
+ return get_timer_microseconds() * 0.001f;
+
+
+ - name: get_timer_microseconds
+ type: float
+ body: |
+ float time_with_latency = timer.get_elapsed_time_microseconds() - (latency_sec * 1000000);
+ if (time_with_latency < 0) return 0;
+ return time_with_latency;
+
+
+ - name: get_beat_num
+ type: int
+ parameters:
+ - name: seconds
+ type: float
+ default_argument: 0.0f
+ body: |
+ float beat = (seconds * (song_bpm / 60.0));
+ return ((int)beat) % 4 + 1;
+
+
+ - name: get_measure_num
+ type: int
+ parameters:
+ - name: seconds
+ type: float
+ default_argument: 0.0f
+ body: |
+ float beat = (seconds * (song_bpm / 60.0));
+ return ((int)beat) / 4;
+
+
+ - name: build_beat_clock_str
+ type: std::string
+ body: |
+ float seconds = get_timer_seconds();
+ std::stringstream result;
+ result << get_measure_num(seconds) << ":" << get_beat_num(seconds);
+ return result.str();
+
+
+ - name: start
+ body: |
+ if (!stream_is_attached)
+ {
+ al_register_event_source(event_queue, al_get_audio_stream_event_source(audio_stream));
+ if (!al_attach_audio_stream_to_mixer(audio_stream, audio_mixer))
+ {
+ throw std::runtime_error("boobaz");
+ }
+ timer.start();
+ }
+
+ return;
+
+
+ - name: initialize
+ guards:
+ - (!initialized)
+ - al_is_audio_installed()
+ - al_is_acodec_addon_initialized()
+ - event_queue
+ body: |
+ audio_voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2);
+ if (!audio_voice) throw std::runtime_error("could not create voice!!");
+
+ audio_mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
+ if (!al_attach_mixer_to_voice(audio_mixer, audio_voice))
+ {
+ throw std::runtime_error("could not attach mixer to voice");
+ }
+
+ song_filename = "/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/some-jamzz-04.ogg";
+ song_bpm = 130.0f;
+
+ //song_filename = "/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/tempo-track-180.ogg";
+ //song_bpm = 180.0f;
+
+ //song_filename = "/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/tempo-track-152.ogg";
+ //song_bpm = 152.0f;
+
+ audio_stream = al_load_audio_stream(song_filename.c_str(), 4, 2048);
+ if (!audio_stream) throw std::runtime_error("could not load stream!!");
+
+ al_set_audio_stream_playmode(audio_stream, ALLEGRO_PLAYMODE_ONCE);
+
+ initialized = true;
+ return;
+ body_dependency_symbols:
+ - al_is_acodec_addon_initialized
+ - std::cout
+
+
+ - name: destruct
+ body: |
+ if (audio_mixer)
+ {
+ if (stream_is_attached)
+ {
+ // TODO: sort out this destruction
+ al_detach_voice(audio_voice);
+ al_destroy_mixer(audio_mixer);
+ }
+ }
+ if (audio_voice)
+ {
+ al_destroy_voice(audio_voice);
+ }
+ if (audio_stream)
+ {
+ al_unregister_event_source(event_queue, al_get_audio_stream_event_source(audio_stream));
+ al_destroy_audio_stream(audio_stream);
+ }
+ return;
+
+
+dependencies:
+
+
+ - symbol: ALLEGRO_EVENT_QUEUE
+ headers: [ allegro5/allegro.h ]
+ - symbol: ALLEGRO_AUDIO_STREAM
+ headers: [ allegro5/allegro_audio.h ]
+ - symbol: ALLEGRO_VOICE
+ headers: [ allegro5/allegro_audio.h ]
+ - symbol: ALLEGRO_MIXER
+ headers: [ allegro5/allegro_audio.h ]
+ - symbol: al_is_acodec_addon_initialized
+ headers: [ allegro5/allegro_acodec.h ]
+ - symbol: AllegroFlare::Timer
+ headers: [ AllegroFlare/Timer.hpp ]
+ - symbol: fmod
+ headers: [ cmath ]
+
+
diff --git a/quintessence/AllegroFlare/Prototypes/MindDive/MindDive.q.yml b/quintessence/AllegroFlare/Prototypes/MindDive/MindDive.q.yml
index b2f219eb2..0065b55d3 100644
--- a/quintessence/AllegroFlare/Prototypes/MindDive/MindDive.q.yml
+++ b/quintessence/AllegroFlare/Prototypes/MindDive/MindDive.q.yml
@@ -38,6 +38,10 @@ properties:
type: AllegroFlare::Sound*
init_with: nullptr
+ - name: current_music_track_bpm
+ type: float
+ init_with: 130.0f
+
- name: surfer_position
type: AllegroFlare::Vec3D
init_with: '{0, 0, 0}'
@@ -62,6 +66,10 @@ properties:
type: int
init_with: STATE_WAITING_START
+ - name: surfer_attached_to_playhead
+ type: bool
+ init_with: false
+
- name: initialized
type: bool
init_with: false
@@ -90,6 +98,14 @@ properties:
static: true
init_with: 4
+ - name: debug_metronome_sound
+ type: AllegroFlare::Sound*
+ init_with: nullptr
+
+ - name: music_started_at
+ type: float
+ init_with: 0.0f
+
functions:
@@ -146,8 +162,33 @@ functions:
body: |
AllegroFlare::Prototypes::MindDive::TunnelMeshFactory factory(bitmap_bin);
//current_tunnel_mesh = factory.create_classic_random();
- current_tunnel_mesh = factory.create_random_with_walls();
- current_music_track = new AllegroFlare::Sound(sample_bin->auto_get("music_tracks/some-jamzz-04.ogg"));
+ //current_tunnel_mesh = factory.create_random_with_walls();
+ std::string map_filename = "/Users/markoates/Repos/allegro_flare/bin/data/maps/tunnel_mesh-02.tmj";
+ current_tunnel_mesh = factory.create_from_tmj(map_filename);
+
+ //current_music_track_identifier = "music_tracks/some-jamzz-04.ogg";
+ //std::string current_music_track_identifier = "music_tracks/tempo-track-152.ogg";
+ //current_music_track_bpm = 152;
+ //current_music_track_bpm = 152;
+
+ std::map> playlist = {
+ { "song-60bpm", { "music_tracks/tempo-track-60.ogg", 60.0f } },
+ { "song-80bpm", { "music_tracks/tempo-track-80.ogg", 80.0f } },
+ { "song-120bpm", { "music_tracks/tempo-track-120.ogg", 120.0f } },
+ { "song-152bpm", { "music_tracks/tempo-track-152.ogg", 152.0f } },
+ { "original-jamzz", { "music_tracks/some-jamzz-04.ogg", 130.0f } },
+ };
+
+ //std::string playlist_song_to_play = "song-152bpm";
+ //std::string playlist_song_to_play = "song-80bpm";
+ //std::string playlist_song_to_play = "song-120bpm";
+ std::string playlist_song_to_play = "original-jamzz";
+
+ std::string current_music_track_identifier = playlist[playlist_song_to_play].first;
+ current_music_track_bpm = playlist[playlist_song_to_play].second;
+ current_music_track = new AllegroFlare::Sound(sample_bin->auto_get(current_music_track_identifier));
+
+ debug_metronome_sound = new AllegroFlare::Sound(sample_bin->auto_get("metronome-01.ogg"));
hud.set_font_bin(font_bin);
hud.set_timer(&timer);
@@ -156,6 +197,7 @@ functions:
initialized = true;
return;
body_dependency_symbols:
+ - std::map
- al_is_audio_installed
- al_is_acodec_addon_initialized
- AllegroFlare::Prototypes::MindDive::TunnelMeshFactory
@@ -181,13 +223,29 @@ functions:
return;
+ - name: calculate_current_tunnel_mesh_height
+ type: float
+ private: true
+ body: |
+ if (!current_tunnel_mesh) return 0.0f;
+ return current_tunnel_mesh->infer_real_height();
+
+
+ - name: calculate_current_tunnel_mesh_tile_depth
+ type: float
+ private: true
+ body: |
+ if (!current_tunnel_mesh) return 0.0f;
+ return current_tunnel_mesh->obtain_tile_height();
+
+
- name: reset
guards: [ initialized ]
body: |
surfer_position.x = current_tunnel_mesh->infer_real_width() * 0.5
- current_tunnel_mesh->obtain_tile_width() * 0.5;
surfer_position.z = current_tunnel_mesh->infer_real_height()
- - current_tunnel_mesh->obtain_tile_height() * 0.5;
+ - current_tunnel_mesh->obtain_tile_height();
surfer_velocity = AllegroFlare::Vec3D(0, 0, 0);
@@ -198,8 +256,9 @@ functions:
//camera.tilt = 0.4;
//camera.zoom = 2.1;
//camera.spin += 0.01f;
+ music_started_at = 0.0f;
- event_emitter->emit_play_music_track_event("[unset-music-track-identifier]");
+ //event_emitter->emit_play_music_track_event("[unset-music-track-identifier]");
if (current_music_track) current_music_track->stop();
reset_timer();
return;
@@ -209,12 +268,23 @@ functions:
body: |
if (state != STATE_WAITING_START) return;
state = STATE_RACING;
- if (current_music_track) current_music_track->play();
+ if (current_music_track)
+ {
+ attach_surfer_to_playhead();
+ current_music_track->play();
+ music_started_at = al_get_time();
+ }
start_timer();
hud.clear_slate();
return;
+ - name: attach_surfer_to_playhead
+ body: |
+ surfer_attached_to_playhead = true;
+ return;
+
+
- name: stop_racing_due_to_death
body: |
if (state == STATE_DEAD) return;
@@ -315,14 +385,69 @@ functions:
- name: update
guards: [ initialized ]
body: |
- AllegroFlare::Prototypes::MindDive::TunnelMeshSurferCollisionResolver collision_resolver(
- current_tunnel_mesh,
- &surfer_position,
- &surfer_velocity
- );
- AllegroFlare::Physics::TileMapCollisionStepperStepResult step_result = collision_resolver.resolve();
+ float time_now = al_get_time();
+ static float previous_surfer_position_z = surfer_position.z;
+ float surfer_next_position_z = 0;//previous_surfer_position_z;
- play_around_with_collision_step_result(&step_result);
+ if (surfer_attached_to_playhead)
+ {
+ //float explicit_playhead_position = time_now - music_started_at;
+ float explicit_playhead_position = (float) timer.get_elapsed_time_microseconds() / 1000000;
+
+ // update the surfer playhead position
+ float song_bpm = current_music_track_bpm;
+ //float song_bpm = 120.0;
+ static const float SECONDS_PER_MINUTE = 60.0f;
+ //static const int TILES_PER_BEAT = 4;
+ static const float TILES_PER_BEAT = 1;
+ float time_multiplier = song_bpm / SECONDS_PER_MINUTE;
+ //float time_multiplier = SECONDS_PER_MINUTE / song_bpm;
+ float playhead_tile_position = calculate_current_tunnel_mesh_tile_depth()
+ * TILES_PER_BEAT
+ * explicit_playhead_position
+ * time_multiplier
+ - 0.05; // some weird sync offset needs this for some reason
+ ;
+
+
+
+ //* infer_playhead_position_sec();
+ //* time_multiplier;
+
+ //surfer_position.z = calculate_current_tunnel_mesh_height() - playhead_tile_position;
+ //surfer_next_position_z = playhead_tile_position; //calculate_current_tunnel_mesh_height() - playhead_tile_position;
+ //surfer_next_position_z = (calculate_current_tunnel_mesh_height() + current_tunnel_mesh->obtain_tile_height())
+ //- playhead_tile_position;
+ surfer_position.z = calculate_current_tunnel_mesh_height() - playhead_tile_position;
+ //surfer_velocity.z = previous_surfer_position_z - surfer_position.z; //-1.0f;
+
+ int tile_y = (int)surfer_position.z;
+ int tile_x = (int)surfer_position.x;
+
+ current_tunnel_mesh->get_prim_mesh_ref().set_tile_id(tile_x, tile_y, 4);
+
+
+
+ //surfer_next_position_z = (calculate_current_tunnel_mesh_height() + current_tunnel_mesh->obtain_tile_height());
+ //surfer_velocity.z = -surfer_position.z - previous_surfer_position_z; //-1.0f;
+
+ // this is implicit, and only used for the collision resolver to calculate
+ // collisions. It should be set constant to the rate of the music track playing
+ }
+ else
+ {
+ AllegroFlare::Prototypes::MindDive::TunnelMeshSurferCollisionResolver collision_resolver(
+ current_tunnel_mesh,
+ &surfer_position,
+ &surfer_velocity
+ );
+ AllegroFlare::Physics::TileMapCollisionStepperStepResult step_result = collision_resolver.resolve();
+
+ //surfer_position.z = calculate_current_tunnel_mesh_height() - playhead_tile_position;
+
+ play_around_with_collision_step_result(&step_result);
+ //surfer_position.z = surfer_next_position_z;
+ }
camera.position = surfer_position;
@@ -340,6 +465,12 @@ functions:
default_argument: nullptr
guards: [ step_result, current_tunnel_mesh ]
body: |
+ if (step_result->get_collisions_ref().empty()) return;
+
+ //event_emitter->emit_play_sound_effect_event("menu-click-01.ogg");
+ //debug_metronome_sound->stop();
+ //debug_metronome_sound->play();
+
for (auto &collision : step_result->get_collisions_ref())
{
// stop racing due do death
@@ -352,12 +483,12 @@ functions:
else if (collision.get_tile_value() == 2)
{
// this is cool just disabled
- bool disable_this_feature = true;
+ bool disable_this_feature = false;
if (!disable_this_feature)
{
AllegroFlare::Physics::Int2D tile_pos = collision.get_collided_tile_coordinate();
current_tunnel_mesh->get_prim_mesh_ref().set_tile_id(tile_pos.get_x(), tile_pos.get_y(), 3);
- current_tunnel_mesh->get_collision_tile_map_ref().set_tile(tile_pos.get_x(), tile_pos.get_y(), 0);
+ //current_tunnel_mesh->get_collision_tile_map_ref().set_tile(tile_pos.get_x(), tile_pos.get_y(), 0);
}
}
}
diff --git a/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMesh.q.yml b/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMesh.q.yml
index 7f9e4c9f4..27d763576 100644
--- a/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMesh.q.yml
+++ b/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMesh.q.yml
@@ -146,6 +146,18 @@ functions:
return prim_mesh.get_tile_height();
+ - name: obtain_num_rows
+ type: float
+ body: |
+ return prim_mesh.get_num_rows();
+
+
+ - name: obtain_num_columns
+ type: float
+ body: |
+ return prim_mesh.get_num_columns();
+
+
- name: render
guards: [ initialized ]
body: |
diff --git a/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.q.yml b/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.q.yml
index 600cb6023..bb42e7e14 100644
--- a/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.q.yml
+++ b/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMeshFactory.q.yml
@@ -34,14 +34,63 @@ functions:
result->set_bitmap_bin(bitmap_bin);
result->set_atlas_configuration("uv-with-decorations-0x.png", 50, 50);
result->initialize();
- result->rescale_tile_dimentions_to(2, 6);
- result->resize(12, 32);
+ //result->rescale_tile_dimentions_to(2, 6);
+ result->rescale_tile_dimentions_to(1, 1);
+ result->resize(12, 32 * 2);
random_fill_from(result, { { 2, 2 } });
random_sparce_placement(result, { { 0, 0 } }, 20);
random_sparce_placement(result, { { 1, 1 } }, 40);
return result;
+ - name: create_from_tmj
+ type: AllegroFlare::Prototypes::MindDive::TunnelMesh*
+ guards: [ bitmap_bin ]
+ parameters:
+ - name: tmj_filename
+ type: std::string
+ default_argument: '"unset-tmj_filename.tmj"'
+ body: |
+ AllegroFlare::Prototypes::MindDive::TunnelMeshTMJDataLoader tmj_data_loader(tmj_filename);
+ tmj_data_loader.load();
+
+ int num_columns = tmj_data_loader.get_num_columns();
+ if (num_columns != 12)
+ {
+ std::stringstream error_message;
+ error_message << "AllegroFlare::Prototypes::MindDive::TunnelMeshFactory error: "
+ << "Expecting data loaded from \"" << tmj_filename << "\" to have a column count of "
+ << "\"12\", but it is \"" << num_columns << "\"";
+ throw std::runtime_error(error_message.str());
+ }
+
+ AllegroFlare::Prototypes::MindDive::TunnelMesh *result = new AllegroFlare::Prototypes::MindDive::TunnelMesh;
+ result->set_bitmap_bin(bitmap_bin);
+ result->set_atlas_configuration("uv-with-decorations-0x.png", 50, 50);
+ result->initialize();
+
+ // resize the mesh and fill with data
+ AllegroFlare::TileMaps::PrimMesh &prim_mesh = result->get_prim_mesh_ref();
+ AllegroFlare::TileMaps::TileMap &collision_tile_map = result->get_collision_tile_map_ref();
+ result->resize(num_columns, tmj_data_loader.get_num_rows());
+ int tile_count = 0;
+ for (auto &tile : tmj_data_loader.get_layer_tile_data())
+ {
+ int tile_x = tile_count % num_columns;
+ int tile_y = tile_count / num_columns;
+ int tile_value = tile - 1; // offset by one, Tiled likes to index the first tile as 1, rather than 0
+
+ prim_mesh.set_tile_id(tile_x, tile_y, tile_value);
+ collision_tile_map.set_tile(tile_x, tile_y, tile_value);
+
+ tile_count++;
+ }
+
+ return result;
+ body_dependency_symbols:
+ - AllegroFlare::Prototypes::MindDive::TunnelMeshTMJDataLoader
+
+
- name: random_fill_from
parameters:
- name: tunnel_mesh
@@ -147,5 +196,7 @@ dependencies:
headers: [ AllegroFlare/Prototypes/MindDive/TunnelMesh.hpp ]
- symbol: AllegroFlare::Random
headers: [ AllegroFlare/Random.hpp ]
+ - symbol: AllegroFlare::Prototypes::MindDive::TunnelMeshTMJDataLoader
+ headers: [ AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader.hpp ]
diff --git a/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader.q.yml b/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader.q.yml
new file mode 100644
index 000000000..cb370a92b
--- /dev/null
+++ b/quintessence/AllegroFlare/Prototypes/MindDive/TunnelMeshTMJDataLoader.q.yml
@@ -0,0 +1,182 @@
+properties:
+
+
+ - name: filename
+ type: std::string
+ init_with: '"filename-not-set.tmj"'
+ constructor_arg: true
+
+ - name: num_columns
+ type: int
+ init_with: 0
+ getter: explicit
+
+ - name: num_rows
+ type: int
+ init_with: 0
+ getter: explicit
+
+ - name: tile_width
+ type: int
+ init_with: 0
+ getter: explicit
+
+ - name: tile_height
+ type: int
+ init_with: 0
+ getter: explicit
+
+ - name: layer_num_columns
+ type: int
+ init_with: 0
+ getter: explicit
+
+ - name: layer_num_rows
+ type: int
+ init_with: 0
+ getter: explicit
+
+ - name: layer_tile_data
+ type: std::vector
+ init_with: '{}'
+ getter: explicit
+
+ - name: loaded
+ type: bool
+ init_with: false
+ getter: true
+
+
+functions:
+
+
+ - name: get_num_columns
+ type: int
+ guards: [ loaded ]
+ body: return num_columns;
+
+
+ - name: get_num_rows
+ type: int
+ guards: [ loaded ]
+ body: return num_rows;
+
+
+ - name: get_tile_width
+ type: int
+ guards: [ loaded ]
+ body: return tile_width;
+
+
+ - name: get_tile_height
+ type: int
+ guards: [ loaded ]
+ body: return tile_height;
+
+
+ - name: get_layer_num_columns
+ type: int
+ guards: [ loaded ]
+ body: return layer_num_columns;
+
+
+ - name: get_layer_num_rows
+ type: int
+ guards: [ loaded ]
+ body: return layer_num_rows;
+
+
+ - name: get_layer_tile_data
+ type: std::vector
+ guards: [ loaded ]
+ body: return layer_tile_data;
+
+
+ - name: load
+ type: bool
+ guards: [ (!loaded) ]
+ body: |
+ if (!file_exists(filename))
+ {
+ std::stringstream error_message;
+ error_message << "[MindDive::TunnelMeshTMJDataLoader] load() error: the file \""
+ << filename << "\" does not exist.";
+ throw std::runtime_error(error_message.str());
+ }
+
+ // load and validate the json data to variables
+ std::ifstream i(filename);
+ nlohmann::json j;
+ try
+ {
+ i >> j;
+ }
+ catch (const std::exception& e)
+ {
+ i.close();
+ std::stringstream error_message;
+ error_message << "[MindDive::TunnelMeshTMJDataLoader] load() error: the file \""
+ << filename << "\" appears to have"
+ << " malformed JSON. The following error was thrown by nlohmann::json: \""
+ << e.what() << "\"";
+ throw std::runtime_error(error_message.str());
+ }
+
+ num_columns = j["width"]; // get width
+ num_rows = j["height"]; // get height
+ tile_width = j["tilewidth"]; // get width
+ tile_height = j["tileheight"]; // get height
+
+ // get first j["layers"] that is a ["type"] == "tilelayer"
+ bool tilelayer_type_found = false;
+ nlohmann::json tilelayer;
+ for (auto &layer : j["layers"].items())
+ {
+ if (layer.value()["type"] == "tilelayer" && layer.value()["name"] != "collision")
+ {
+ tilelayer = layer.value();
+ tilelayer_type_found = true;
+ break;
+ }
+ }
+ if (!tilelayer_type_found) throw std::runtime_error("TMJMeshLoader: error: tilelayer type not found.");
+
+ layer_num_columns = tilelayer["width"];
+ layer_num_rows = tilelayer["height"];
+ layer_tile_data = tilelayer["data"].get>();
+
+ loaded = true;
+
+ i.close();
+
+ return true;
+ body_dependency_symbols:
+ - std::stringstream
+ - nlohmann::json
+ - std::ifstream
+
+
+ - name: file_exists
+ type: bool
+ static: true
+ private: true
+ parameters:
+ - name: filename
+ type: std::string
+ default_argument: '"[unset-filename]"'
+ body: |
+ return std::filesystem::exists(filename);
+ body_dependency_symbols:
+ - std::filesystem::exists
+
+
+dependencies:
+
+
+ - symbol: std::ifstream
+ headers: [ fstream ]
+ - symbol: nlohmann::json
+ headers: [ lib/nlohmann/json.hpp ]
+ - symbol: std::filesystem::exists
+ headers: [ filesystem ]
+
diff --git a/src/AllegroFlare/Prototypes/MindDive/Hypersync.cpp b/src/AllegroFlare/Prototypes/MindDive/Hypersync.cpp
new file mode 100644
index 000000000..7ebc1a4be
--- /dev/null
+++ b/src/AllegroFlare/Prototypes/MindDive/Hypersync.cpp
@@ -0,0 +1,197 @@
+
+
+#include
+
+#include
+#include
+#include
+#include
+
+
+namespace AllegroFlare
+{
+namespace Prototypes
+{
+namespace MindDive
+{
+
+
+Hypersync::Hypersync(ALLEGRO_EVENT_QUEUE* event_queue)
+ : event_queue(event_queue)
+ , timer({})
+ , audio_stream(nullptr)
+ , audio_voice(nullptr)
+ , audio_mixer(nullptr)
+ , initialized(false)
+ , stream_is_attached(false)
+ , song_filename("/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/some-jamzz-04.ogg")
+ , song_bpm(130.0f)
+ , latency_sec(0.140f)
+{
+}
+
+
+Hypersync::~Hypersync()
+{
+}
+
+
+ALLEGRO_EVENT_QUEUE* Hypersync::get_event_queue() const
+{
+ return event_queue;
+}
+
+
+void Hypersync::TODO()
+{
+ // TODO: investigate calculating the amount of latency needed.
+ // - you might consume stream filling events, size of buffer, etc.
+ return;
+}
+
+void Hypersync::set_event_queue(ALLEGRO_EVENT_QUEUE* event_queue)
+{
+ if (!(initialized))
+ {
+ std::stringstream error_message;
+ error_message << "Hypersync" << "::" << "set_event_queue" << ": error: " << "guard \"initialized\" not met";
+ throw std::runtime_error(error_message.str());
+ }
+ this->event_queue = event_queue;
+ return;
+}
+
+float Hypersync::get_timer_seconds()
+{
+ return get_timer_microseconds() * 0.000001f;
+}
+
+float Hypersync::get_timer_milliseconds()
+{
+ return get_timer_microseconds() * 0.001f;
+}
+
+float Hypersync::get_timer_microseconds()
+{
+ float time_with_latency = timer.get_elapsed_time_microseconds() - (latency_sec * 1000000);
+ if (time_with_latency < 0) return 0;
+ return time_with_latency;
+}
+
+int Hypersync::get_beat_num(float seconds)
+{
+ float beat = (seconds * (song_bpm / 60.0));
+ return ((int)beat) % 4 + 1;
+}
+
+int Hypersync::get_measure_num(float seconds)
+{
+ float beat = (seconds * (song_bpm / 60.0));
+ return ((int)beat) / 4;
+}
+
+std::string Hypersync::build_beat_clock_str()
+{
+ float seconds = get_timer_seconds();
+ std::stringstream result;
+ result << get_measure_num(seconds) << ":" << get_beat_num(seconds);
+ return result.str();
+}
+
+void Hypersync::start()
+{
+ if (!stream_is_attached)
+ {
+ al_register_event_source(event_queue, al_get_audio_stream_event_source(audio_stream));
+ if (!al_attach_audio_stream_to_mixer(audio_stream, audio_mixer))
+ {
+ throw std::runtime_error("boobaz");
+ }
+ timer.start();
+ }
+
+ return;
+}
+
+void Hypersync::initialize()
+{
+ if (!((!initialized)))
+ {
+ std::stringstream error_message;
+ error_message << "Hypersync" << "::" << "initialize" << ": error: " << "guard \"(!initialized)\" not met";
+ throw std::runtime_error(error_message.str());
+ }
+ if (!(al_is_audio_installed()))
+ {
+ std::stringstream error_message;
+ error_message << "Hypersync" << "::" << "initialize" << ": error: " << "guard \"al_is_audio_installed()\" not met";
+ throw std::runtime_error(error_message.str());
+ }
+ if (!(al_is_acodec_addon_initialized()))
+ {
+ std::stringstream error_message;
+ error_message << "Hypersync" << "::" << "initialize" << ": error: " << "guard \"al_is_acodec_addon_initialized()\" not met";
+ throw std::runtime_error(error_message.str());
+ }
+ if (!(event_queue))
+ {
+ std::stringstream error_message;
+ error_message << "Hypersync" << "::" << "initialize" << ": error: " << "guard \"event_queue\" not met";
+ throw std::runtime_error(error_message.str());
+ }
+ audio_voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2);
+ if (!audio_voice) throw std::runtime_error("could not create voice!!");
+
+ audio_mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
+ if (!al_attach_mixer_to_voice(audio_mixer, audio_voice))
+ {
+ throw std::runtime_error("could not attach mixer to voice");
+ }
+
+ song_filename = "/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/some-jamzz-04.ogg";
+ song_bpm = 130.0f;
+
+ //song_filename = "/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/tempo-track-180.ogg";
+ //song_bpm = 180.0f;
+
+ //song_filename = "/Users/markoates/Repos/allegro_flare/bin/data/samples/music_tracks/tempo-track-152.ogg";
+ //song_bpm = 152.0f;
+
+ audio_stream = al_load_audio_stream(song_filename.c_str(), 4, 2048);
+ if (!audio_stream) throw std::runtime_error("could not load stream!!");
+
+ al_set_audio_stream_playmode(audio_stream, ALLEGRO_PLAYMODE_ONCE);
+
+ initialized = true;
+ return;
+}
+
+void Hypersync::destruct()
+{
+ if (audio_mixer)
+ {
+ if (stream_is_attached)
+ {
+ // TODO: sort out this destruction
+ al_detach_voice(audio_voice);
+ al_destroy_mixer(audio_mixer);
+ }
+ }
+ if (audio_voice)
+ {
+ al_destroy_voice(audio_voice);
+ }
+ if (audio_stream)
+ {
+ al_unregister_event_source(event_queue, al_get_audio_stream_event_source(audio_stream));
+ al_destroy_audio_stream(audio_stream);
+ }
+ return;
+}
+
+
+} // namespace MindDive
+} // namespace Prototypes
+} // namespace AllegroFlare
+
+
diff --git a/src/AllegroFlare/Prototypes/MindDive/MindDive.cpp b/src/AllegroFlare/Prototypes/MindDive/MindDive.cpp
index 267543d16..bd4bf8df0 100644
--- a/src/AllegroFlare/Prototypes/MindDive/MindDive.cpp
+++ b/src/AllegroFlare/Prototypes/MindDive/MindDive.cpp
@@ -11,6 +11,7 @@
#include
#include
#include
+#include