diff options
| -rw-r--r-- | res/maps/hallucination_beach.tmx | 3 | ||||
| -rw-r--r-- | res/maps/hallucination_cliff.tmx | 3 | ||||
| -rw-r--r-- | res/maps/hallucination_hot_spring.tmx | 3 | ||||
| -rw-r--r-- | res/maps/hallucination_interior.tmx | 3 | ||||
| -rw-r--r-- | res/music/red_green_yellow_yellow.wav | bin | 0 -> 7078446 bytes | |||
| -rw-r--r-- | res/scripts/common.lua | 8 | ||||
| -rw-r--r-- | src/main.cpp | 4 | ||||
| -rw-r--r-- | src/map.cpp | 6 | ||||
| -rw-r--r-- | src/map.h | 5 | ||||
| -rw-r--r-- | src/mixer.cpp | 58 | ||||
| -rw-r--r-- | src/mixer.h | 36 | ||||
| -rw-r--r-- | src/script_system.cpp | 18 |
12 files changed, 142 insertions, 5 deletions
| diff --git a/res/maps/hallucination_beach.tmx b/res/maps/hallucination_beach.tmx index c6fd1cb..ce6c830 100644 --- a/res/maps/hallucination_beach.tmx +++ b/res/maps/hallucination_beach.tmx | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="48" height="32" tilewidth="16" tileheight="16" infinite="0" nextlayerid="2" nextobjectid="1"> | 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="48" height="32" tilewidth="16" tileheight="16" infinite="0" nextlayerid="2" nextobjectid="1"> |
| 3 | <properties> | ||
| 4 | <property name="music" value="red_green_yellow_yellow"/> | ||
| 5 | </properties> | ||
| 3 | <tileset firstgid="1" source="hallucination.tsx"/> | 6 | <tileset firstgid="1" source="hallucination.tsx"/> |
| 4 | <layer id="1" name="Lower" width="48" height="32"> | 7 | <layer id="1" name="Lower" width="48" height="32"> |
| 5 | <data encoding="csv"> | 8 | <data encoding="csv"> |
| diff --git a/res/maps/hallucination_cliff.tmx b/res/maps/hallucination_cliff.tmx index e6bd65e..8159d54 100644 --- a/res/maps/hallucination_cliff.tmx +++ b/res/maps/hallucination_cliff.tmx | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="48" height="48" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="5"> | 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="48" height="48" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="5"> |
| 3 | <properties> | ||
| 4 | <property name="music" value="red_green_yellow_yellow"/> | ||
| 5 | </properties> | ||
| 3 | <tileset firstgid="1" source="hallucination.tsx"/> | 6 | <tileset firstgid="1" source="hallucination.tsx"/> |
| 4 | <layer id="2" name="Background" width="48" height="48"> | 7 | <layer id="2" name="Background" width="48" height="48"> |
| 5 | <data encoding="csv"> | 8 | <data encoding="csv"> |
| diff --git a/res/maps/hallucination_hot_spring.tmx b/res/maps/hallucination_hot_spring.tmx index 2bb840d..b019681 100644 --- a/res/maps/hallucination_hot_spring.tmx +++ b/res/maps/hallucination_hot_spring.tmx | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="5"> | 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="5"> |
| 3 | <properties> | ||
| 4 | <property name="music" value="red_green_yellow_yellow"/> | ||
| 5 | </properties> | ||
| 3 | <tileset firstgid="1" source="hallucination.tsx"/> | 6 | <tileset firstgid="1" source="hallucination.tsx"/> |
| 4 | <layer id="2" name="Lower" width="32" height="16"> | 7 | <layer id="2" name="Lower" width="32" height="16"> |
| 5 | <data encoding="csv"> | 8 | <data encoding="csv"> |
| diff --git a/res/maps/hallucination_interior.tmx b/res/maps/hallucination_interior.tmx index e792133..ee7a5cd 100644 --- a/res/maps/hallucination_interior.tmx +++ b/res/maps/hallucination_interior.tmx | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="64" height="64" tilewidth="16" tileheight="16" infinite="0" nextlayerid="2" nextobjectid="3"> | 2 | <map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="64" height="64" tilewidth="16" tileheight="16" infinite="0" nextlayerid="2" nextobjectid="3"> |
| 3 | <properties> | ||
| 4 | <property name="music" value="red_green_yellow_yellow"/> | ||
| 5 | </properties> | ||
| 3 | <tileset firstgid="1" source="hallucination.tsx"/> | 6 | <tileset firstgid="1" source="hallucination.tsx"/> |
| 4 | <layer id="1" name="Lower" width="64" height="64"> | 7 | <layer id="1" name="Lower" width="64" height="64"> |
| 5 | <data encoding="csv"> | 8 | <data encoding="csv"> |
| diff --git a/res/music/red_green_yellow_yellow.wav b/res/music/red_green_yellow_yellow.wav new file mode 100644 index 0000000..e1cd6dd --- /dev/null +++ b/res/music/red_green_yellow_yellow.wav | |||
| Binary files differ | |||
| diff --git a/res/scripts/common.lua b/res/scripts/common.lua index 2a51419..a5e7873 100644 --- a/res/scripts/common.lua +++ b/res/scripts/common.lua | |||
| @@ -260,7 +260,13 @@ function ChangeMap(map, warp, options) | |||
| 260 | FadeToBlack(150) | 260 | FadeToBlack(150) |
| 261 | end | 261 | end |
| 262 | loadMap(map) | 262 | loadMap(map) |
| 263 | character():transplantParty(playerId, getWarpPoint(warp), direction) | 263 | character():transplantParty(playerId, getMap():getWarpPoint(warp), direction) |
| 264 | |||
| 265 | if (mixer():isPlayingMusic() and not getMap():hasMusic()) then | ||
| 266 | mixer():fadeoutMusic(150) | ||
| 267 | elseif (getMap():hasMusic() and (not mixer():isPlayingMusic() or not mixer():getPlayingTrack() == getMap():getMusic())) then | ||
| 268 | mixer():playMusic(getMap():getMusic(), 150) | ||
| 269 | end | ||
| 264 | 270 | ||
| 265 | coroutine.yield() | 271 | coroutine.yield() |
| 266 | if (options & ChangeMapOptions.DO_NOT_FADE == 0) then | 272 | if (options & ChangeMapOptions.DO_NOT_FADE == 0) then |
| diff --git a/src/main.cpp b/src/main.cpp index 25e7013..b98c8f1 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -70,6 +70,10 @@ void loop(Renderer& renderer, std::mt19937& rng) { | |||
| 70 | 70 | ||
| 71 | renderer.render(game); | 71 | renderer.render(game); |
| 72 | 72 | ||
| 73 | if (game.getMap().hasMusic()) { | ||
| 74 | game.getMixer().playMusic(game.getMap().getMusic()); | ||
| 75 | } | ||
| 76 | |||
| 73 | size_t lastTime = SDL_GetTicks(); | 77 | size_t lastTime = SDL_GetTicks(); |
| 74 | 78 | ||
| 75 | while (!game.shouldQuit()) { | 79 | while (!game.shouldQuit()) { |
| diff --git a/src/map.cpp b/src/map.cpp index a5ecbdd..7a3de78 100644 --- a/src/map.cpp +++ b/src/map.cpp | |||
| @@ -153,6 +153,12 @@ Map::Map(std::string_view name) : name_(name) { | |||
| 153 | } | 153 | } |
| 154 | } | 154 | } |
| 155 | } | 155 | } |
| 156 | |||
| 157 | for (const tmx::Property& property : mapfile.getProperties()) { | ||
| 158 | if (property.getName() == "music") { | ||
| 159 | music_ = property.getStringValue(); | ||
| 160 | } | ||
| 161 | } | ||
| 156 | } | 162 | } |
| 157 | 163 | ||
| 158 | bool Map::isBlocked(int x, int y) const { | 164 | bool Map::isBlocked(int x, int y) const { |
| diff --git a/src/map.h b/src/map.h index 9f5a93b..ee88920 100644 --- a/src/map.h +++ b/src/map.h | |||
| @@ -77,6 +77,10 @@ public: | |||
| 77 | 77 | ||
| 78 | const Zone& getZone(const std::string& name) const { return zones_.at(name); } | 78 | const Zone& getZone(const std::string& name) const { return zones_.at(name); } |
| 79 | 79 | ||
| 80 | bool hasMusic() const { return !music_.empty(); } | ||
| 81 | |||
| 82 | const std::string& getMusic() const { return music_; } | ||
| 83 | |||
| 80 | private: | 84 | private: |
| 81 | 85 | ||
| 82 | std::string name_; | 86 | std::string name_; |
| @@ -90,6 +94,7 @@ private: | |||
| 90 | std::map<std::string, vec2i> warpPoints_; | 94 | std::map<std::string, vec2i> warpPoints_; |
| 91 | std::vector<Trigger> triggers_; | 95 | std::vector<Trigger> triggers_; |
| 92 | std::map<std::string, Zone> zones_; | 96 | std::map<std::string, Zone> zones_; |
| 97 | std::string music_; | ||
| 93 | }; | 98 | }; |
| 94 | 99 | ||
| 95 | #endif /* end of include guard: MAP_H_D95D6D47 */ | 100 | #endif /* end of include guard: MAP_H_D95D6D47 */ |
| diff --git a/src/mixer.cpp b/src/mixer.cpp index bdcb7ce..37c2177 100644 --- a/src/mixer.cpp +++ b/src/mixer.cpp | |||
| @@ -23,6 +23,49 @@ void Mixer::stopChannel(int channel) { | |||
| 23 | Mix_HaltChannel(channel); | 23 | Mix_HaltChannel(channel); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | void Mixer::playMusic(std::string_view name, int ms) { | ||
| 27 | Mix_Music* song = getMusicByName(name); | ||
| 28 | int ret; | ||
| 29 | |||
| 30 | if (ms == 0) { | ||
| 31 | ret = Mix_PlayMusic(song, -1); | ||
| 32 | } else { | ||
| 33 | ret = Mix_FadeInMusic(song, -1, ms); | ||
| 34 | } | ||
| 35 | |||
| 36 | if (ret == -1) { | ||
| 37 | throw mix_error(); | ||
| 38 | } | ||
| 39 | |||
| 40 | playingTrack_ = name; | ||
| 41 | } | ||
| 42 | |||
| 43 | void Mixer::fadeoutMusic(int ms) { | ||
| 44 | if (Mix_FadeOutMusic(ms) == 0) { | ||
| 45 | throw mix_error(); | ||
| 46 | } | ||
| 47 | |||
| 48 | playingTrack_ = ""; | ||
| 49 | } | ||
| 50 | |||
| 51 | void Mixer::muteMusic() { | ||
| 52 | Mix_VolumeMusic(0); | ||
| 53 | musicMuted_ = true; | ||
| 54 | } | ||
| 55 | |||
| 56 | void Mixer::unmuteMusic() { | ||
| 57 | Mix_VolumeMusic(musicVolume_); | ||
| 58 | musicMuted_ = false; | ||
| 59 | } | ||
| 60 | |||
| 61 | void Mixer::pauseMusic() { | ||
| 62 | Mix_PauseMusic(); | ||
| 63 | } | ||
| 64 | |||
| 65 | void Mixer::unpauseMusic() { | ||
| 66 | Mix_ResumeMusic(); | ||
| 67 | } | ||
| 68 | |||
| 26 | Mix_Chunk* Mixer::getChunkByFilename(std::string filename) { | 69 | Mix_Chunk* Mixer::getChunkByFilename(std::string filename) { |
| 27 | if (!sounds_.count(filename)) { | 70 | if (!sounds_.count(filename)) { |
| 28 | Mix_Chunk* sample = Mix_LoadWAV(filename.c_str()); | 71 | Mix_Chunk* sample = Mix_LoadWAV(filename.c_str()); |
| @@ -35,3 +78,18 @@ Mix_Chunk* Mixer::getChunkByFilename(std::string filename) { | |||
| 35 | 78 | ||
| 36 | return sounds_[filename].get(); | 79 | return sounds_[filename].get(); |
| 37 | } | 80 | } |
| 81 | |||
| 82 | Mix_Music* Mixer::getMusicByName(std::string_view name) { | ||
| 83 | std::string filename = "../res/music/" + std::string(name) + ".wav"; | ||
| 84 | |||
| 85 | if (!music_.count(filename)) { | ||
| 86 | Mix_Music* song = Mix_LoadMUS(filename.c_str()); | ||
| 87 | if (!song) { | ||
| 88 | throw mix_error(); | ||
| 89 | } | ||
| 90 | |||
| 91 | music_[filename] = music_ptr(song); | ||
| 92 | } | ||
| 93 | |||
| 94 | return music_[filename].get(); | ||
| 95 | } | ||
| diff --git a/src/mixer.h b/src/mixer.h index 7f6ef72..b049118 100644 --- a/src/mixer.h +++ b/src/mixer.h | |||
| @@ -52,6 +52,16 @@ public: | |||
| 52 | 52 | ||
| 53 | using chunk_ptr = std::unique_ptr<Mix_Chunk, chunk_deleter>; | 53 | using chunk_ptr = std::unique_ptr<Mix_Chunk, chunk_deleter>; |
| 54 | 54 | ||
| 55 | class music_deleter { | ||
| 56 | public: | ||
| 57 | |||
| 58 | void operator()(Mix_Music* music) { | ||
| 59 | Mix_FreeMusic(music); | ||
| 60 | } | ||
| 61 | }; | ||
| 62 | |||
| 63 | using music_ptr = std::unique_ptr<Mix_Music, music_deleter>; | ||
| 64 | |||
| 55 | // MUST create the Renderer first! | 65 | // MUST create the Renderer first! |
| 56 | class Mixer { | 66 | class Mixer { |
| 57 | public: | 67 | public: |
| @@ -62,12 +72,38 @@ public: | |||
| 62 | 72 | ||
| 63 | void stopChannel(int channel); | 73 | void stopChannel(int channel); |
| 64 | 74 | ||
| 75 | // name is the name of the file, not containing the extension | ||
| 76 | // ms is the time in milliseconds to fade in | ||
| 77 | void playMusic(std::string_view name, int ms = 0); | ||
| 78 | |||
| 79 | bool isPlayingMusic() const { return !playingTrack_.empty(); } | ||
| 80 | |||
| 81 | const std::string& getPlayingTrack() const { return playingTrack_; } | ||
| 82 | |||
| 83 | void fadeoutMusic(int ms); | ||
| 84 | |||
| 85 | void muteMusic(); | ||
| 86 | |||
| 87 | void unmuteMusic(); | ||
| 88 | |||
| 89 | bool isMusicMuted() const { return musicMuted_; } | ||
| 90 | |||
| 91 | void pauseMusic(); | ||
| 92 | |||
| 93 | void unpauseMusic(); | ||
| 94 | |||
| 65 | private: | 95 | private: |
| 66 | 96 | ||
| 67 | Mix_Chunk* getChunkByFilename(std::string filename); | 97 | Mix_Chunk* getChunkByFilename(std::string filename); |
| 68 | 98 | ||
| 99 | Mix_Music* getMusicByName(std::string_view name); | ||
| 100 | |||
| 69 | mix_wrapper mix_; | 101 | mix_wrapper mix_; |
| 70 | std::map<std::string, chunk_ptr> sounds_; | 102 | std::map<std::string, chunk_ptr> sounds_; |
| 103 | std::map<std::string, music_ptr> music_; | ||
| 104 | std::string playingTrack_; | ||
| 105 | int musicVolume_ = MIX_MAX_VOLUME; | ||
| 106 | bool musicMuted_ = false; | ||
| 71 | }; | 107 | }; |
| 72 | 108 | ||
| 73 | #endif /* end of include guard: MIXER_H_6DF82000 */ | 109 | #endif /* end of include guard: MIXER_H_6DF82000 */ |
| diff --git a/src/script_system.cpp b/src/script_system.cpp index 1846de2..7f9f908 100644 --- a/src/script_system.cpp +++ b/src/script_system.cpp | |||
| @@ -97,7 +97,17 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) { | |||
| 97 | "mixer", | 97 | "mixer", |
| 98 | "playSound", &Mixer::playSound, | 98 | "playSound", &Mixer::playSound, |
| 99 | "loopSound", &Mixer::loopSound, | 99 | "loopSound", &Mixer::loopSound, |
| 100 | "stopChannel", &Mixer::stopChannel); | 100 | "stopChannel", &Mixer::stopChannel, |
| 101 | "playMusic", &Mixer::playMusic, | ||
| 102 | "fadeoutMusic", &Mixer::fadeoutMusic, | ||
| 103 | "isPlayingMusic", &Mixer::isPlayingMusic, | ||
| 104 | "getPlayingTrack", &Mixer::getPlayingTrack); | ||
| 105 | |||
| 106 | engine_.new_usertype<Map>( | ||
| 107 | "map", | ||
| 108 | "getWarpPoint", &Map::getWarpPoint, | ||
| 109 | "hasMusic", &Map::hasMusic, | ||
| 110 | "getMusic", &Map::getMusic); | ||
| 101 | 111 | ||
| 102 | engine_.set_function( | 112 | engine_.set_function( |
| 103 | "message", | 113 | "message", |
| @@ -190,9 +200,9 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) { | |||
| 190 | }); | 200 | }); |
| 191 | 201 | ||
| 192 | engine_.set_function( | 202 | engine_.set_function( |
| 193 | "getWarpPoint", | 203 | "getMap", |
| 194 | [&] (std::string warp) { | 204 | [&] () -> const Map& { |
| 195 | return game_.getMap().getWarpPoint(warp); | 205 | return game_.getMap(); |
| 196 | }); | 206 | }); |
| 197 | 207 | ||
| 198 | engine_.set_function( | 208 | engine_.set_function( |
