summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--res/maps/hallucination_beach.tmx3
-rw-r--r--res/maps/hallucination_cliff.tmx3
-rw-r--r--res/maps/hallucination_hot_spring.tmx3
-rw-r--r--res/maps/hallucination_interior.tmx3
-rw-r--r--res/music/red_green_yellow_yellow.wavbin0 -> 7078446 bytes
-rw-r--r--res/scripts/common.lua8
-rw-r--r--src/main.cpp4
-rw-r--r--src/map.cpp6
-rw-r--r--src/map.h5
-rw-r--r--src/mixer.cpp58
-rw-r--r--src/mixer.h36
-rw-r--r--src/script_system.cpp18
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
158bool Map::isBlocked(int x, int y) const { 164bool 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
80private: 84private:
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
26void 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
43void Mixer::fadeoutMusic(int ms) {
44 if (Mix_FadeOutMusic(ms) == 0) {
45 throw mix_error();
46 }
47
48 playingTrack_ = "";
49}
50
51void Mixer::muteMusic() {
52 Mix_VolumeMusic(0);
53 musicMuted_ = true;
54}
55
56void Mixer::unmuteMusic() {
57 Mix_VolumeMusic(musicVolume_);
58 musicMuted_ = false;
59}
60
61void Mixer::pauseMusic() {
62 Mix_PauseMusic();
63}
64
65void Mixer::unpauseMusic() {
66 Mix_ResumeMusic();
67}
68
26Mix_Chunk* Mixer::getChunkByFilename(std::string filename) { 69Mix_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
82Mix_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
53using chunk_ptr = std::unique_ptr<Mix_Chunk, chunk_deleter>; 53using chunk_ptr = std::unique_ptr<Mix_Chunk, chunk_deleter>;
54 54
55class music_deleter {
56public:
57
58 void operator()(Mix_Music* music) {
59 Mix_FreeMusic(music);
60 }
61};
62
63using music_ptr = std::unique_ptr<Mix_Music, music_deleter>;
64
55// MUST create the Renderer first! 65// MUST create the Renderer first!
56class Mixer { 66class Mixer {
57public: 67public:
@@ -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
65private: 95private:
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(