aboutsummaryrefslogtreecommitdiff
path: root/src/sdl/sounds.c
blob: 2c8c3f183f4e567c9a1b3b83ca3d14c07e62539d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <SDL.h>
#include "util.h"
#include "assets.h"
#include "sounds.h"

#define SOUND_OFS(asset_id) ((asset_id) - ASSET_SOUND_FIRST - 1)

static const struct {
  sound_t     sound;
  asset_id_t  asset_id;
} SOUND_MAP[] = {
  { SOUND_BUMP,         ASSET_SOUND_HIT_1_WAV },
  { SOUND_LEVEL_DONE,   ASSET_SOUND_POWERUP_3_WAV },
  { SOUND_UNDO,         ASSET_SOUND_HIT_1_WAV },
  { SOUND_LEVEL_NEXT,   ASSET_SOUND_POWERUP_1_WAV },
  { SOUND_LEVEL_RESET,  ASSET_SOUND_UNDO_0_WAV },
  { SOUND_LEVEL_WARP,   ASSET_SOUND_POWERUP_1_WAV },
  { SOUND_SOLVE_CANCEL, ASSET_SOUND_HIT_2_WAV },
  { SOUND_SOLVE_DONE,   ASSET_SOUND_POWERUP_4_WAV },
  { SOUND_LAST,         ASSET_LAST },
};

void
sounds_init(
  Mix_Chunk ** const sounds
) {
  for (asset_id_t id = ASSET_SOUND_FIRST + 1; id < ASSET_SOUND_LAST; id++) {
    // get asset
    const asset_t * const asset = asset_get(id);

    // create rwops
    SDL_RWops *rw = SDL_RWFromConstMem(asset->buf, asset->len);
    if (!rw) {
      die("SDL_RWFromConstMem(): %s", SDL_GetError());
    }

    // load chunk
    Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1);
    if (!chunk) {
      die("Mix_LoadWAV_RW(): %s", Mix_GetError());
    }

    // add to list of sounds
    sounds[SOUND_OFS(id)] = chunk;
  }
}

static asset_id_t
get_asset_id(
  const sound_t sound_id
) {
  for (size_t i = 0; SOUND_MAP[i].sound != SOUND_LAST; i++) {
    if (SOUND_MAP[i].sound == sound_id) {
      return SOUND_MAP[i].asset_id;
    }
  }

  // return failure
  return ASSET_LAST;
}

void
sound_play(
  Mix_Chunk ** const sounds,
  const sound_t sound_id
) {
  // get asset ID
  const asset_id_t id = get_asset_id(sound_id);

  if (id == ASSET_LAST) {
    // no sound to play, return
    return;
  }

  // check asset ID bounds
  if (id <= ASSET_SOUND_FIRST || id >= ASSET_SOUND_LAST) {
    warn("invalid sound asset id: %u", id);
    return;
  }

  // play sound
  if (Mix_PlayChannel(-1, sounds[SOUND_OFS(id)], 0)) {
    warn("Mix_PlayChannel(): %s", Mix_GetError());
  }
}