diff --git a/.gitmodules b/.gitmodules index db49e0a56..26741ce44 100644 --- a/.gitmodules +++ b/.gitmodules @@ -42,3 +42,7 @@ [submodule "lib/usb/libusbohci"] path = lib/usb/libusbohci url = https://github.com/XboxDev/libusbohci.git +[submodule "lib/sdl/SDL_mixer"] + path = lib/sdl/SDL_mixer + url = https://github.com/PaulMDemers/SDL_mixer.git + branch = nxdk-sdl-mixer diff --git a/README.md b/README.md index da55de532..41d63f5ac 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Notable features: - No complicated cross-compiling or big library dependencies! Builds with `make` and just needs standard tools and llvm. - Modern C / C++ standards and compiler features. - Supports popular APIs like Windows API and BSD sockets. -- SDL2 support for input, audio and 2D graphics. +- SDL2 support for input, audio, optional audio mixing, and 2D graphics. - Custom API for 3D graphics using NVIDIA-designed shader-languages (with additional Xbox extensions). - Open-Source drivers which can be modified to get the most out of the hardware. - Modifiable startup code, for as much system control as necessary. @@ -46,6 +46,9 @@ Next Steps ---------- Copy one of the sample directories to get started. You can copy it anywhere you like. Run nxdk's activation script `bin/activate`, then, in the directory of your program, you can simply run `make`. +SDL_mixer is optional. Projects that use it should set `NXDK_SDL_MIXER = y` in +their Makefile alongside `NXDK_SDL = y`. + Credits ------- - [OpenXDK](https://web.archive.org/web/20170624051336/http://openxdk.sourceforge.net:80/) is the inspiration for nxdk, and large parts of it have been reused. (License: MIT) @@ -64,7 +67,7 @@ Code Overview * `lib/net` - Network stack for the Xbox based on lwIP. * `lib/pdclib` - Xbox port of PDCLib, a CC0-licensed C standard library. * `lib/pbkit` - A low level library for interfacing with the Xbox GPU. -* `lib/sdl` - Xbox ports of SDL2 and SDL_ttf. +* `lib/sdl` - Xbox ports of SDL2, SDL_image, optional SDL_mixer, and SDL_ttf. * `lib/usb` - USB support from OpenXDK. Hacked together parts of an old Linux OHCI stack. * `lib/winapi` - Xbox specific implementations of common useful WinAPI-functions. * `lib/xboxkrnl` - Header and import library for interfacing with the Xbox kernel. diff --git a/lib/pkgconfig/SDL2_mixer.pc b/lib/pkgconfig/SDL2_mixer.pc new file mode 100644 index 000000000..8fbf663f1 --- /dev/null +++ b/lib/pkgconfig/SDL2_mixer.pc @@ -0,0 +1,6 @@ +Name: SDL2_mixer +Description: audio mixer library for Simple DirectMedia Layer +Version: 2.0.4 +Requires: sdl2 >= 2.0.9 +Libs: -l${NXDK_DIR}/lib/libSDL2_mixer.lib +Cflags: -I${NXDK_DIR}/lib/sdl/SDL_mixer diff --git a/lib/sdl/Makefile b/lib/sdl/Makefile index b0328c326..97ed19807 100644 --- a/lib/sdl/Makefile +++ b/lib/sdl/Makefile @@ -74,3 +74,33 @@ CLEANRULES += clean-libsdlimage .PHONY: clean-libsdlimage clean-libsdlimage: $(VE)rm -f $(LIBSDLIMAGE_OBJS) $(NXDK_DIR)/lib/libSDL2_image.lib + +SDLMIXER_DIR = $(NXDK_DIR)/lib/sdl/SDL_mixer + +ifneq ($(NXDK_SDL_MIXER),) + +SDLMIXER_SRCS = $(SDLMIXER_DIR)/effect_position.c \ + $(SDLMIXER_DIR)/effect_stereoreverse.c \ + $(SDLMIXER_DIR)/effects_internal.c \ + $(SDLMIXER_DIR)/load_aiff.c \ + $(SDLMIXER_DIR)/load_voc.c \ + $(SDLMIXER_DIR)/mixer.c \ + $(SDLMIXER_DIR)/music.c \ + $(SDLMIXER_DIR)/music_wav.c + +SDLMIXER_OBJS = $(addsuffix .obj, $(basename $(SDLMIXER_SRCS))) + +NXDK_CFLAGS += -I$(SDLMIXER_DIR) -DMUSIC_WAV +NXDK_CXXFLAGS += -I$(SDLMIXER_DIR) -DMUSIC_WAV + +$(NXDK_DIR)/lib/libSDL2_mixer.lib: $(SDLMIXER_OBJS) + +main.exe: $(NXDK_DIR)/lib/libSDL2_mixer.lib + +CLEANRULES += clean-sdlmixer + +.PHONY: clean-sdlmixer +clean-sdlmixer: + $(VE)rm -f $(SDLMIXER_OBJS) $(NXDK_DIR)/lib/libSDL2_mixer.lib + +endif diff --git a/lib/sdl/SDL_mixer b/lib/sdl/SDL_mixer new file mode 160000 index 000000000..e5e4b187c --- /dev/null +++ b/lib/sdl/SDL_mixer @@ -0,0 +1 @@ +Subproject commit e5e4b187c9ab498405e091535c07af1c73376687 diff --git a/samples/sdl_mixer/Makefile b/samples/sdl_mixer/Makefile new file mode 100644 index 000000000..c462fdf77 --- /dev/null +++ b/samples/sdl_mixer/Makefile @@ -0,0 +1,19 @@ +XBE_TITLE = nxdk\ sample\ -\ SDL2_mixer +GEN_XISO = $(XBE_TITLE).iso +SRCS = $(CURDIR)/main.c +NXDK_DIR ?= $(CURDIR)/../.. +NXDK_SDL = y +NXDK_SDL_MIXER = y + +include $(NXDK_DIR)/Makefile + +TARGET += $(OUTPUT_DIR)/sdl_mixer_tone.wav \ + $(OUTPUT_DIR)/sdl_mixer_music.wav + +$(GEN_XISO): $(OUTPUT_DIR)/sdl_mixer_tone.wav $(OUTPUT_DIR)/sdl_mixer_music.wav + +$(OUTPUT_DIR)/sdl_mixer_tone.wav: $(CURDIR)/sdl_mixer_tone.wav $(OUTPUT_DIR) + $(VE)cp '$<' '$@' + +$(OUTPUT_DIR)/sdl_mixer_music.wav: $(CURDIR)/sdl_mixer_music.wav $(OUTPUT_DIR) + $(VE)cp '$<' '$@' diff --git a/samples/sdl_mixer/main.c b/samples/sdl_mixer/main.c new file mode 100644 index 000000000..90b3b8f71 --- /dev/null +++ b/samples/sdl_mixer/main.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +#define SAMPLE_RATE 22050 + +static void shutdown_audio(Mix_Chunk *chunk, Mix_Music *music) +{ + Mix_HaltMusic(); + Mix_HaltChannel(-1); + if (music) { + Mix_FreeMusic(music); + } + if (chunk) { + Mix_FreeChunk(chunk); + } + Mix_CloseAudio(); + SDL_Quit(); +} + +int main(void) +{ + Mix_Chunk *chunk = NULL; + Mix_Music *music = NULL; + int channel; + + XVideoSetMode(640, 480, 32, REFRESH_DEFAULT); + debugPrint("nxdk SDL_mixer sample\n"); + + if (SDL_Init(SDL_INIT_AUDIO) < 0) { + debugPrint("SDL_Init failed: %s\n", SDL_GetError()); + return 1; + } + + if (Mix_OpenAudio(SAMPLE_RATE, AUDIO_S16SYS, 2, 1024) < 0) { + debugPrint("Mix_OpenAudio failed: %s\n", Mix_GetError()); + SDL_Quit(); + return 1; + } + + chunk = Mix_LoadWAV("D:\\sdl_mixer_tone.wav"); + if (!chunk) { + debugPrint("Mix_LoadWAV failed: %s\n", Mix_GetError()); + shutdown_audio(chunk, music); + return 1; + } + + music = Mix_LoadMUS("D:\\sdl_mixer_music.wav"); + if (!music) { + debugPrint("Mix_LoadMUS failed: %s\n", Mix_GetError()); + shutdown_audio(chunk, music); + return 1; + } + + if (Mix_PlayMusic(music, 0) < 0) { + debugPrint("Mix_PlayMusic failed: %s\n", Mix_GetError()); + shutdown_audio(chunk, music); + return 1; + } + + channel = Mix_PlayChannel(-1, chunk, 0); + if (channel < 0) { + debugPrint("Mix_PlayChannel failed: %s\n", Mix_GetError()); + shutdown_audio(chunk, music); + return 1; + } + + debugPrint("Playing packaged WAV assets on channel %d\n", channel); + while (Mix_PlayingMusic() || Mix_Playing(channel)) { + Sleep(50); + } + + shutdown_audio(chunk, music); + debugPrint("SDL_mixer sample complete\n"); + while (1) { + Sleep(1000); + } + + return 0; +} diff --git a/samples/sdl_mixer/sdl_mixer_music.wav b/samples/sdl_mixer/sdl_mixer_music.wav new file mode 100644 index 000000000..e115aa840 Binary files /dev/null and b/samples/sdl_mixer/sdl_mixer_music.wav differ diff --git a/samples/sdl_mixer/sdl_mixer_tone.wav b/samples/sdl_mixer/sdl_mixer_tone.wav new file mode 100644 index 000000000..160fc9420 Binary files /dev/null and b/samples/sdl_mixer/sdl_mixer_tone.wav differ