aboutsummaryrefslogtreecommitdiff
path: root/src/sdl/sounds.c
blob: a78e8ad4a97d7c8821b9ab7a460a5d2efae1bdb4 (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
86
87
88
89
90
#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_MOVE,               ASSET_LAST }, // none
  { SOUND_MOVE_FAILED,        ASSET_SOUND_HIT_1_WAV }, // bump
  { SOUND_LEVEL_DONE,         ASSET_SOUND_POWERUP_3_WAV },
  { SOUND_UNDO,               ASSET_SOUND_HIT_1_WAV }, // bump
  { SOUND_UNDO_FAILED,        ASSET_SOUND_HIT_1_WAV }, // bump
  { SOUND_LEVEL_NEXT,         ASSET_SOUND_POWERUP_1_WAV },
  { SOUND_LEVEL_NEXT_FAILED,  ASSET_SOUND_HIT_1_WAV }, // bump
  { SOUND_LEVEL_RESET,        ASSET_SOUND_UNDO_0_WAV },
  { SOUND_LEVEL_WARP,         ASSET_SOUND_POWERUP_1_WAV },
  { SOUND_SOLVE_START,        ASSET_LAST }, // none
  { SOUND_SOLVE_FAILED,       ASSET_LAST }, // none
  { 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());
  }
}