168 lines
3.9 KiB
C++
168 lines
3.9 KiB
C++
#pragma once
|
|
|
|
#include "../Environment.h"
|
|
#include "../Types.hpp"
|
|
#include <string>
|
|
#include <tuple>
|
|
#include <vector>
|
|
|
|
struct Mix_Chunk;
|
|
|
|
namespace openloco
|
|
{
|
|
struct vehicle_26;
|
|
}
|
|
|
|
namespace openloco::audio
|
|
{
|
|
struct sample
|
|
{
|
|
void* pcm{};
|
|
size_t len{};
|
|
Mix_Chunk* chunk{};
|
|
};
|
|
|
|
// TODO: This should only be a byte needs to be split off from sound object
|
|
enum class sound_id : uint16_t
|
|
{
|
|
click_down = 0,
|
|
click_up = 1,
|
|
click_press = 2,
|
|
construct = 3,
|
|
demolish = 4,
|
|
income = 5,
|
|
crash = 6,
|
|
water = 7,
|
|
splash_1 = 8,
|
|
splash_2 = 9,
|
|
waypoint = 10,
|
|
notification = 11,
|
|
open_window = 12,
|
|
applause_1 = 13,
|
|
error = 14,
|
|
unk_15 = 15,
|
|
unk_16 = 16,
|
|
demolish_tree = 17,
|
|
demolish_building = 18,
|
|
unk_19 = 19,
|
|
unk_20 = 20,
|
|
construct_ship = 21,
|
|
ticker = 22,
|
|
applause_2 = 23,
|
|
news_oooh = 24,
|
|
news_awww = 25,
|
|
breakdown_1 = 26,
|
|
breakdown_2 = 27,
|
|
breakdown_3 = 28,
|
|
breakdown_4 = 29,
|
|
breakdown_5 = 30,
|
|
breakdown_6 = 31,
|
|
|
|
null = 0xFF
|
|
};
|
|
|
|
enum class channel_id
|
|
{
|
|
bgm,
|
|
unk_1,
|
|
ambient,
|
|
title,
|
|
vehicle_0, // * 10
|
|
};
|
|
constexpr int32_t num_reserved_channels = 4 + 10;
|
|
|
|
using music_id = uint8_t;
|
|
|
|
struct music_info
|
|
{
|
|
environment::path_id path_id;
|
|
string_id title_id;
|
|
uint16_t start_year;
|
|
uint16_t end_year;
|
|
};
|
|
|
|
void initialiseDSound();
|
|
void disposeDSound();
|
|
|
|
const std::vector<std::string>& getDevices();
|
|
const char* getCurrentDeviceName();
|
|
size_t getCurrentDevice();
|
|
void set_device(size_t index);
|
|
|
|
sample* getSoundSample(sound_id id);
|
|
bool shouldSoundLoop(sound_id id);
|
|
|
|
void toggleSound();
|
|
void pauseSound();
|
|
void unpauseSound();
|
|
void playSound(vehicle_26* t);
|
|
void playSound(sound_id id, loc16 loc);
|
|
void playSound(sound_id id, loc16 loc, int32_t pan);
|
|
void playSound(sound_id id, int32_t pan);
|
|
void playSound(sound_id id, loc16 loc, int32_t volume, int32_t frequency);
|
|
void updateSounds();
|
|
|
|
bool loadChannel(channel_id id, const char* path, int32_t c);
|
|
bool playChannel(channel_id id, int32_t loop, int32_t volume, int32_t d, int32_t freq);
|
|
void stopChannel(channel_id id);
|
|
void setChannelVolume(channel_id id, int32_t volume);
|
|
bool isChannelPlaying(channel_id id);
|
|
|
|
void updateVehicleNoise();
|
|
void stopVehicleNoise();
|
|
|
|
void updateAmbientNoise();
|
|
void stopAmbientNoise();
|
|
|
|
void revalidateCurrentTrack();
|
|
|
|
void playBackgroundMusic();
|
|
void stopBackgroundMusic();
|
|
void playTitleScreenMusic();
|
|
void stopTitleMusic();
|
|
|
|
bool isAudioEnabled();
|
|
|
|
const music_info* getMusicInfo(music_id track);
|
|
constexpr int32_t num_music_tracks = 29;
|
|
|
|
/**
|
|
* Converts a Locomotion volume range to SDL2.
|
|
* @remarks Not constexpr as it requires an SDL2 macro and we avoid
|
|
* library header includes in our own headers.
|
|
*/
|
|
int32_t volumeLocoToSDL(int32_t loco);
|
|
|
|
constexpr bool isObjectSoundId(sound_id id)
|
|
{
|
|
return ((int32_t)id & 0x8000);
|
|
}
|
|
|
|
constexpr sound_id makeObjectSoundId(sound_object_id_t id)
|
|
{
|
|
return (sound_id)((int32_t)id | 0x8000);
|
|
}
|
|
|
|
/**
|
|
* Converts a Locomotion pan range to a left and right value for SDL2 mixer.
|
|
*/
|
|
constexpr std::tuple<int32_t, int32_t> panLocoToSDL(int32_t pan)
|
|
{
|
|
constexpr auto range = 2048.0f;
|
|
if (pan == 0)
|
|
{
|
|
return std::make_tuple(0, 0);
|
|
}
|
|
else if (pan < 0)
|
|
{
|
|
auto r = (int32_t)(255 - ((pan / -range) * 255));
|
|
return std::make_tuple(255, r);
|
|
}
|
|
else
|
|
{
|
|
auto r = (int32_t)(255 - ((pan / range) * 255));
|
|
return std::make_tuple(r, 255);
|
|
}
|
|
}
|
|
}
|