Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 85 additions & 3 deletions src/wasm_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "gameswf/gameswf_player.h"
#include "gameswf/gameswf_movie_def.h"
#include "gameswf/gameswf_types.h"
#include "audio_mixer.h"
#include <vector>
#include <cstring>
#include <algorithm>
Expand All @@ -19,6 +20,86 @@ uint32_t g_wasm_height = 600;

static gameswf::player* g_player = nullptr;
static gameswf::root* g_movie = nullptr;
static AudioMixer g_audio_mixer;

struct WasmSoundHandler : public gameswf::sound_handler {
struct SoundData {
std::vector<int16_t> samples;
int sample_rate = 44100;
bool stereo = true;
bool is_stream = false;
};

std::vector<SoundData> m_sounds;

void reset() {
m_sounds.clear();
}

virtual bool is_open() override {
return true;
}

virtual int create_sound(
void* data,
int data_bytes,
int sample_count,
format_type format,
int sample_rate,
bool stereo) override
{
int id = static_cast<int>(m_sounds.size());
m_sounds.push_back(SoundData());
m_sounds[id].sample_rate = sample_rate;
m_sounds[id].stereo = stereo;

if (data && data_bytes > 0) {
m_sounds[id].is_stream = false;
size_t num_samples = data_bytes / sizeof(int16_t);
const int16_t* pcm = static_cast<const int16_t*>(data);
m_sounds[id].samples.assign(pcm, pcm + num_samples);
} else {
m_sounds[id].is_stream = true;
}
return id;
}

virtual int load_sound(const char* url) override {
return -1;
}

virtual void append_sound(int sound_handle, void* data, int data_bytes) override {
if (sound_handle >= 0 && sound_handle < static_cast<int>(m_sounds.size())) {
if (data && data_bytes > 0) {
size_t num_samples = data_bytes / sizeof(int16_t);
const int16_t* pcm = static_cast<const int16_t*>(data);
m_sounds[sound_handle].samples.insert(
m_sounds[sound_handle].samples.end(), pcm, pcm + num_samples);
g_audio_mixer.queue_samples(pcm, num_samples);
}
}
}

virtual void play_sound(gameswf::as_object* listener_obj, int sound_handle, int loop_count) override {
if (sound_handle >= 0 && sound_handle < static_cast<int>(m_sounds.size())) {
const auto& snd = m_sounds[sound_handle];
if (!snd.is_stream && !snd.samples.empty()) {
int loops = (loop_count < 0) ? 1 : (loop_count + 1);
for (int l = 0; l < loops; ++l) {
g_audio_mixer.queue_samples(snd.samples.data(), snd.samples.size());
}
}
}
}

virtual void set_volume(int sound_handle, int volume) override {}
virtual void set_max_volume(int vol) override {}
virtual void stop_sound(int sound_handle) override {}
virtual void stop_all_sounds() override {}
virtual void delete_sound(int sound_handle) override {}
};

static WasmSoundHandler g_sound_handler;

extern "C" {

Expand All @@ -31,7 +112,9 @@ int wasm_load_swf(const uint8_t* data, size_t size) {
}

gameswf::set_render_handler(create_render_handler_wasm());
gameswf::set_sound_handler(nullptr);
g_audio_mixer.reset();
g_sound_handler.reset();
gameswf::set_sound_handler(&g_sound_handler);

tu_file* in = create_gameswf_tu_file_mem(data, size);
if (!in) return 0;
Expand Down Expand Up @@ -89,8 +172,7 @@ uint32_t wasm_get_player_hp(void) { return 0; }

size_t wasm_get_audio_samples(int16_t* out_buffer, size_t num_frames) {
if (!out_buffer || num_frames == 0) return 0;
std::memset(out_buffer, 0, num_frames * 2 * sizeof(int16_t));
return num_frames;
return g_audio_mixer.render_frame(out_buffer, num_frames);
}

} // extern "C"
2 changes: 1 addition & 1 deletion third_party/gameswf/gameswf/gameswf_sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ namespace gameswf
character* sib = parent_sp->m_display_list.get_character(i);
if (sib && sib != this) {
sprite_instance* sib_sp = cast_to<sprite_instance>(sib);
if (sib_sp && sib_sp->get_character_def() && sib_sp->get_frame_count() > 0 && sib_sp->get_loaded_bytes() == 0) {
if (sib_sp && sib_sp->get_character_def() && sib_sp->get_frame_count() > 0 && sib_sp->m_on_event_load_called == false) {
skip_enterframe = true;
break;
}
Expand Down
Loading