DEADSOFTWARE

sdlmixer: fix sound loading (but sdlmixer still emits broken sound)
[flatwaifu.git] / src / sdlmixer / sound.c
index 92334c7fc0ad58c9aff515e07e7863a8a34e2d7b..c4b9cd7473eed6cde3286c12c532ab70960a3e89 100644 (file)
@@ -1,24 +1,41 @@
+/* Copyright (C) 2020 SovietPony
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #include "glob.h"
 #include "sound.h"
 #include "music.h"
-#include "misc.h" // int2host
 #include "memory.h" // M_lock M_unlock
 #include "files.h" // F_findres
 #include "error.h"
 
+#include "common/endianness.h"
+
 #include "SDL.h"
 #include "SDL_mixer.h"
 #include <assert.h>
+#include <string.h>
 
 #define TAG_MIX1 0x4d495831
 
 #pragma pack(1)
 typedef struct dmi {
-  Uint32 len;    // length [bytes]
-  Uint32 rate;   // freq [Hz]
-  Uint32 lstart; // loop start offset [bytes]
-  Uint32 llen;   // loop length [bytes]
-  Uint8 data[];  // sound data
+  word len;    // length [bytes]
+  word rate;   // freq [Hz]
+  word lstart; // loop start offset [bytes]
+  word llen;   // loop length [bytes]
+  byte data[];  // sound data
 } dmi;
 #pragma pack()
 
@@ -27,7 +44,7 @@ typedef struct sdlmixer_snd {
   Mix_Chunk *c;
 } sdlmixer_snd;
 
-short snd_vol; // public 0..128
+static short snd_vol;
 
 static int devfreq = MIX_DEFAULT_FREQUENCY;
 static Uint32 devformat = AUDIO_S16SYS; // MIX_DEFAULT_FORMAT
@@ -38,45 +55,92 @@ static int devinit;
 
 /* music */
 
-short mus_vol;
-char music_random;
-int music_time;
-int music_fade;
+const cfg_t *MUS_args (void) {
+  return NULL;
+}
 
-void S_initmusic (void) {
+const cfg_t *MUS_conf (void) {
+  return NULL;
+}
 
+const menu_t *MUS_menu (void) {
+  return NULL;
 }
 
-void S_donemusic (void) {
+void MUS_init (void) {
 
 }
 
-void S_startmusic (int time) {
+void MUS_done (void) {
 
 }
 
-void S_stopmusic (void) {
+void MUS_start (int time) {
 
 }
 
-void S_volumemusic (int v) {
+void MUS_stop (void) {
 
 }
 
-void F_loadmus (char n[8]) {
+void MUS_volume (int v) {
 
 }
 
-void F_freemus (void) {
+void MUS_load (char n[8]) {
 
 }
 
-void S_updatemusic (void) {
+void MUS_free (void) {
+
+}
+
+void MUS_update (void) {
 
 }
 
 /* Sound */
 
+static int sound_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
+  static int cur;
+  enum { VOLUME, __NUM__ };
+  static const simple_menu_t sm = {
+    GM_BIG, "Sound", NULL,
+    {
+      { "Volume", NULL },
+    }
+  };
+  if (i == VOLUME) {
+    switch (msg->type) {
+      case GM_GETENTRY: return GM_init_int0(msg, GM_SCROLLER, 0, 0, 0);
+      case GM_GETINT: return GM_init_int(msg, snd_vol, 0, 128, 8);
+      case GM_SETINT: S_volume(msg->integer.i); return 1;
+    }
+  }
+  return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
+}
+
+const menu_t *S_menu (void) {
+  static const menu_t m = { sound_menu_handler };
+  return &m;
+}
+
+const cfg_t *S_args (void) {
+  static const cfg_t args[] = {
+    { "sndvol", &snd_vol, Y_WORD },
+    { NULL, NULL, 0 }
+  };
+  return args;
+}
+
+const cfg_t *S_conf (void) {
+  static const cfg_t conf[] = {
+    { "sound_volume", &snd_vol, Y_WORD },
+    { NULL, NULL, 0 }
+  };
+  return conf;
+}
+
 void S_init (void) {
   assert(devinit == 0);
   logo("S_init: initialize sound\n");
@@ -145,18 +209,18 @@ snd_t *S_get (int id) {
     handle = M_lock(id);
     if (handle != NULL) {
       void *data = handle;
-      dword len = F_getreslen(id);
-      dword rate = 11025;
-      dword lstart = 0;
-      dword llen = 0;
+      word len = F_getreslen(id);
+      word rate = 11025;
+      word lstart = 0;
+      word llen = 0;
       int sign = 0;
-      if (len > 16) {
+      if (len > 8) {
         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) {
+        word hdr_len = short2host(hdr->len);
+        word hdr_rate = short2host(hdr->rate);
+        word hdr_lstart = short2host(hdr->lstart);
+        word hdr_llen = short2host(hdr->llen);
+        if (hdr_len <= len - 4 && hdr_lstart + hdr_llen <= len - 8) {
           data = hdr->data;
           len = hdr_len;
           rate = hdr_rate;