ifdef MINGW
ifneq ($(ENABLE_NLS),0)
- INTL_LIBS := -lintl -liconv
+ INTL_LIBS := -lintl -liconv
endif
- OGL_LIBS := -lopengl32 -lm
- BASE_LIBS := -lSDL -lSDL_image $(INTL_LIBS)
- ALL_LIBS := $(SDL_LIBS) -lSDL_image $(INTL_LIBS) \
- $(PNG_LIBS) -lSDL_ttf -lSDL_mixer $(OGL_LIBS)
+ OGL_LIBS := -lopengl32 -lm
+ BASE_LIBS := -lSDL -lSDL_image $(INTL_LIBS)
+ ALL_LIBS := $(SDL_LIBS) -lSDL_image $(INTL_LIBS) \
+ $(PNG_LIBS) -lSDL_ttf -lvorbisfile $(OGL_LIBS)
else
- OGL_LIBS := -lGL -lm
- BASE_LIBS := $(SDL_LIBS) -lSDL_image
- ALL_LIBS := $(BASE_LIBS) $(PNG_LIBS) -lSDL_ttf -lSDL_mixer $(OGL_LIBS)
+ OGL_LIBS := -lGL -lm
+ BASE_LIBS := $(SDL_LIBS) -lSDL_image
+ ALL_LIBS := $(BASE_LIBS) $(PNG_LIBS) -lSDL_ttf -lvorbisfile $(OGL_LIBS)
+endif
+
+#------------------------------------------------------------------------------
+# Quick hack by rlk to enable command-line building using macports
+
+ifeq ($(shell uname), Darwin)
+ ALL_CFLAGS += -I/opt/local/include
+ OGL_LIBS = -framework OpenGL
+ ALL_LIBS := -lintl -liconv $(BASE_LIBS) $(PNG_LIBS) -lSDL_ttf -lvorbisfile $(OGL_LIBS)
endif
#------------------------------------------------------------------------------
--- /dev/null
+# This makefile only exists so that I can run emacs M-x compile from within
+# the source directory. See the Makefile in the parent directory
+
+all :
+ (cd ..; $(MAKE))
+
+clean :
+ (cd ..; $(MAKE) clean)
+
+test :
+ (cd ..; $(MAKE) clean)
/* Test for an item. */
if (bt && (hp = sol_item_test(fp, p, COIN_RADIUS)))
{
- int sound = AUD_COIN;
+ const char *sound = AUD_COIN;
item_color(hp, c);
part_burst(p, c);
/*---------------------------------------------------------------------------*/
-#define AUD_MENU 1
-#define AUD_START 2
-#define AUD_READY 3
-#define AUD_SET 4
-#define AUD_GO 5
-#define AUD_BALL 6
-#define AUD_BUMPS 7
-#define AUD_BUMPM 8
-#define AUD_BUMPL 9
-#define AUD_COIN 10
-#define AUD_TICK 11
-#define AUD_TOCK 12
-#define AUD_SWITCH 13
-#define AUD_JUMP 14
-#define AUD_GOAL 15
-#define AUD_SCORE 16
-#define AUD_FALL 17
-#define AUD_TIME 18
-#define AUD_OVER 19
-#define AUD_GROW 20
-#define AUD_SHRINK 21
-#define AUD_COUNT 22
+#define AUD_MENU "snd/menu.ogg"
+#define AUD_START _("snd/select.ogg")
+#define AUD_READY _("snd/ready.ogg")
+#define AUD_SET _("snd/set.ogg")
+#define AUD_GO _("snd/go.ogg")
+#define AUD_BALL "snd/ball.ogg"
+#define AUD_BUMPS "snd/bumplil.ogg"
+#define AUD_BUMPM "snd/bump.ogg"
+#define AUD_BUMPL "snd/bumpbig.ogg"
+#define AUD_COIN "snd/coin.ogg"
+#define AUD_TICK "snd/tick.ogg"
+#define AUD_TOCK "snd/tock.ogg"
+#define AUD_SWITCH "snd/switch.ogg"
+#define AUD_JUMP "snd/jump.ogg"
+#define AUD_GOAL "snd/goal.ogg"
+#define AUD_SCORE _("snd/record.ogg")
+#define AUD_FALL _("snd/fall.ogg")
+#define AUD_TIME _("snd/time.ogg")
+#define AUD_OVER _("snd/over.ogg")
+#define AUD_GROW "snd/grow.ogg"
+#define AUD_SHRINK "snd/shrink.ogg"
/*---------------------------------------------------------------------------*/
/* Initialize the audio. */
- audio_bind(AUD_MENU, 3, "snd/menu.wav");
- audio_bind(AUD_START, 1, _("snd/select.ogg"));
- audio_bind(AUD_READY, 1, _("snd/ready.ogg"));
- audio_bind(AUD_SET, 1, _("snd/set.ogg"));
- audio_bind(AUD_GO, 1, _("snd/go.ogg"));
- audio_bind(AUD_BALL, 2, "snd/ball.ogg");
- audio_bind(AUD_BUMPS, 3, "snd/bumplil.ogg");
- audio_bind(AUD_BUMPM, 3, "snd/bump.ogg");
- audio_bind(AUD_BUMPL, 3, "snd/bumpbig.ogg");
- audio_bind(AUD_COIN, 2, "snd/coin.wav");
- audio_bind(AUD_TICK, 4, "snd/tick.ogg");
- audio_bind(AUD_TOCK, 4, "snd/tock.ogg");
- audio_bind(AUD_SWITCH, 5, "snd/switch.wav");
- audio_bind(AUD_JUMP, 5, "snd/jump.ogg");
- audio_bind(AUD_GOAL, 5, "snd/goal.wav");
- audio_bind(AUD_SCORE, 1, _("snd/record.ogg"));
- audio_bind(AUD_FALL, 1, _("snd/fall.ogg"));
- audio_bind(AUD_TIME, 1, _("snd/time.ogg"));
- audio_bind(AUD_OVER, 1, _("snd/over.ogg"));
- audio_bind(AUD_GROW, 5, "snd/grow.ogg");
- audio_bind(AUD_SHRINK, 5, "snd/shrink.ogg");
-
audio_init();
/* Require 16-bit double buffer with 16-bit depth buffer. */
goto_state(&st_title);
gui_timer(id, dt);
- audio_timer(dt);
}
static void demo_point(int id, int x, int y, int dx, int dy)
game_step_fade(dt);
gui_timer(id, dt);
- audio_timer(dt);
global_time += dt;
hud_timer(dt);
}
gui_timer(id, dt);
- audio_timer(dt);
}
static int fall_out_buttn(int b, int d)
}
gui_timer(id, dt);
- audio_timer(dt);
}
static int goal_buttn(int b, int d)
static void level_timer(int id, float dt)
{
game_step_fade(dt);
- audio_timer(dt);
}
static int level_click(int b, int d)
goto_state(&st_start);
gui_timer(id, dt);
- audio_timer(dt);
}
static int over_click(int b, int d)
switch(i)
{
case PAUSE_CONTINUE:
- Mix_ResumeMusic();
+ SDL_PauseAudio(0);
config_set_grab(0);
return goto_state(st_continue);
case PAUSE_RESTART:
level_same();
clear_pause();
- Mix_ResumeMusic();
+ SDL_PauseAudio(0);
config_set_grab(1);
return goto_state(&st_play_ready);
level_stat(GAME_NONE, curr_clock(), curr_coins());
level_stop();
clear_pause();
+ SDL_PauseAudio(0);
+ audio_music_stop();
return goto_state(&st_over);
}
int id, jd, title_id;
config_clr_grab();
-
- Mix_PauseMusic();
+ SDL_PauseAudio(1);
/* Build the pause GUI. */
game_step_fade(dt);
gui_timer(id, dt);
- audio_timer(dt);
}
static int play_ready_click(int b, int d)
game_step_fade(dt);
gui_timer(id, dt);
- audio_timer(dt);
}
static int play_set_click(int b, int d)
game_step_fade(dt);
demo_play_step(at);
- audio_timer(dt);
}
static void play_loop_point(int id, int x, int y, int dx, int dy)
void shared_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
/* Pulse, activate and return the active id (if changed)*/
}
gui_timer(id, dt);
- audio_timer(dt);
game_step_fade(dt);
}
# Get these from the /SDLMain/NIBless folder of the SDL devel extras found at http://www.libsdl.org/download-1.2.php.
# It will work only with MacPorts layout.
cp /opt/local/lib/libpng12.a /opt/local/lib/libintl.a /opt/local/lib/libiconv.a external_libs/.
+cp /opt/local/lib/libvorbis.a /opt/local/lib/libvorbisenc.a /opt/local/lib/libvorbisfile.a external_libs/.
+cp /opt/local/lib/libogg.a
cp /opt/local/include/libintl.h /opt/local/include/iconv.h external_libs/.
cp /opt/local/include/libpng12/png.h /opt/local/include/libpng12/pngconf.h external_libs/.
+cp /opt/local/include/vorbis/codec.h /opt/local/include/vorbis/vorbisenc.h /opt/local/include/vorbis/vorbisfile.h external_libs/.
+cp /opt/local/include/ogg/config_types.h /opt/local/include/ogg/ogg.h /opt/local/include/ogg/os_types.h external_libs/.
cp /opt/local/bin/msgfmt external_tools/.
\ No newline at end of file
8137FA130AEAE74D009172EC /* libintl.h in Headers */ = {isa = PBXBuildFile; fileRef = 8137F99D0AEAE105009172EC /* libintl.h */; };
8137FA140AEAE74E009172EC /* libintl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8137F99C0AEAE105009172EC /* libintl.a */; };
8137FA150AEAE75C009172EC /* SDL_ttf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 815F03F60AEAC72600AFD07F /* SDL_ttf.framework */; };
- 8137FA160AEAE762009172EC /* SDL_mixer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 815F03F20AEAC70A00AFD07F /* SDL_mixer.framework */; };
8137FA1B0AEAE77D009172EC /* SDL_ttf.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 815F03F60AEAC72600AFD07F /* SDL_ttf.framework */; };
- 8137FA1C0AEAE77D009172EC /* SDL_mixer.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 815F03F20AEAC70A00AFD07F /* SDL_mixer.framework */; };
8137FA280AEAE7E6009172EC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
8137FA440AEAE909009172EC /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2F67ED704C74A3F00A80002 /* OpenGL.framework */; };
8137FB120AEB07D4009172EC /* SDLMain.h in Headers */ = {isa = PBXBuildFile; fileRef = F5A47A9D01A0482F01D3D55B /* SDLMain.h */; };
8137FB130AEB07D7009172EC /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = F5A47A9E01A0483001D3D55B /* SDLMain.m */; };
8137FD0F0AEBE491009172EC /* libintl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8137F99C0AEAE105009172EC /* libintl.a */; };
- 8137FD100AEBE49A009172EC /* SDL_mixer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 815F03F20AEAC70A00AFD07F /* SDL_mixer.framework */; };
8137FD110AEBE4A3009172EC /* SDL_ttf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 815F03F60AEAC72600AFD07F /* SDL_ttf.framework */; };
8137FD120AEBE4A8009172EC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
8137FD3B0AEBE4AD009172EC /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2F67ED704C74A3F00A80002 /* OpenGL.framework */; };
815FFD150AEA356800AFD07F /* solid.h in Headers */ = {isa = PBXBuildFile; fileRef = 815FFBA30AEA2E0300AFD07F /* solid.h */; };
815FFD170AEA357600AFD07F /* binary.h in Headers */ = {isa = PBXBuildFile; fileRef = 815FFB840AEA2E0300AFD07F /* binary.h */; };
81D0B3F30AEE6C710041CE19 /* SDL_ttf.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 815F03F60AEAC72600AFD07F /* SDL_ttf.framework */; };
- 81D0B3F40AEE6C710041CE19 /* SDL_mixer.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 815F03F20AEAC70A00AFD07F /* SDL_mixer.framework */; };
81D0B3F50AEE6C710041CE19 /* SDL_image.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 815FFD030AEA341500AFD07F /* SDL_image.framework */; };
81D0B3F60AEE6C710041CE19 /* SDL.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 815FFCFD0AEA340300AFD07F /* SDL.framework */; };
B5117CE80C9060CB005837F9 /* st_pause.c in Sources */ = {isa = PBXBuildFile; fileRef = B5117CE60C9060CB005837F9 /* st_pause.c */; };
B5117CE90C9060CB005837F9 /* st_pause.h in Headers */ = {isa = PBXBuildFile; fileRef = B5117CE70C9060CB005837F9 /* st_pause.h */; };
- B511CD210D0E3A7300E99AE0 /* text.c in Sources */ = {isa = PBXBuildFile; fileRef = B511CD1F0D0E3A7300E99AE0 /* text.c */; };
- B511CD220D0E3A7300E99AE0 /* text.h in Headers */ = {isa = PBXBuildFile; fileRef = B511CD200D0E3A7300E99AE0 /* text.h */; };
- B511CD230D0E3A7300E99AE0 /* text.c in Sources */ = {isa = PBXBuildFile; fileRef = B511CD1F0D0E3A7300E99AE0 /* text.c */; };
- B511CD240D0E3A7300E99AE0 /* text.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B511CD200D0E3A7300E99AE0 /* text.h */; };
B5412EB90CA36ACD00C9A9F7 /* demo.h in Headers */ = {isa = PBXBuildFile; fileRef = 815FFC0E0AEA2EF600AFD07F /* demo.h */; };
B5412EBA0CA36AE000C9A9F7 /* demo.c in Sources */ = {isa = PBXBuildFile; fileRef = 815FFC0D0AEA2EF600AFD07F /* demo.c */; };
B5412EC20CA36C3C00C9A9F7 /* score.c in Sources */ = {isa = PBXBuildFile; fileRef = B5412EBE0CA36C3C00C9A9F7 /* score.c */; };
B5412EC30CA36C3C00C9A9F7 /* score.h in Headers */ = {isa = PBXBuildFile; fileRef = B5412EBF0CA36C3C00C9A9F7 /* score.h */; };
B5412EC40CA36C3C00C9A9F7 /* mode.c in Sources */ = {isa = PBXBuildFile; fileRef = B5412EC00CA36C3C00C9A9F7 /* mode.c */; };
B5412EC50CA36C3C00C9A9F7 /* mode.h in Headers */ = {isa = PBXBuildFile; fileRef = B5412EC10CA36C3C00C9A9F7 /* mode.h */; };
+ B5452B830D19C959000F8933 /* text.c in Sources */ = {isa = PBXBuildFile; fileRef = B5452B810D19C959000F8933 /* text.c */; };
+ B5452B840D19C959000F8933 /* text.h in Headers */ = {isa = PBXBuildFile; fileRef = B5452B820D19C959000F8933 /* text.h */; };
+ B5452B850D19C959000F8933 /* text.c in Sources */ = {isa = PBXBuildFile; fileRef = B5452B810D19C959000F8933 /* text.c */; };
+ B5452B860D19C959000F8933 /* text.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5452B820D19C959000F8933 /* text.h */; };
+ B5452B8D0D19CA83000F8933 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452B8C0D19CA83000F8933 /* libvorbis.a */; };
+ B5452B8E0D19CA83000F8933 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452B8C0D19CA83000F8933 /* libvorbis.a */; };
+ B5452B930D19CAFB000F8933 /* codec.h in Headers */ = {isa = PBXBuildFile; fileRef = B5452B900D19CAFB000F8933 /* codec.h */; };
+ B5452B940D19CAFB000F8933 /* vorbisenc.h in Headers */ = {isa = PBXBuildFile; fileRef = B5452B910D19CAFB000F8933 /* vorbisenc.h */; };
+ B5452B950D19CAFB000F8933 /* vorbisfile.h in Headers */ = {isa = PBXBuildFile; fileRef = B5452B920D19CAFB000F8933 /* vorbisfile.h */; };
+ B5452B960D19CAFB000F8933 /* codec.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5452B900D19CAFB000F8933 /* codec.h */; };
+ B5452B970D19CAFB000F8933 /* vorbisenc.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5452B910D19CAFB000F8933 /* vorbisenc.h */; };
+ B5452B980D19CAFB000F8933 /* vorbisfile.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5452B920D19CAFB000F8933 /* vorbisfile.h */; };
+ B5452B9E0D19CB9F000F8933 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452B9C0D19CB9F000F8933 /* libvorbisenc.a */; };
+ B5452B9F0D19CB9F000F8933 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452B9D0D19CB9F000F8933 /* libvorbisfile.a */; };
+ B5452BA00D19CB9F000F8933 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452B9C0D19CB9F000F8933 /* libvorbisenc.a */; };
+ B5452BA10D19CB9F000F8933 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452B9D0D19CB9F000F8933 /* libvorbisfile.a */; };
+ B5452BA70D19CBDC000F8933 /* config_types.h in Headers */ = {isa = PBXBuildFile; fileRef = B5452BA30D19CBDC000F8933 /* config_types.h */; };
+ B5452BA80D19CBDC000F8933 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452BA40D19CBDC000F8933 /* libogg.a */; };
+ B5452BA90D19CBDC000F8933 /* ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = B5452BA50D19CBDC000F8933 /* ogg.h */; };
+ B5452BAA0D19CBDC000F8933 /* os_types.h in Headers */ = {isa = PBXBuildFile; fileRef = B5452BA60D19CBDC000F8933 /* os_types.h */; };
+ B5452BAB0D19CBDC000F8933 /* config_types.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5452BA30D19CBDC000F8933 /* config_types.h */; };
+ B5452BAC0D19CBDC000F8933 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5452BA40D19CBDC000F8933 /* libogg.a */; };
+ B5452BAD0D19CBDC000F8933 /* ogg.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5452BA50D19CBDC000F8933 /* ogg.h */; };
+ B5452BAE0D19CBDC000F8933 /* os_types.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5452BA60D19CBDC000F8933 /* os_types.h */; };
B549682A0C964EBF004309DA /* lang.h in Headers */ = {isa = PBXBuildFile; fileRef = B54968290C964EBF004309DA /* lang.h */; };
B549682C0C964ED3004309DA /* lang.c in Sources */ = {isa = PBXBuildFile; fileRef = B549682B0C964ED3004309DA /* lang.c */; };
B56171BB0C96BABD00FE88EE /* lang.c in Sources */ = {isa = PBXBuildFile; fileRef = B549682B0C964ED3004309DA /* lang.c */; };
dstSubfolderSpec = 10;
files = (
8137FA1B0AEAE77D009172EC /* SDL_ttf.framework in CopyFiles */,
- 8137FA1C0AEAE77D009172EC /* SDL_mixer.framework in CopyFiles */,
815F02EE0AEA8B8100AFD07F /* SDL_image.framework in CopyFiles */,
815F02EF0AEA8B8100AFD07F /* SDL.framework in CopyFiles */,
);
files = (
81D0B3F60AEE6C710041CE19 /* SDL.framework in CopyFiles */,
81D0B3F30AEE6C710041CE19 /* SDL_ttf.framework in CopyFiles */,
- 81D0B3F40AEE6C710041CE19 /* SDL_mixer.framework in CopyFiles */,
81D0B3F50AEE6C710041CE19 /* SDL_image.framework in CopyFiles */,
- B511CD240D0E3A7300E99AE0 /* text.h in CopyFiles */,
+ B5452B860D19C959000F8933 /* text.h in CopyFiles */,
+ B5452B960D19CAFB000F8933 /* codec.h in CopyFiles */,
+ B5452B970D19CAFB000F8933 /* vorbisenc.h in CopyFiles */,
+ B5452B980D19CAFB000F8933 /* vorbisfile.h in CopyFiles */,
+ B5452BAB0D19CBDC000F8933 /* config_types.h in CopyFiles */,
+ B5452BAD0D19CBDC000F8933 /* ogg.h in CopyFiles */,
+ B5452BAE0D19CBDC000F8933 /* os_types.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8137FD630AEBE54F009172EC /* st_conf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = st_conf.c; sourceTree = "<group>"; };
8137FD640AEBE54F009172EC /* st_conf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = st_conf.h; sourceTree = "<group>"; };
815F03A70AEA8CB400AFD07F /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
- 815F03F20AEAC70A00AFD07F /* SDL_mixer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_mixer.framework; path = /Library/Frameworks/SDL_mixer.framework; sourceTree = "<absolute>"; };
815F03F60AEAC72600AFD07F /* SDL_ttf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_ttf.framework; path = /Library/Frameworks/SDL_ttf.framework; sourceTree = "<absolute>"; };
815FFB720AEA2E0300AFD07F /* audio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = "<group>"; };
815FFB740AEA2E0300AFD07F /* audio.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
B5117CDE0C906001005837F9 /* VeraBd.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = VeraBd.ttf; sourceTree = "<group>"; };
B5117CE60C9060CB005837F9 /* st_pause.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = st_pause.c; sourceTree = "<group>"; };
B5117CE70C9060CB005837F9 /* st_pause.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = st_pause.h; sourceTree = "<group>"; };
- B511CD1F0D0E3A7300E99AE0 /* text.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = text.c; sourceTree = "<group>"; };
- B511CD200D0E3A7300E99AE0 /* text.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
B5412DD80CA36A6700C9A9F7 /* arrow */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = arrow; sourceTree = "<group>"; };
B5412DD90CA36A6700C9A9F7 /* arrow-dark */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "arrow-dark"; sourceTree = "<group>"; };
B5412DDA0CA36A6700C9A9F7 /* arrow-dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow-dark.png"; sourceTree = "<group>"; };
B5412EBF0CA36C3C00C9A9F7 /* score.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = score.h; sourceTree = "<group>"; };
B5412EC00CA36C3C00C9A9F7 /* mode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mode.c; sourceTree = "<group>"; };
B5412EC10CA36C3C00C9A9F7 /* mode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mode.h; sourceTree = "<group>"; };
+ B5452B810D19C959000F8933 /* text.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = text.c; sourceTree = "<group>"; };
+ B5452B820D19C959000F8933 /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
+ B5452B8C0D19CA83000F8933 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libvorbis.a; sourceTree = "<group>"; };
+ B5452B900D19CAFB000F8933 /* codec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = codec.h; sourceTree = "<group>"; };
+ B5452B910D19CAFB000F8933 /* vorbisenc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbisenc.h; sourceTree = "<group>"; };
+ B5452B920D19CAFB000F8933 /* vorbisfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbisfile.h; sourceTree = "<group>"; };
+ B5452B9C0D19CB9F000F8933 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libvorbisenc.a; sourceTree = "<group>"; };
+ B5452B9D0D19CB9F000F8933 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libvorbisfile.a; sourceTree = "<group>"; };
+ B5452BA30D19CBDC000F8933 /* config_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config_types.h; sourceTree = "<group>"; };
+ B5452BA40D19CBDC000F8933 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libogg.a; sourceTree = "<group>"; };
+ B5452BA50D19CBDC000F8933 /* ogg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ogg.h; sourceTree = "<group>"; };
+ B5452BA60D19CBDC000F8933 /* os_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = os_types.h; sourceTree = "<group>"; };
B54968290C964EBF004309DA /* lang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lang.h; sourceTree = "<group>"; };
B549682B0C964ED3004309DA /* lang.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lang.c; sourceTree = "<group>"; };
B568EAF50C96BE83006D5E93 /* dmg-background.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "dmg-background.jpg"; sourceTree = "<group>"; };
8137FD0F0AEBE491009172EC /* libintl.a in Frameworks */,
815FFD000AEA340300AFD07F /* SDL.framework in Frameworks */,
815FFD060AEA341500AFD07F /* SDL_image.framework in Frameworks */,
- 8137FD100AEBE49A009172EC /* SDL_mixer.framework in Frameworks */,
8137FD110AEBE4A3009172EC /* SDL_ttf.framework in Frameworks */,
8137FD120AEBE4A8009172EC /* Cocoa.framework in Frameworks */,
8137FD3B0AEBE4AD009172EC /* OpenGL.framework in Frameworks */,
+ B5452B8E0D19CA83000F8933 /* libvorbis.a in Frameworks */,
+ B5452BA00D19CB9F000F8933 /* libvorbisenc.a in Frameworks */,
+ B5452BA10D19CB9F000F8933 /* libvorbisfile.a in Frameworks */,
+ B5452BAC0D19CBDC000F8933 /* libogg.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8137FA140AEAE74E009172EC /* libintl.a in Frameworks */,
815FFCFF0AEA340300AFD07F /* SDL.framework in Frameworks */,
815FFD050AEA341500AFD07F /* SDL_image.framework in Frameworks */,
- 8137FA160AEAE762009172EC /* SDL_mixer.framework in Frameworks */,
8137FA150AEAE75C009172EC /* SDL_ttf.framework in Frameworks */,
8137FA280AEAE7E6009172EC /* Cocoa.framework in Frameworks */,
8137FA440AEAE909009172EC /* OpenGL.framework in Frameworks */,
+ B5452B8D0D19CA83000F8933 /* libvorbis.a in Frameworks */,
+ B5452B9E0D19CB9F000F8933 /* libvorbisenc.a in Frameworks */,
+ B5452B9F0D19CB9F000F8933 /* libvorbisfile.a in Frameworks */,
+ B5452BA80D19CBDC000F8933 /* libogg.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXGroup;
children = (
815F03F60AEAC72600AFD07F /* SDL_ttf.framework */,
- 815F03F20AEAC70A00AFD07F /* SDL_mixer.framework */,
815F03A70AEA8CB400AFD07F /* AppKit.framework */,
815FFDE70AEA3B8A00AFD07F /* CoreFoundation.framework */,
815FFD030AEA341500AFD07F /* SDL_image.framework */,
8137F99B0AEAE105009172EC /* external_libs */ = {
isa = PBXGroup;
children = (
+ B5452BA30D19CBDC000F8933 /* config_types.h */,
+ B5452BA40D19CBDC000F8933 /* libogg.a */,
+ B5452BA50D19CBDC000F8933 /* ogg.h */,
+ B5452BA60D19CBDC000F8933 /* os_types.h */,
+ B5452B9C0D19CB9F000F8933 /* libvorbisenc.a */,
+ B5452B9D0D19CB9F000F8933 /* libvorbisfile.a */,
+ B5452B900D19CAFB000F8933 /* codec.h */,
+ B5452B910D19CAFB000F8933 /* vorbisenc.h */,
+ B5452B920D19CAFB000F8933 /* vorbisfile.h */,
+ B5452B8C0D19CA83000F8933 /* libvorbis.a */,
B5C41C040C905BB800C19E20 /* iconv.h */,
B5C41BFE0C905AC400C19E20 /* libiconv.a */,
8137F99D0AEAE105009172EC /* libintl.h */,
815FFB710AEA2E0300AFD07F /* share */ = {
isa = PBXGroup;
children = (
- B511CD1F0D0E3A7300E99AE0 /* text.c */,
- B511CD200D0E3A7300E99AE0 /* text.h */,
+ B5452B810D19C959000F8933 /* text.c */,
+ B5452B820D19C959000F8933 /* text.h */,
815FFB720AEA2E0300AFD07F /* audio.c */,
815FFB740AEA2E0300AFD07F /* audio.h */,
815FFB760AEA2E0300AFD07F /* back.c */,
B57D63D20CAE8138005DE710 /* st_fall_out.h in Headers */,
B57D63D30CAE8138005DE710 /* st_time_out.h in Headers */,
B57D63D50CAE8138005DE710 /* st_goal.h in Headers */,
- B511CD220D0E3A7300E99AE0 /* text.h in Headers */,
+ B5452B840D19C959000F8933 /* text.h in Headers */,
+ B5452B930D19CAFB000F8933 /* codec.h in Headers */,
+ B5452B940D19CAFB000F8933 /* vorbisenc.h in Headers */,
+ B5452B950D19CAFB000F8933 /* vorbisfile.h in Headers */,
+ B5452BA70D19CBDC000F8933 /* config_types.h in Headers */,
+ B5452BA90D19CBDC000F8933 /* ogg.h in Headers */,
+ B5452BAA0D19CBDC000F8933 /* os_types.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8137FD690AEBE54F009172EC /* main.c in Sources */,
8137FD6A0AEBE54F009172EC /* st_all.c in Sources */,
8137FD6B0AEBE54F009172EC /* st_conf.c in Sources */,
- B511CD230D0E3A7300E99AE0 /* text.c in Sources */,
+ B5452B850D19C959000F8933 /* text.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B57D63D10CAE8138005DE710 /* st_goal.c in Sources */,
B57D63D40CAE8138005DE710 /* st_time_out.c in Sources */,
B57D63D60CAE8138005DE710 /* st_fall_out.c in Sources */,
- B511CD210D0E3A7300E99AE0 /* text.c in Sources */,
+ B5452B830D19C959000F8933 /* text.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL_mixer.framework/Versions/A/Headers",
"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL_ttf.framework/Versions/A/Headers",
);
+ LIBRARY_SEARCH_PATHS = (
+ /opt/local/lib,
+ "$(inherited)",
+ );
MACOSX_DEPLOYMENT_TARGET = 10.4;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ USER_HEADER_SEARCH_PATHS = "/opt/local/include $(inherited)";
WARNING_CFLAGS = (
"-Wall",
"-pedantic",
GCC_WARN_UNUSED_PARAMETER = NO;
GCC_WARN_UNUSED_VARIABLE = NO;
HEADER_SEARCH_PATHS = "";
+ LIBRARY_SEARCH_PATHS = (
+ /opt/local/lib,
+ "$(inherited)",
+ );
MACOSX_DEPLOYMENT_TARGET = 10.4;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ USER_HEADER_SEARCH_PATHS = "/opt/local/include $(inherited)";
WARNING_CFLAGS = (
"-Wall",
"-pedantic",
--- /dev/null
+# This makefile only exists so that I can run emacs M-x compile from within
+# the source directory. See the Makefile in the parent directory
+
+all :
+ (cd ..; $(MAKE))
+
+clean :
+ (cd ..; $(MAKE) clean)
+
+test :
+ (cd ..; $(MAKE) clean)
/*---------------------------------------------------------------------------*/
-#define AUD_BIRDIE 0
-#define AUD_BOGEY 1
-#define AUD_BUMP 2
-#define AUD_DOUBLE 3
-#define AUD_EAGLE 4
-#define AUD_JUMP 5
-#define AUD_MENU 6
-#define AUD_ONE 7
-#define AUD_PAR 8
-#define AUD_PENALTY 9
-#define AUD_PLAYER1 10
-#define AUD_PLAYER2 11
-#define AUD_PLAYER3 12
-#define AUD_PLAYER4 13
-#define AUD_SUCCESS 14
-#define AUD_SWITCH 15
-#define AUD_COUNT 16
+#define AUD_BIRDIE "snd/birdie.ogg"
+#define AUD_BOGEY "snd/bogey.ogg"
+#define AUD_BUMP "snd/bink.ogg"
+#define AUD_DOUBLE "snd/double.ogg"
+#define AUD_EAGLE "snd/eagle.ogg"
+#define AUD_JUMP "snd/jump.ogg"
+#define AUD_MENU "snd/menu.ogg"
+#define AUD_ONE "snd/one.ogg"
+#define AUD_PAR "snd/par.ogg"
+#define AUD_PENALTY "snd/penalty.ogg"
+#define AUD_PLAYER1 "snd/player1.ogg"
+#define AUD_PLAYER2 "snd/player2.ogg"
+#define AUD_PLAYER3 "snd/player3.ogg"
+#define AUD_PLAYER4 "snd/player4.ogg"
+#define AUD_SWITCH "snd/switch.ogg"
+#define AUD_SUCCESS "snd/success.ogg"
/*---------------------------------------------------------------------------*/
/* Initialize the audio. */
- audio_bind(AUD_BIRDIE, 1, "snd/birdie.ogg");
- audio_bind(AUD_BOGEY, 1, "snd/bogey.ogg");
- audio_bind(AUD_BUMP, 1, "snd/bink.wav");
- audio_bind(AUD_DOUBLE, 1, "snd/double.ogg");
- audio_bind(AUD_EAGLE, 1, "snd/eagle.ogg");
- audio_bind(AUD_JUMP, 2, "snd/jump.ogg");
- audio_bind(AUD_MENU, 2, "snd/menu.wav");
- audio_bind(AUD_ONE, 1, "snd/one.ogg");
- audio_bind(AUD_PAR, 1, "snd/par.ogg");
- audio_bind(AUD_PENALTY, 1, "snd/penalty.ogg");
- audio_bind(AUD_PLAYER1, 1, "snd/player1.ogg");
- audio_bind(AUD_PLAYER2, 1, "snd/player2.ogg");
- audio_bind(AUD_PLAYER3, 1, "snd/player3.ogg");
- audio_bind(AUD_PLAYER4, 1, "snd/player4.ogg");
- audio_bind(AUD_SWITCH, 2, "snd/switch.wav");
- audio_bind(AUD_SUCCESS, 1, "snd/success.ogg");
-
audio_init();
/* Require 16-bit double buffer with 16-bit depth buffer. */
game_set_fly(fcosf(time_state() / 10.f));
gui_timer(id, dt);
- audio_timer(dt);
}
static void title_point(int id, int x, int y, int dx, int dy)
static void course_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static void course_point(int id, int x, int y, int dx, int dy)
static void party_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static void party_point(int id, int x, int y, int dx, int dy)
static void pause_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static void pause_point(int id, int x, int y, int dx, int dy)
static void next_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static void next_point(int id, int x, int y, int dx, int dy)
game_set_fly(1.f - t);
gui_timer(id, dt);
- audio_timer(dt);
}
static int flyby_click(int b, int d)
game_update_view(dt);
game_step(g, dt);
- audio_timer(dt);
}
static void stroke_point(int id, int x, int y, int dx, int dy)
case GAME_GOAL: goto_state(&st_goal); break;
case GAME_FALL: goto_state(&st_fall); break;
}
- audio_timer(dt);
}
static int roll_buttn(int b, int d)
else
goto_state(&st_score);
}
- audio_timer(dt);
}
static int goal_click(int b, int d)
game_update_view(dt);
game_step(g, dt);
- audio_timer(dt);
if (time_state() > 1)
{
else
goto_state(&st_score);
}
- audio_timer(dt);
}
static int fall_click(int b, int d)
static void score_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static int score_click(int b, int d)
static void over_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static int over_click(int b, int d)
static void conf_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static void conf_point(int id, int x, int y, int dx, int dy)
--- /dev/null
+# This makefile only exists so that I can run emacs M-x compile from within
+# the source directory. See the Makefile in the parent directory
+
+all :
+ (cd ..; $(MAKE))
+
+clean :
+ (cd ..; $(MAKE) clean)
+
+test :
+ (cd ..; $(MAKE) clean)
*/
#include <SDL.h>
-#include <SDL_mixer.h>
+
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
#include <string.h>
#include "text.h"
/*---------------------------------------------------------------------------*/
-static int audio_state = 0;
-
-static char name[MAXSND][MAXSTR];
-static int chan[MAXSND];
-static Mix_Chunk *buff[MAXSND];
-static Mix_Music *song;
+#define AUDIO_RATE 44100
+#define AUDIO_CHAN 2
-static char curr_bgm[MAXSTR];
-static char next_bgm[MAXSTR];
-
-static float fade_volume = 1.0f;
-static float fade_rate = 0.0f;
+struct voice
+{
+ OggVorbis_File vf;
+ float amp;
+ float damp;
+ int chan;
+ int play;
+ int loop;
+ char *name;
+ struct voice *next;
+};
+
+static int audio_state = 0;
+static float sound_vol = 1.0f;
+static float music_vol = 1.0f;
+
+static SDL_AudioSpec spec;
+
+static struct voice *music = NULL;
+static struct voice *queue = NULL;
+static struct voice *voices = NULL;
+static short *buffer = NULL;
/*---------------------------------------------------------------------------*/
-void audio_init(void)
+#define MIX(d, s) { \
+ int n = (int) (d) + (int) (s); \
+ if (n > 32767) (d) = 32767; \
+ else if (n < -32768) (d) = -32768; \
+ else (d) = (short) n; \
+ }
+
+static int voice_step(struct voice *V, float volume, Uint8 *stream, int length)
{
- int r = config_get_d(CONFIG_AUDIO_RATE);
- int b = config_get_d(CONFIG_AUDIO_BUFF);
- int i;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ int order = 1;
+#else
+ int order = 0;
+#endif
+
+ short *obuf = (short *) stream;
+ char *ibuf = (char *) buffer;
- memset(curr_bgm, 0, MAXSTR);
- memset(next_bgm, 0, MAXSTR);
+ int i, b = 0, n = 1, c = 0, r = 0;
- if (audio_state == 0)
+ /* Compute the total request size for the current stream. */
+
+ if (V->chan == 1) r = length / 2;
+ if (V->chan == 2) r = length ;
+
+ /* While data is coming in and data is still needed... */
+
+ while (n > 0 && r > 0)
{
- if (Mix_OpenAudio(r, MIX_DEFAULT_FORMAT, 2, b) == 0)
+ /* Read audio from the stream. */
+
+ if ((n = (int) ov_read(&V->vf, ibuf, r, order, 2, 1, &b)) > 0)
{
- for (i = 0; i < MAXSND; i++)
- if (chan[i])
- buff[i] = Mix_LoadWAV(config_data(name[i]));
+ /* Mix mono audio. */
- audio_state = 1;
+ if (V->chan == 1)
+ for (i = 0; i < n / 2; i += 1)
+ {
+ short M = (short) (V->amp * volume * buffer[i]);
+
+ MIX(obuf[c], M); c++;
+ MIX(obuf[c], M); c++;
+
+ V->amp += V->damp;
+
+ if (V->amp < 0.0) V->amp = 0.0;
+ if (V->amp > 1.0) V->amp = 1.0;
+ }
- audio_volume(config_get_d(CONFIG_SOUND_VOLUME),
- config_get_d(CONFIG_MUSIC_VOLUME));
+ /* Mix stereo audio. */
+
+ if (V->chan == 2)
+ for (i = 0; i < n / 2; i += 2)
+ {
+ short L = (short) (V->amp * volume * buffer[i + 0]);
+ short R = (short) (V->amp * volume * buffer[i + 1]);
+
+ MIX(obuf[c], L); c++;
+ MIX(obuf[c], R); c++;
+
+ V->amp += V->damp;
+
+ if (V->amp < 0.0) V->amp = 0.0;
+ if (V->amp > 1.0) V->amp = 1.0;
+ }
+
+ r -= n;
}
else
{
- fprintf(stderr, L_("Sound disabled\n"));
- audio_state = 0;
+ /* We're at EOF. Loop or end the voice. */
+
+ if (V->loop)
+ {
+ ov_raw_seek(&V->vf, 0);
+ n = 1;
+ }
+ else return 1;
}
}
+ return 0;
}
-void audio_free(void)
+static struct voice *voice_init(const char *filename, float a)
{
- int i;
+ struct voice *V;
+ FILE *fp;
+
+ /* Allocate and initialize a new voice structure. */
- if (audio_state == 1)
+ if ((V = (struct voice *) calloc(1, sizeof (struct voice))))
{
- for (i = 0; i < MAXSND; i++)
- if (buff[i])
+ /* Note the name. */
+
+ V->name = (char *) malloc(strlen(filename) + 1);
+
+ strcpy(V->name, filename);
+
+ /* Attempt to open the named Ogg stream. */
+
+ if ((fp = fopen(config_data(filename), FMODE_RB)))
+ {
+ if (ov_open(fp, &V->vf, NULL, 0) == 0)
{
- Mix_FreeChunk(buff[i]);
+ vorbis_info *info = ov_info(&V->vf, -1);
+
+ /* On success, configure the voice. */
- buff[i] = NULL;
- }
+ V->amp = a;
+ V->damp = 0;
+ V->chan = info->channels;
+ V->play = 1;
+ V->loop = 0;
- Mix_CloseAudio();
- audio_state = 0;
+ if (V->amp > 1.0) V->amp = 1.0;
+ if (V->amp < 0.0) V->amp = 0.0;
+
+ /* The file will be closed when the Ogg is cleared. */
+ }
+ else fclose(fp);
+ }
}
+ return V;
}
-void audio_bind(int i, int c, const char *filename)
+static void voice_free(struct voice *V)
{
- strncpy(name[i], filename, MAXSTR);
- chan[i] = c;
+ ov_clear(&V->vf);
+
+ free(V->name);
+ free(V);
}
-void audio_play(int i, float v)
+/*---------------------------------------------------------------------------*/
+
+static void audio_step(void *data, Uint8 *stream, int length)
{
- if (audio_state == 1 && buff[i])
+ struct voice *V = voices;
+ struct voice *P = NULL;
+
+ /* Zero the output buffer. */
+
+ memset(stream, 0, length);
+
+ /* Mix the background music. */
+
+ if (music)
+ {
+ voice_step(music, music_vol, stream, length);
+
+ /* If the track has faded out, move to a queued track. */
+
+ if (music->amp <= 0.0f && music->damp < 0.0f && queue)
+ {
+ voice_free(music);
+ music = queue;
+ queue = NULL;
+ }
+ }
+
+ /* Iterate over all active voices. */
+
+ while (V)
{
- Mix_VolumeChunk(buff[i], (int) (v * MIX_MAX_VOLUME));
- Mix_PlayChannel(chan[i], buff[i], 0);
+ /* Mix this voice. */
+
+ if (V->play && voice_step(V, sound_vol, stream, length))
+ {
+ /* Delete a finished voice... */
+
+ struct voice *T = V;
+
+ if (P)
+ V = P->next = V->next;
+ else
+ V = voices = V->next;
+
+ voice_free(T);
+ }
+ else
+ {
+ /* ... or continue to the next. */
+
+ P = V;
+ V = V->next;
+ }
}
}
/*---------------------------------------------------------------------------*/
-void audio_music_play(const char *filename)
+void audio_init(void)
{
- if (audio_state)
+ audio_state = 0;
+
+ /* Configure the audio. */
+
+ spec.format = AUDIO_S16SYS;
+ spec.channels = AUDIO_CHAN;
+ spec.samples = config_get_d(CONFIG_AUDIO_BUFF);
+ spec.freq = AUDIO_RATE;
+ spec.callback = audio_step;
+
+ /* Allocate an input buffer. */
+
+ if ((buffer = (short *) malloc(spec.samples * 4)))
{
- audio_music_stop();
+ /* Start the audio thread. */
- if ((config_get_d(CONFIG_MUSIC_VOLUME) > 0) &&
- (song = Mix_LoadMUS(config_data(filename))))
+ if (SDL_OpenAudio(&spec, NULL) == 0)
{
- Mix_PlayMusic(song, -1);
- strcpy(curr_bgm, filename);
+ audio_state = 1;
+ SDL_PauseAudio(0);
}
+ else fprintf(stderr, "%s\n", SDL_GetError());
}
+
+ /* Set the initial volumes. */
+
+ audio_volume(config_get_d(CONFIG_SOUND_VOLUME),
+ config_get_d(CONFIG_MUSIC_VOLUME));
}
-void audio_music_queue(const char *filename)
+void audio_free(void)
{
- if (audio_state)
- {
- if (strlen(curr_bgm) == 0 || strcmp(filename, curr_bgm) != 0)
- {
- Mix_VolumeMusic(0);
- fade_volume = 0.0f;
+ /* Halt the audio thread. */
- audio_music_play(filename);
- strcpy(curr_bgm, filename);
+ SDL_CloseAudio();
- Mix_PauseMusic();
- }
- }
+ /* Release the input buffer. */
+
+ free(buffer);
+
+ /* Ogg streams and voice structure remain open to allow quality setting. */
}
-void audio_music_stop(void)
+void audio_play(const char *filename, float a)
{
if (audio_state)
{
- if (Mix_PlayingMusic())
- Mix_HaltMusic();
+ struct voice *V;
+
+ /* If we're already playing this sound, preempt the running copy. */
+
+ for (V = voices; V; V = V->next)
+ if (strcmp(V->name, filename) == 0)
+ {
+ ov_raw_seek(&V->vf, 0);
+
+ V->amp = a;
+
+ if (V->amp > 1.0) V->amp = 1.0;
+ if (V->amp < 0.0) V->amp = 0.0;
+
+ return;
+ }
+
+ /* Create a new voice structure. */
- if (song)
- Mix_FreeMusic(song);
+ V = voice_init(filename, a);
- song = NULL;
+ /* Add it to the list of sounding voices. */
+
+ SDL_LockAudio();
+ {
+ V->next = voices;
+ voices = V;
+ }
+ SDL_UnlockAudio();
}
}
/*---------------------------------------------------------------------------*/
-/*
- * SDL_mixer already provides music fading. Unfortunately, it halts playback
- * at the end of a fade. We need to be able to fade music back in from the
- * point where it stopped. So, we reinvent this wheel.
- */
-void audio_timer(float dt)
+void audio_music_play(const char *filename)
{
if (audio_state)
{
- if (fade_rate > 0.0f || fade_rate < 0.0f)
- fade_volume += dt / fade_rate;
+ audio_music_stop();
- if (fade_volume < 0.0f)
+ SDL_LockAudio();
{
- fade_volume = 0.0f;
-
- if (strlen(next_bgm) == 0)
+ if ((music = voice_init(filename, 0.0f)))
{
- fade_rate = 0.0f;
- if (Mix_PlayingMusic())
- Mix_PauseMusic();
+ music->loop = 1;
}
- else
+ }
+ SDL_UnlockAudio();
+ }
+}
+
+void audio_music_queue(const char *filename)
+{
+ if (audio_state)
+ {
+ SDL_LockAudio();
+ {
+ if ((queue = voice_init(filename, 0.0f)))
{
- fade_rate = -fade_rate;
- audio_music_queue(next_bgm);
+ queue->loop = 1;
}
}
+ SDL_UnlockAudio();
+ }
+}
- if (fade_volume > 1.0f)
+void audio_music_stop(void)
+{
+ if (audio_state)
+ {
+ SDL_LockAudio();
{
- fade_rate = 0.0f;
- fade_volume = 1.0f;
+ if (music)
+ {
+ voice_free(music);
+ }
+ music = NULL;
}
-
- if (Mix_PausedMusic() && fade_rate > 0.0f)
- Mix_ResumeMusic();
-
- if (Mix_PlayingMusic())
- Mix_VolumeMusic(config_get_d(CONFIG_MUSIC_VOLUME) *
- (int) (fade_volume * MIX_MAX_VOLUME) / 10);
+ SDL_UnlockAudio();
}
}
+/*---------------------------------------------------------------------------*/
+
void audio_music_fade_out(float t)
{
- fade_rate = -t;
- strcpy(next_bgm, "");
+ SDL_LockAudio();
+ {
+ if (music) music->damp = -1.0f / (AUDIO_RATE * t);
+ }
+ SDL_UnlockAudio();
}
void audio_music_fade_in(float t)
{
- fade_rate = +t;
- strcpy(next_bgm, "");
+ SDL_LockAudio();
+ {
+ if (music) music->damp = +1.0f / (AUDIO_RATE * t);
+ }
+ SDL_UnlockAudio();
}
void audio_music_fade_to(float t, const char *filename)
{
- if (fade_volume > 0)
+ if (music)
{
- if (strlen(curr_bgm) == 0 || strcmp(filename, curr_bgm) != 0)
+ if (strcmp(filename, music->name))
{
- strcpy(next_bgm, filename);
- fade_rate = -t;
+ audio_music_queue(filename);
+ audio_music_fade_out(t);
+
+ if (queue) queue->damp = +1.0f / (AUDIO_RATE * t);
}
- else fade_rate = t;
+ else audio_music_fade_in(t);
}
else
{
- audio_music_queue(filename);
+ audio_music_play(filename);
audio_music_fade_in(t);
}
}
void audio_volume(int s, int m)
{
- if (audio_state)
- {
- Mix_Volume(-1, s * MIX_MAX_VOLUME / 10);
- Mix_VolumeMusic(m * MIX_MAX_VOLUME / 10);
- }
+ sound_vol = (float) s / 10.0f;
+ music_vol = (float) m / 10.0f;
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
-#define MAXSND 32
-
void audio_init(void);
void audio_free(void);
-void audio_bind(int, int, const char *);
-void audio_play(int, float);
+void audio_play(const char *, float);
void audio_music_queue(const char *);
void audio_music_play(const char *);
static void resol_timer(int id, float dt)
{
gui_timer(id, dt);
- audio_timer(dt);
}
static void resol_point(int id, int x, int y, int dx, int dy)