GameBoy (Color) port of the GTA San Andreas arcade game Duality
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sample.c 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * sample.c
  3. * Duality
  4. *
  5. * Copyright (C) 2025 Thomas Buck <thomas@xythobuz.de>
  6. *
  7. * Based on examples from gbdk-2020:
  8. * https://github.com/gbdk-2020/gbdk-2020/tree/develop/gbdk-lib/examples/gb/wav_sample
  9. *
  10. * And the docs for the DMG APU:
  11. * https://gbdev.io/pandocs/Audio_Registers.html
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation, either version 3 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * See <http://www.gnu.org/licenses/>.
  24. */
  25. #include "sfx_shoot.h"
  26. #include "sfx_expl_orb.h"
  27. #include "sfx_expl_ship.h"
  28. #include "sample.h"
  29. BANKREF(sample)
  30. static volatile uint8_t play_bank = 1;
  31. static volatile const uint8_t *play_sample = 0;
  32. static volatile uint16_t play_length = 0;
  33. static volatile uint8_t playing = 0;
  34. uint8_t snd_vol_sfx = 0x00;
  35. struct sfxs {
  36. uint8_t bank;
  37. uint8_t * const smp;
  38. uint16_t len;
  39. };
  40. static const struct sfxs sfxs[SFX_COUNT] = {
  41. { .bank = BANK(sfx_shoot), .smp = sfx_shoot, .len = sfx_shoot_SIZE >> 4 }, // SFX_SHOT
  42. { .bank = BANK(sfx_expl_orb), .smp = sfx_expl_orb, .len = sfx_expl_orb_SIZE >> 4 }, // SFX_EXPL_ORB
  43. { .bank = BANK(sfx_expl_ship), .smp = sfx_expl_ship, .len = sfx_expl_ship_SIZE >> 4 }, // SFX_EXPL_SHIP
  44. };
  45. void sample_play(enum SFXS sfx) BANKED {
  46. if (sfx >= SFX_COUNT) {
  47. return;
  48. }
  49. CRITICAL {
  50. play_bank = sfxs[sfx].bank;
  51. play_sample = sfxs[sfx].smp;
  52. play_length = sfxs[sfx].len;
  53. playing = 1;
  54. }
  55. }
  56. uint8_t sample_running(void) BANKED {
  57. return playing;
  58. }
  59. void sample_isr(void) NONBANKED NAKED {
  60. __asm
  61. ld hl, #_play_length ; something left to play?
  62. ld a, (hl+)
  63. or (hl)
  64. jp z, done
  65. ld hl, #_play_sample
  66. ld a, (hl+)
  67. ld h, (hl)
  68. ld l, a ; HL = current position inside the sample
  69. ; load new waveform
  70. ld a, (#__current_bank) ; save bank and switch
  71. ld e, a
  72. ld a, (#_play_bank)
  73. ld (_rROMB0), a
  74. ldh a, (_NR51_REG)
  75. ld c, a
  76. and #0b10111011
  77. ldh (_NR51_REG), a
  78. xor a
  79. ldh (_NR30_REG), a
  80. .irp ofs,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  81. ld a, (hl+)
  82. ldh (__AUD3WAVERAM+ofs), a
  83. .endm
  84. ld a, #0x80
  85. ldh (_NR30_REG), a
  86. ld a, #0xFE ; length of wave
  87. ldh (_NR31_REG), a
  88. ld a, (_snd_vol_sfx) ; volume
  89. swap a ; shift vol to upper bits
  90. ldh (_NR32_REG), a
  91. xor a ; low freq bits are zero
  92. ldh (_NR33_REG), a
  93. ld a, #0xC7 ; start; no loop; high freq bits are 111
  94. ldh (_NR34_REG), a
  95. ld a, c
  96. ldh (_NR51_REG), a
  97. ld a, e ; restore bank
  98. ld (_rROMB0), a
  99. ld a, l ; save current position
  100. ld (#_play_sample), a
  101. ld a, h
  102. ld (#_play_sample+1), a
  103. ld hl, #_play_length ; decrement length variable
  104. ld a, (hl)
  105. sub #1
  106. ld (hl+), a
  107. ld a, (hl)
  108. sbc #0
  109. ld (hl), a
  110. ret
  111. done:
  112. ld a, #0
  113. ld (_playing), a
  114. ret z
  115. __endasm;
  116. }