mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-20 13:15:16 -04:00
mp3 support for playing background music
This commit is contained in:
parent
73a4187f79
commit
dd23d8c989
24 changed files with 2245 additions and 252 deletions
|
@ -14,10 +14,11 @@ void show_help(const char *arg0) {
|
|||
"\n"
|
||||
"Usage:"
|
||||
);
|
||||
printf("%s [-f <file>] [-a <file>] [-l <lang>] [-s <dir>] [-h]\n\n", arg0);
|
||||
printf("%s [-f <file>] [-a <file>] [-p <file> ] [-l <lang>] [-s <dir>] [-h]\n\n", arg0);
|
||||
|
||||
printf("-f <file> path to configuration file\n"
|
||||
"-a <adv> path for adventure file (.adv)\n"
|
||||
"-p <file> patch data with custom DDL\n"
|
||||
"-l <lang> set language (cz|en)\n"
|
||||
"-s <directory> generate string-tables (for localization) and exit\n"
|
||||
"-h this help\n");
|
||||
|
@ -33,12 +34,14 @@ int main(int argc, char **argv) {
|
|||
std::string config_name = SKELDALINI;
|
||||
std::string adv_config_file;
|
||||
std::string gen_stringtable_path;
|
||||
std::string patch;
|
||||
std::string lang;
|
||||
for (int optchr = -1; (optchr = getopt(argc, argv, "hf:a:s:l:")) != -1; ) {
|
||||
for (int optchr = -1; (optchr = getopt(argc, argv, "hf:a:s:l:p:")) != -1; ) {
|
||||
switch (optchr) {
|
||||
case 'f': config_name = optarg;break;
|
||||
case 'a': adv_config_file = optarg;break;
|
||||
case 'h': show_help(argv[0]);break;
|
||||
case 'p': patch = optarg; break;
|
||||
case 'l': lang = optarg;break;
|
||||
case 's': gen_stringtable_path = optarg;break;
|
||||
default: show_help_short();
|
||||
|
@ -54,6 +57,7 @@ int main(int argc, char **argv) {
|
|||
cfg.adventure_path = adv_config_file.empty()?NULL:adv_config_file.c_str();
|
||||
cfg.config_path = config_name.c_str();
|
||||
cfg.lang_path = lang.empty()?NULL:lang.c_str();
|
||||
cfg.patch_file = patch.empty()?NULL:patch.c_str();
|
||||
try {
|
||||
|
||||
if (!gen_stringtable_path.empty()) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
// Funkce pro mapování souboru do paměti
|
||||
void* map_file_to_memory(const char *name, size_t *sz) {
|
||||
const void* map_file_to_memory(const char *name, size_t *sz) {
|
||||
if (!name || !sz) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -49,13 +49,13 @@ void* map_file_to_memory(const char *name, size_t *sz) {
|
|||
}
|
||||
|
||||
// Funkce pro zrušení mapování
|
||||
void unmap_file(void *ptr, size_t sz) {
|
||||
void unmap_file(const void *ptr, size_t sz) {
|
||||
if (!ptr || sz == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Zrušení mapování
|
||||
if (munmap(ptr, sz) == -1) {
|
||||
perror("Chyba při rušení mapování");
|
||||
if (munmap((void *)ptr, sz) == -1) {
|
||||
perror("Failed to unmap file");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(void *ptr, size_t sz);
|
||||
const void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(const void *ptr, size_t sz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -82,8 +82,8 @@ char change_current_directory(const char *path);
|
|||
|
||||
|
||||
|
||||
void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(void *ptr, size_t sz);
|
||||
const void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(const void *ptr, size_t sz);
|
||||
|
||||
char copy_text_to_clipboard(const char *);
|
||||
|
||||
|
|
|
@ -130,10 +130,10 @@ size_t copy_to_music_buffer(const void *data, size_t data_size) {
|
|||
}
|
||||
|
||||
|
||||
static const char * (*end_of_song_callback)(void *ctx) = NULL;
|
||||
static TEND_OF_SONG_CALLBACK end_of_song_callback;
|
||||
static void *end_of_song_callback_ctx = NULL;
|
||||
|
||||
void set_end_of_song_callback(const char * (*cb)(void *), void *ctx) {
|
||||
void set_end_of_song_callback(TEND_OF_SONG_CALLBACK cb, void *ctx) {
|
||||
end_of_song_callback = cb;
|
||||
end_of_song_callback_ctx = ctx;
|
||||
}
|
||||
|
@ -191,9 +191,9 @@ void create_new_music_track(int freq, int buffsize) {
|
|||
music_buffer_write_pos = buffsize/2;
|
||||
}
|
||||
|
||||
static std::unique_ptr<IMusicStream> load_music_ex(const char *name) {
|
||||
if (name) {
|
||||
TMUSIC_STREAM *stream = music_open(name);
|
||||
static std::unique_ptr<IMusicStream> load_music_ex(const TMUSIC_SOURCE *src, TMUSIC_SOURCE_TYPE type) {
|
||||
if (src) {
|
||||
TMUSIC_STREAM *stream = music_open(src, type);
|
||||
if (stream) {
|
||||
TMUSIC_STREAM_INFO nfo = music_get_info(stream);
|
||||
if (nfo.channels != 2) {
|
||||
|
@ -212,8 +212,10 @@ static std::unique_ptr<IMusicStream> load_music_ex(const char *name) {
|
|||
static void handle_end_of_song() {
|
||||
current_music.reset();
|
||||
if (end_of_song_callback != NULL) {
|
||||
const char *new_music = end_of_song_callback(end_of_song_callback_ctx);
|
||||
current_music = load_music_ex(new_music);
|
||||
TMUSIC_SOURCE src;
|
||||
TMUSIC_SOURCE_TYPE type;
|
||||
char ok = end_of_song_callback(end_of_song_callback_ctx, &src, &type);
|
||||
current_music = ok?load_music_ex(&src, type):std::unique_ptr<IMusicStream>{};
|
||||
if (current_music) {
|
||||
auto nfo = current_music->get_info();
|
||||
create_new_music_track(nfo.freq, BACK_BUFF_SIZE);
|
||||
|
@ -246,13 +248,16 @@ int mix_back_sound(int _) {
|
|||
|
||||
}
|
||||
|
||||
//int open_backsound(char *filename);
|
||||
void change_music(const char *filename) {
|
||||
void stop_play_music() {
|
||||
if (music_source) {
|
||||
fade_music();
|
||||
stop_music();
|
||||
fade_music();
|
||||
stop_music();
|
||||
}
|
||||
current_music = load_music_ex(filename);
|
||||
}
|
||||
|
||||
void play_music(const TMUSIC_SOURCE *source, TMUSIC_SOURCE_TYPE type) {
|
||||
stop_play_music();
|
||||
current_music = load_music_ex(source, type);
|
||||
if (current_music) {
|
||||
auto nfo = current_music->get_info();
|
||||
create_new_music_track(nfo.freq, BACK_BUFF_SIZE);
|
||||
|
@ -309,7 +314,7 @@ char set_snd_effect(AUDIO_PROPERTY funct,int data) {
|
|||
case SND_PING: break;
|
||||
case SND_GFX: sound_effect_volume = data/256.0;break;
|
||||
case SND_MUSIC: music_volume = data/128.0;update_music_volume();break;
|
||||
case SND_GVOLUME: master_volume = data/512.0;update_music_volume();break;
|
||||
case SND_GVOLUME: master_volume = data/512.0;update_music_volume();break;
|
||||
case SND_SWAP: swap_channels = !!data;break;
|
||||
case SND_BASS: bass_boost = data/25.0;sound_mixer.set_bass(bass_boost);break;
|
||||
case SND_TREBL: treble_boost = data/25.0;sound_mixer.set_treble(treble_boost);break;
|
||||
|
|
|
@ -24,14 +24,19 @@ SND_MAXFUNCT} AUDIO_PROPERTY;
|
|||
|
||||
void game_sound_init_device(const INI_CONFIG_SECTION *audio_section);
|
||||
|
||||
|
||||
typedef char (*TEND_OF_SONG_CALLBACK)(void *ctx, TMUSIC_SOURCE *, TMUSIC_SOURCE_TYPE *);
|
||||
|
||||
|
||||
char start_mixing();
|
||||
void stop_mixing();
|
||||
void play_sample(int channel,const void *sample,int32_t size,int32_t lstart,int32_t sfreq,int type);
|
||||
void set_channel_volume(int channel,int left,int right);
|
||||
void set_end_of_song_callback(const char * (*cb)(void *), void *ctx);
|
||||
void set_end_of_song_callback(TEND_OF_SONG_CALLBACK cb, void *ctx);
|
||||
void play_music(const TMUSIC_SOURCE *source, TMUSIC_SOURCE_TYPE type);
|
||||
void stop_play_music();
|
||||
void fade_music();
|
||||
int mix_back_sound(int synchro);
|
||||
void change_music(const char *filename);
|
||||
char get_channel_state(int channel);
|
||||
void get_channel_volume(int channel,int *left,int *right);
|
||||
void mute_channel(int channel);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <shellapi.h>
|
||||
|
||||
void show_help(std::ostream &out, const char *arg0) {
|
||||
out <<
|
||||
out <<
|
||||
"Brany Skeldalu (Gates of Skeldal) portable game player\n"
|
||||
"Copyright (c) 2025 Ondrej Novak. All rights reserved.\n\n"
|
||||
"This work is licensed under the terms of the MIT license.\n"
|
||||
|
@ -21,9 +21,10 @@ void show_help(std::ostream &out, const char *arg0) {
|
|||
out << arg0 << " [-f <file>] [-a <file>] [-l <lang>] [-s <dir>] [-h]\n\n";
|
||||
out << "-f <file> path to configuration file\n"
|
||||
"-a <adv> path for adventure file (.adv)\n"
|
||||
"-p <file> patch data with custom DDL\n"
|
||||
"-l <lang> set language (cz|en)\n"
|
||||
"-s <directory> generate string-tables (for localization) and exit\n"
|
||||
"-h this help\n";
|
||||
"-h this help\n";
|
||||
}
|
||||
|
||||
void show_help_short(std::ostream &out) {
|
||||
|
@ -31,20 +32,22 @@ void show_help_short(std::ostream &out) {
|
|||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int main(int argc, char **argv) {
|
||||
std::string config_name = SKELDALINI;
|
||||
std::string adv_config_file;
|
||||
std::string gen_stringtable_path;
|
||||
std::string lang;
|
||||
std::string patch;
|
||||
std::ostringstream console;
|
||||
for (int optchr = -1; (optchr = getopt(argc, argv, "hf:a:s:l:")) != -1; ) {
|
||||
for (int optchr = -1; (optchr = getopt(argc, argv, "hf:a:s:l:p:")) != -1; ) {
|
||||
switch (optchr) {
|
||||
case 'f': config_name = optarg;break;
|
||||
case 'a': adv_config_file = optarg;break;
|
||||
case 'h': show_help(console, argv[0]);break;
|
||||
case 'p': patch = optarg; break;
|
||||
case 'l': lang = optarg;break;
|
||||
case 's': gen_stringtable_path = optarg;break;
|
||||
default: show_help_short(console);break;
|
||||
default: show_help_short(console);break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +67,7 @@ int main(int argc, char **argv) {
|
|||
cfg.adventure_path = adv_config_file.empty()?NULL:adv_config_file.c_str();
|
||||
cfg.config_path = config_name.c_str();
|
||||
cfg.lang_path = lang.empty()?NULL:lang.c_str();
|
||||
cfg.patch_file = patch.empty()?NULL:patch.c_str();
|
||||
|
||||
{
|
||||
std::string msg = console.str();
|
||||
|
|
|
@ -12,7 +12,7 @@ extern "C" {
|
|||
#include <stdexcept>
|
||||
|
||||
// Funkce pro mapování souboru do paměti
|
||||
void* map_file_to_memory_cpp(const char *name, size_t *sz) {
|
||||
const void* map_file_to_memory_cpp(const char *name, size_t *sz) {
|
||||
if (!name || !sz) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ void* map_file_to_memory_cpp(const char *name, size_t *sz) {
|
|||
throw std::runtime_error(std::string("failed to get size of file:").append(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HANDLE hMapping = CreateFileMapping(h,NULL,PAGE_READONLY,0,0,NULL);
|
||||
if (hMapping == NULL || hMapping == INVALID_HANDLE_VALUE) {
|
||||
|
@ -40,16 +40,16 @@ void* map_file_to_memory_cpp(const char *name, size_t *sz) {
|
|||
if (mappedData == NULL) {
|
||||
throw std::runtime_error(std::string("Failed to map file:").append(name));
|
||||
}
|
||||
|
||||
|
||||
*sz = fsize.LowPart;
|
||||
return mappedData;
|
||||
}
|
||||
|
||||
void* map_file_to_memory(const char *name, size_t *sz) {
|
||||
const void* map_file_to_memory(const char *name, size_t *sz) {
|
||||
return map_file_to_memory_cpp(name, sz);
|
||||
}
|
||||
|
||||
// Funkce pro zrušení mapování
|
||||
void unmap_file(void *ptr, size_t) {
|
||||
UnmapViewOfFile(ptr);
|
||||
void unmap_file(const void *ptr, size_t) {
|
||||
UnmapViewOfFile((void *)ptr);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(void *ptr, size_t sz);
|
||||
const void *map_file_to_memory(const char *name, size_t *sz);
|
||||
void unmap_file(const void *ptr, size_t sz);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue