diff --git a/binding-mri/audioplayback-binding.cpp b/binding-mri/audioplayback-binding.cpp index e403ebc..9ef5eb8 100644 --- a/binding-mri/audioplayback-binding.cpp +++ b/binding-mri/audioplayback-binding.cpp @@ -44,18 +44,28 @@ static VALUE rb_playbackPlay(int argc, VALUE *argv, VALUE self) { return Qnil; } -static VALUE rb_playbackStop(VALUE self){ +static VALUE rb_playbackStop(VALUE self) { PLAYBACK pb->stop(); return Qnil; } -static VALUE rb_playbackPlaying(VALUE self){ +static VALUE rb_playbackPlaying(VALUE self) { PLAYBACK return rb_bool_new(pb->isPlaying()); } +static VALUE rb_playbackLength(VALUE self) { + PLAYBACK + return INT2FIX(pb->getLength()); +} + +static VALUE rb_playbackLengthNormalized(VALUE self) { + PLAYBACK + return DBL2NUM(pb->getLengthNormalized()); +} + static VALUE rb_playbackAddTag(int argc, VALUE *argv, VALUE self) { char* c_str; rb_get_args(argc, argv, c_str RB_ARG_END); @@ -141,15 +151,15 @@ static VALUE rb_playbackGetStartSample(VALUE self) { return INT2FIX(pb->startSample); } -static VALUE rb_playbackSetMaxSamples(VALUE self, VALUE samples) { +static VALUE rb_playbackSetMaxSample(VALUE self, VALUE samples) { PLAYBACK - pb->maxSamples = samples; + pb->maxSample = samples; return Qnil; } -static VALUE rb_playbackGetMaxSamples(VALUE self) { +static VALUE rb_playbackGetMaxSample(VALUE self) { PLAYBACK - return INT2FIX(pb->maxSamples); + return INT2FIX(pb->maxSample); } static VALUE rb_playbackSetPosition(VALUE self, VALUE position){ @@ -211,6 +221,9 @@ void audioPlaybackBindingInit(){ rb_define_method(audioplayback_klass, "playing", RUBY_METHOD_FUNC(rb_playbackPlaying), 0); + rb_define_method(audioplayback_klass, "length", RUBY_METHOD_FUNC(rb_playbackLength), 0); + rb_define_method(audioplayback_klass, "length_normalized", RUBY_METHOD_FUNC(rb_playbackLengthNormalized), 0); + rb_define_method(audioplayback_klass, "add_tag", RUBY_METHOD_FUNC(rb_playbackAddTag), -1); rb_define_method(audioplayback_klass, "remove_tag", RUBY_METHOD_FUNC(rb_playbackRemoveTag), -1); rb_define_method(audioplayback_klass, "clear_tags", RUBY_METHOD_FUNC(rb_playbackClearTags), 0); @@ -227,10 +240,10 @@ void audioPlaybackBindingInit(){ rb_define_method(audioplayback_klass, "pitch=", RUBY_METHOD_FUNC(rb_playbackSetPitch), 1); rb_define_method(audioplayback_klass, "pitch", RUBY_METHOD_FUNC(rb_playbackGetPitch), 0); - rb_define_method(audioplayback_klass, "start_sample=", RUBY_METHOD_FUNC(rb_playbackSetStartSample), 1); - rb_define_method(audioplayback_klass, "start_sample", RUBY_METHOD_FUNC(rb_playbackGetStartSample), 0); - rb_define_method(audioplayback_klass, "max_samples=", RUBY_METHOD_FUNC(rb_playbackSetMaxSamples), 1); - rb_define_method(audioplayback_klass, "max_samples", RUBY_METHOD_FUNC(rb_playbackGetMaxSamples), 0); + rb_define_method(audioplayback_klass, "start_frame=", RUBY_METHOD_FUNC(rb_playbackSetStartSample), 1); + rb_define_method(audioplayback_klass, "start_frame", RUBY_METHOD_FUNC(rb_playbackGetStartSample), 0); + rb_define_method(audioplayback_klass, "max_frame=", RUBY_METHOD_FUNC(rb_playbackSetMaxSample), 1); + rb_define_method(audioplayback_klass, "max_frame", RUBY_METHOD_FUNC(rb_playbackGetMaxSample), 0); rb_define_method(audioplayback_klass, "position=", RUBY_METHOD_FUNC(rb_playbackSetPosition), 1); rb_define_method(audioplayback_klass, "position", RUBY_METHOD_FUNC(rb_playbackGetPosition), 0); diff --git a/scripts/Scene_OF.rb b/scripts/Scene_OF.rb index 2d45b2c..66c04e3 100644 --- a/scripts/Scene_OF.rb +++ b/scripts/Scene_OF.rb @@ -1,9 +1,9 @@ class Scene_OF BPM = 135 - WAIT_TIME = 1.0 * (BPM / 60.0) * Graphics.frame_rate + BPM_TIME = 1.0 / (BPM / 60.0) * Graphics.frame_rate * 2 - BUMP_SCALE = 1.2 - BUMP_RETURN_SPEED = 0.2 + BUMP_SCALE = 1.07 + BUMP_RETURN_SPEED = 0.1 ARROW_SIZE = 32 ARROW_SCALE = 2 @@ -11,6 +11,8 @@ class Scene_OF ARROWS_TOP_MARGIN = 32 ARROWS_SIDES_MARGIN = 48 + ARROWS_SPEED = 10 + SPRITES = { :cat_base_arrow_left => Rect.new(0, 0, 32, 32), :cat_base_arrow_down => Rect.new(32, 0, 32, 32), :cat_base_arrow_up => Rect.new(64, 0, 32, 32), :cat_base_arrow_right => Rect.new(96, 0, 32, 32), :cat_pressed_arrow_left => Rect.new(0, 32, 32, 32), :cat_pressed_arrow_down => Rect.new(32, 32, 32, 32), :cat_pressed_arrow_up => Rect.new(64, 32, 32, 32), :cat_pressed_arrow_right => Rect.new(96, 32, 32, 32), @@ -61,9 +63,22 @@ class Scene_OF def main Audio.bgm_stop + @arrows_states = [false, false, false, false] + + @instruments = Audio.create_sound("Audio/.cats", false, Audio.music_group) + length = @instruments.length + @instruments.max_frame = length / 3 + @voice_cat = Audio.create_sound("Audio/.cats", false, Audio.music_group) + @voice_cat.start_frame = length / 6 + @voice_cat.max_frame = length / 3 + @voice_niko = Audio.create_sound("Audio/.cats", false, Audio.music_group) + @voice_niko.start_frame = length / 3 + @voice_niko.max_frame = length / 3 * 2 + @viewport_ui = Viewport.new(0, 0, Graphics.width, Graphics.height) - @viewport_ui.ox = -Graphics.width / 2 - @viewport_ui.oy = -Graphics.height / 2 + @viewport_arrows = Viewport.new(0, 0, Graphics.width, Graphics.height) + @viewport_ui.ox = @viewport_arrows.ox = -Graphics.width / 2 + @viewport_ui.oy = @viewport_arrows.oy = -Graphics.height / 2 @spritesheet = RPG::Cache.misc(".cats") @player_arrows = [] @@ -86,10 +101,21 @@ class Scene_OF @cat_arrows << cat_arrow end - @bump_timeout = WAIT_TIME + @bst_debug = Sprite.new(@viewport_ui) + @bst_debug.bitmap = Bitmap.new(300, 40) + + @total_time = 0 + @bump_timeout = 0 + + make_mapping # Execute transition Graphics.transition(40) + + @instruments.play + @voice_cat.play + @voice_niko.play + # Main loop while true # Update game screen @@ -109,14 +135,37 @@ class Scene_OF end def update + @total_time += 1 + + # fl studio b:s:t :3 + beat = (@total_time / BPM_TIME / 2).to_i + 1 + step = (@total_time / BPM_TIME * 15 / 2).to_i % 15 + 1 + tick = (@total_time / BPM_TIME * 24 * 15 / 2).to_i % 24 + + @bst_debug.bitmap.clear + @bst_debug.bitmap.draw_text(Rect.new(0, 0, 300, 40), "#{beat} : #{step} : #{tick}") + + @viewport_arrows.oy += ARROWS_SPEED + @bump_timeout -= 1 if @bump_timeout <= 0 - @bump_timeout += WAIT_TIME - @viewport_ui.scale_x = BUMP_SCALE - @viewport_ui.scale_y = BUMP_SCALE + @bump_timeout += BPM_TIME + @viewport_arrows.scale_x = @viewport_ui.scale_x = BUMP_SCALE + @viewport_arrows.scale_y = @viewport_ui.scale_y = BUMP_SCALE + end + @viewport_arrows.scale_x = @viewport_ui.scale_x = @viewport_ui.scale_x * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED + @viewport_arrows.scale_y = @viewport_ui.scale_y = @viewport_ui.scale_y * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED + + # player + for i in 1..4 + mapped = map_input(i * 2) + is_pressed = Input.press?(i * 2) + if @arrows_states[mapped] != is_pressed + @arrows_states[mapped] = is_pressed + @player_arrows[mapped].bitmap.clear + @player_arrows[mapped].bitmap.stretch_blt(Rect.new(0, 0, ARROW_SIZE, ARROW_SIZE), @spritesheet, SPRITES[PLAYER_ARROWS_SPRITES[@arrows_states[mapped] ? :pressed : :base][mapped]]) + end end - @viewport_ui.scale_x = @viewport_ui.scale_x * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED - @viewport_ui.scale_y = @viewport_ui.scale_y * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED end def map_input(input) @@ -131,6 +180,53 @@ class Scene_OF 2 end end + + def make_mapping + @cat_flying_arrows = [] + @player_flying_arrows = [] + #beat = (@total_time / BPM_TIME / 2).to_i + 1 + #step = (@total_time / BPM_TIME * 15 / 2).to_i % 15 + 1 + #tick = (@total_time / BPM_TIME * 24 * 15 / 2).to_i % 24 + SONG_MAPPING.each do |line_data| + beat = line_data[1] + step = line_data[2] + tick = line_data[3] + for i in 0..3 + if line_data[0][i] == '#' + arrow = make_arrow(i, true) + arrow.x = ARROWS_SIDES_MARGIN + (ARROW_SIZE * ARROW_SCALE + ARROWS_PADDING) * i - Graphics.width / 2 + arrow.y = ARROWS_TOP_MARGIN - Graphics.height / 2 + + (beat - 1) * 2 * BPM_TIME * ARROWS_SPEED + + (step - 1) / 15.0 * 2 * BPM_TIME * ARROWS_SPEED + + (tick) / 24.0 / 15.0 * 2 * BPM_TIME * ARROWS_SPEED + + @cat_flying_arrows << arrow + end + end + end + end + + def make_arrow(direction, meow) + arrow = Sprite.new(@viewport_arrows) + arrow.bitmap = Bitmap.new(ARROW_SIZE, ARROW_SIZE) + arrow.bitmap.stretch_blt(Rect.new(0, 0, ARROW_SIZE, ARROW_SIZE), @spritesheet, SPRITES[(meow ? CAT_ARROWS_SPRITES : PLAYER_ARROWS_SPRITES)[:target][direction]]) + arrow.zoom_x = arrow.zoom_y = ARROW_SCALE + arrow + end + + SONG_MAPPING = [ + #arrows, B, S, T + ["# | ", 5, 1, 0], + [" # | ", 5, 3, 0], + [" # | ", 5, 5, 0], + [" #| ", 5, 9, 0], + [" # | ", 5, 13, 0], + ["# | ", 6, 1, 0], + [" # | ", 6, 3, 0], + [" # | ", 6, 5, 0], + [" # | ", 6, 9, 0], + ["# | ", 6, 13, 0], + ] end # ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ diff --git a/scripts/Script.rb b/scripts/Script.rb index b563164..0464c7b 100644 --- a/scripts/Script.rb +++ b/scripts/Script.rb @@ -239,10 +239,10 @@ module Script end def self.countdown_update_rue - def self.reflection_update(npc_id, offset_x = 0, offset_y = 0, reverse_x = false, reverse_y = false) return cdown_update(0) end + def self.reflection_update(npc_id, offset_x = 0, offset_y = 0, reverse_x = false, reverse_y = false) event = $game_map.events[npc_id] event.real_x = reverse_x ? offset_x * 128 - $game_player.real_x : $game_player.real_x + offset_x * 128 event.real_y = reverse_y ? offset_y * 128 - $game_player.real_y : $game_player.real_y + offset_y * 128 diff --git a/src/sound/audioplayback.cpp b/src/sound/audioplayback.cpp index 4d3e66b..01a5b61 100644 --- a/src/sound/audioplayback.cpp +++ b/src/sound/audioplayback.cpp @@ -112,6 +112,23 @@ bool AudioPlayback::isPlaying() const { return p_track && MIX_TrackPlaying(p_track); } +long AudioPlayback::getLength() const { + if (p_source) + return MIX_GetAudioDuration(p_source->getAudio()); + return 0.0; +} + +double AudioPlayback::getLengthNormalized() const { + if (p_source) + { + MIX_Audio* audio = p_source->getAudio(); + SDL_AudioSpec spec; + if (MIX_GetAudioFormat(audio, &spec)) + return static_cast(MIX_GetAudioDuration(audio)) / static_cast(spec.freq); + } + return 0.0; +} + void AudioPlayback::addTag(std::string tagName) { if (!p_track) return; @@ -253,7 +270,7 @@ bool AudioPlayback::fadeIn(double time) { SDL_PropertiesID props = SDL_CreateProperties(); SDL_SetNumberProperty(props, MIX_PROP_PLAY_FADE_IN_MILLISECONDS_NUMBER, time * 1000.0); SDL_SetNumberProperty(props, MIX_PROP_PLAY_START_FRAME_NUMBER, startSample); - SDL_SetNumberProperty(props, MIX_PROP_PLAY_MAX_FRAME_NUMBER, maxSamples); + SDL_SetNumberProperty(props, MIX_PROP_PLAY_MAX_FRAME_NUMBER, maxSample); if (result) { result = MIX_PlayTrack(p_track, props); diff --git a/src/sound/audioplayback.h b/src/sound/audioplayback.h index 46e0700..8202729 100644 --- a/src/sound/audioplayback.h +++ b/src/sound/audioplayback.h @@ -15,8 +15,11 @@ public: AudioPlayback(MIX_Mixer* mixer, MIX_Audio* audio, AudioGroup* group); ~AudioPlayback(); - int startSample = 0; - int maxSamples = -1; + long startSample = 0; + long maxSample = -1; + + long getLength() const; + double getLengthNormalized() const; bool initialize(MIX_Mixer* mixer, AudioSource* source, AudioGroup* group); bool initialize(MIX_Mixer* mixer, MIX_Audio* audio, AudioGroup* group);