summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a71064c)
raw | patch | inline | side by side (parent: a71064c)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 23 Mar 2020 11:56:01 +0000 (14:56 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 23 Mar 2020 11:56:01 +0000 (14:56 +0300) |
src/CMakeLists.txt | patch | blob | history | |
src/openal/sound.c | [new file with mode: 0644] | patch | blob |
src/sdl/main.c | patch | blob | history |
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 955827809ecf38a5dd5a8091056dc49afb4771b8..e33b8325772008742ac6eb957f73c781366ff332 100644 (file)
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
option(WITH_OPENGL "Build with OpenGL render" ON)
option(WITH_SOFTWARE "Build with Software render" ON)
+option(SOUND_DRIVER "Build with selected sound driver" "OpenAL")
+
+set(WITH_OPENAL (SOUND_DRIVER EQUALS "OpenAL"))
+set(WITH_SDLMIXER (SOUND_DRIVER EQUALS "SDL_mixer"))
set(D2D_GAME_ROOT .)
set(D2D_OPENGL_ROOT ${D2D_GAME_ROOT}/gl)
set(D2D_SOFTWARE_ROOT ${D2D_GAME_ROOT}/soft)
set(D2D_SDL_ROOT ${D2D_GAME_ROOT}/sdl)
set(D2D_SDLMIXER_ROOT ${D2D_GAME_ROOT}/sdlmixer)
-
-find_package(SDL REQUIRED)
-find_package(SDL_mixer REQUIRED)
-if (WITH_OPENGL)
- find_package(OpenGL REQUIRED)
-endif (WITH_OPENGL)
+set(D2D_OPENAL_ROOT ${D2D_GAME_ROOT}/openal)
aux_source_directory(${D2D_GAME_ROOT} D2D_GAME_SRC)
aux_source_directory(${D2D_OPENGL_ROOT} D2D_OPENGL_SRC)
aux_source_directory(${D2D_SOFTWARE_ROOT} D2D_SOFTWARE_SRC)
aux_source_directory(${D2D_SDL_ROOT} D2D_SDL_SRC)
aux_source_directory(${D2D_SDLMIXER_ROOT} D2D_SDLMIXER_SRC)
+aux_source_directory(${D2D_OPENAL_ROOT} D2D_OPENAL_SRC)
+
+find_package(SDL REQUIRED)
+message(STATUS "sound::${SOUND_DRIVER}")
+if(WITH_OPENAL)
+ find_package(OpenAL REQUIRED)
+ set(D2D_SOUND_SRC "${D2D_OPENAL_SRC}")
+ set(D2D_SOUND_INCLUDE_DIR "${OPENAL_INCLUDE_DIR}")
+ set(D2D_SOUND_LIBRARY "${OPENAL_LIBRARY}")
+elseif(WITH_SDLMIXER)
+ find_package(SDL_mixer REQUIRED)
+ set(D2D_SOUND_SRC "${D2D_SDLMIXER_SRC}")
+ set(D2D_SOUND_INCLUDE_DIR "${SDLMIXER_INCLUDE_DIR}")
+ set(D2D_SOUND_LIBRARY "${SDLMIXER_LIBRARY}")
+else(WITH_OPENAL)
+ message(FATAL_ERROR "Select SOUND_DRIVER as OpenAL or SDL_mixer")
+endif(WITH_OPENAL)
+
+if (WITH_OPENGL)
+ find_package(OpenGL REQUIRED)
+endif (WITH_OPENGL)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
message(STATUS "=== BUILD OPTIONS ===")
-message(STATUS "BUILD: " ${CMAKE_BUILD_TYPE})
-message(STATUS "CFLAGS: " ${CMAKE_C_FLAGS})
+message(STATUS "BUILD: " "${CMAKE_BUILD_TYPE}")
+message(STATUS "CFLAGS: " "${CMAKE_C_FLAGS}")
+message(STATUS "SOUND: " "${SOUND_DRIVER}")
message(STATUS "=== RENDERS ===")
message(STATUS "SOFTWARE: " ${WITH_SOFTWARE})
message(STATUS "OPENGL: " ${WITH_OPENGL})
if (WITH_OPENGL)
- add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SDLMIXER_SRC} ${D2D_OPENGL_SRC})
- target_include_directories(doom2d-gl PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}" "${OPENGL_INCLUDE_DIR}")
- target_link_libraries(doom2d-gl "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}" "${OPENGL_LIBRARY}")
+ add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_SOUND_SRC} ${D2D_SDL_SRC} ${D2D_OPENGL_SRC})
+ target_include_directories(doom2d-gl PRIVATE "${D2D_GAME_ROOT}" "${D2D_SOUND_INCLUDE_DIR}" "${SDL_INCLUDE_DIR}" "${OPENGL_INCLUDE_DIR}")
+ target_link_libraries(doom2d-gl "${D2D_SOUND_LIBRARY}" "${SDL_LIBRARY}" "${OPENGL_LIBRARY}")
endif (WITH_OPENGL)
if (WITH_SOFTWARE)
- add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SDLMIXER_SRC} ${D2D_SOFTWARE_SRC})
- target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}")
- target_link_libraries(doom2d-soft "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}")
+ add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SOUND_SRC} ${D2D_SDL_SRC} ${D2D_SOFTWARE_SRC})
+ target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${D2D_SOUND_LIBRARY}" "${SDL_INCLUDE_DIR}")
+ target_link_libraries(doom2d-soft "${D2D_SOUND_LIBRARY}" "${SDL_LIBRARY}")
endif (WITH_SOFTWARE)
diff --git a/src/openal/sound.c b/src/openal/sound.c
--- /dev/null
+++ b/src/openal/sound.c
@@ -0,0 +1,280 @@
+#include "sound.h"
+#include "music.h"
+
+#include "files.h" // F_findres F_getreslen
+#include "memory.h" // M_lock M_unlock
+#include "misc.h" // int2host
+#include "error.h" // logo
+
+#include <OpenAL/al.h>
+#include <OpenAL/alc.h>
+#include <SDL.h> // SDL_BuildAudioCVT SDL_ConvertAudio
+#include <assert.h>
+#include <stdlib.h> // malloc
+#include <string.h> // memcpy
+
+#define TAG_OAL1 0x4F414C31
+#define MAX_CHANNELS 8
+
+#pragma pack(1)
+typedef struct dmi {
+ dword len;
+ dword rate;
+ dword lstart;
+ dword llen;
+ byte data[];
+} dmi;
+#pragma pack()
+
+typedef struct openal_snd {
+ snd_t base;
+ ALuint buffer;
+} openal_snd;
+
+typedef struct openal_channel {
+ ALuint source;
+} openal_channel;
+
+short snd_vol;
+short mus_vol;
+char music_random;
+int music_time;
+int music_fade;
+
+static ALCdevice *device;
+static ALCcontext *context;
+static ALuint sources[MAX_CHANNELS];
+
+/* Music */
+
+void S_initmusic (void) {
+
+}
+
+void S_donemusic (void) {
+
+}
+
+void S_startmusic (int time) {
+
+}
+
+void S_stopmusic (void) {
+
+}
+
+void S_volumemusic (int v) {
+
+}
+
+void F_loadmus (char n[8]) {
+
+}
+
+void F_freemus (void) {
+
+}
+
+void S_updatemusic (void) {
+
+}
+
+/* Sound */
+
+static void convert_this_ext (Uint32 src_format, int src_chan, int src_rate, Uint32 dst_format, int dst_chan, int dst_rate, const void *buf, int len, void **maxbuf, int *maxlen) {
+ SDL_AudioCVT cvt;
+ *maxlen = 0;
+ *maxbuf = NULL;
+ if (SDL_BuildAudioCVT(&cvt, src_format, src_chan, src_rate, dst_format, dst_chan, dst_rate) != -1) {
+ *maxlen = len * cvt.len_mult;
+ *maxbuf = malloc(*maxlen);
+ if (*maxbuf != NULL) {
+ memcpy(*maxbuf, buf, len);
+ cvt.buf = *maxbuf;
+ cvt.len = len;
+ if (SDL_ConvertAudio(&cvt) == 0) {
+ *maxlen = len * cvt.len_ratio;
+ } else {
+ free(*maxbuf);
+ *maxbuf = NULL;
+ *maxlen = 0;
+ }
+ }
+ }
+}
+
+static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dword lstart, dword llen) {
+ assert(data);
+ ALuint buffer = 0;
+ openal_snd *snd = NULL;
+ void *newdata = NULL;
+ int newlen = 0;
+ // for some reason 8bit formats makes psshshshsh
+ // TODO do this without SDL
+ convert_this_ext(AUDIO_S8, 1, rate, AUDIO_S16SYS, 1, rate, data, len, &newdata, &newlen);
+ if (newdata != NULL) {
+ alGenBuffers(1, &buffer);
+ if (alGetError() == AL_NO_ERROR) {
+ alBufferData(buffer, AL_FORMAT_MONO16, newdata, newlen, rate);
+ if (alGetError() == AL_NO_ERROR) {
+ snd = malloc(sizeof(openal_snd));
+ if (snd != NULL) {
+ snd->base.tag = TAG_OAL1;
+ snd->buffer = buffer;
+ // TODO loops
+ } else {
+ alDeleteBuffers(1, &buffer);
+ }
+ } else {
+ alDeleteBuffers(1, &buffer);
+ }
+ }
+ free(newdata);
+ }
+ return snd;
+}
+
+snd_t *S_get (int id) {
+ openal_snd *snd = NULL;
+ void *handle = M_lock(id);
+ if (context != NULL && handle != NULL) {
+ byte *data = handle;
+ dword len = F_getreslen(id);
+ dword rate = 8000;
+ dword lstart = 0;
+ dword llen = 0;
+ if (len > 16) {
+ dmi *hdr = handle;
+ dword hdr_len = int2host(hdr->len);
+ dword hdr_rate = int2host(hdr->rate);
+ dword hdr_lstart = int2host(hdr->lstart);
+ dword hdr_llen = int2host(hdr->llen);
+ if (hdr_len <= len - 8 && hdr_lstart + hdr_llen <= len - 16) {
+ data = hdr->data;
+ len = hdr_len;
+ rate = hdr_rate;
+ lstart = hdr_lstart;
+ llen = hdr_llen;
+ }
+ }
+ snd = new_openal_snd(data, len, rate, lstart, llen);
+ M_unlock(handle);
+ }
+ return (snd_t*)snd;
+}
+
+snd_t *S_load (const char name[8]) {
+ return S_get(F_findres(name));
+}
+
+void S_init (void) {
+ assert(device == NULL && context == NULL);
+ const ALCint attrs[] = {ALC_MONO_SOURCES, MAX_CHANNELS, 0};
+ device = alcOpenDevice(NULL);
+ if (device != NULL) {
+ context = alcCreateContext(device, attrs);
+ if (context != NULL) {
+ if (alcMakeContextCurrent(context)) {
+ alGenSources(MAX_CHANNELS, sources);
+ if (alGetError() == AL_NO_ERROR) {
+ alListenerf(AL_GAIN, 1);
+ alListener3f(AL_POSITION, 0, 0, 0);
+ alListener3f(AL_VELOCITY, 0, 0, 0);
+ } else {
+ logo("S_init: unable to create OpenAL sources\n");
+ alcDestroyContext(context);
+ alcCloseDevice(device);
+ context = NULL;
+ device = NULL;
+ }
+ } else {
+ logo("S_init: unable to make OpenAL context current\n");
+ alcDestroyContext(context);
+ alcCloseDevice(device);
+ context = NULL;
+ device = NULL;
+ }
+ } else {
+ logo("S_init: unable to create OpenAL context\n");
+ alcCloseDevice(device);
+ device = NULL;
+ }
+ } else {
+ logo("S_init: unable to open OpenAL device\n");
+ }
+}
+
+void S_done (void) {
+ if (context != NULL) {
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(context);
+ alcCloseDevice(device);
+ }
+ context = NULL;
+ device = NULL;
+}
+
+short S_play (snd_t *s, short c, short v) {
+ assert(c >= 0 && c <= MAX_CHANNELS);
+ assert(v >= 0 && v < 256);
+ ALuint source;
+ ALint state;
+ int channel;
+ if (context != NULL && s != NULL) {
+ openal_snd *snd = (openal_snd*)s;
+ assert(snd->base.tag == TAG_OAL1);
+ if (c == 0) {
+ for (channel = 0; channel < MAX_CHANNELS; channel++) {
+ state = AL_PLAYING;
+ alGetSourcei(sources[channel], AL_SOURCE_STATE, &state);
+ if (state == AL_STOPPED || state == AL_INITIAL) {
+ break; // !!!
+ }
+ }
+ } else {
+ channel = c - 1;
+ }
+ if (channel < MAX_CHANNELS) {
+ source = sources[channel];
+ alSourceStop(source);
+ alSourcei(source, AL_BUFFER, snd->buffer);
+ alSourcef(source, AL_PITCH, 1);
+ alSourcef(source, AL_GAIN, v / 255.0);
+ alSource3f(source, AL_POSITION, 0, 0, 0);
+ alSource3f(source, AL_VELOCITY, 0, 0, 0);
+ alSourcei(source, AL_LOOPING, AL_FALSE);
+ alSourcePlay(source);
+ }
+ }
+ return 0;
+}
+
+void S_stop (short c) {
+ assert(c >= 0 && c <= MAX_CHANNELS);
+ if (context != NULL) {
+ if (c != 0) {
+ alSourceStop(sources[c - 1]);
+ }
+ }
+}
+
+void S_volume (int v) {
+ assert(v >= 0 && v <= 128);
+ snd_vol = v;
+ if (context != NULL) {
+ alListenerf(AL_GAIN, v / 128.0);
+ }
+}
+
+void S_wait (void) {
+ int i;
+ ALint state;
+ if (context != NULL) {
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ do {
+ state = AL_STOPPED;
+ alGetSourcei(sources[i], AL_SOURCE_STATE, &state);
+ } while (state == AL_PLAYING);
+ }
+ }
+}
diff --git a/src/sdl/main.c b/src/sdl/main.c
index 48aa5072979c15692ea465d765dab482cd8181a3..15ce855d35c515b2190655c2d843d170632f1706 100644 (file)
--- a/src/sdl/main.c
+++ b/src/sdl/main.c
}
CFG_save();
R_done();
- S_done();
S_donemusic();
+ S_done();
M_shutdown();
SDL_Quit();
return 0;