romdevtools 0.71.0 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/AGENTS.md +19 -16
  2. package/CHANGELOG.md +196 -0
  3. package/README.md +5 -5
  4. package/examples/README.md +1 -0
  5. package/examples/gametank/templates/gt_draw.h +91 -0
  6. package/examples/gametank/templates/gt_hud.h +89 -0
  7. package/examples/gametank/templates/gt_palette.h +59 -0
  8. package/examples/gametank/templates/gt_sound.h +90 -0
  9. package/examples/gametank/templates/gt_sprites.h +53 -0
  10. package/examples/gametank/templates/platformer.c +318 -0
  11. package/examples/gametank/templates/puzzle.c +295 -0
  12. package/examples/gametank/templates/racing.c +139 -0
  13. package/examples/gametank/templates/shmup.c +277 -0
  14. package/examples/gametank/templates/sports.c +119 -0
  15. package/package.json +23 -22
  16. package/src/cores/capabilities.js +24 -0
  17. package/src/cores/registry.js +7 -1
  18. package/src/host/LibretroHost.js +90 -17
  19. package/src/host/callbacks.js +20 -2
  20. package/src/host/cpu-state.js +17 -0
  21. package/src/host/gametank-acp-state.js +53 -0
  22. package/src/http/skill-doc.js +10 -6
  23. package/src/mcp/tools/audio.js +1 -1
  24. package/src/mcp/tools/cart-parts.js +76 -0
  25. package/src/mcp/tools/lifecycle.js +1 -1
  26. package/src/mcp/tools/platform-tools.js +9 -1
  27. package/src/mcp/tools/platforms.js +46 -10
  28. package/src/mcp/tools/toolchain.js +35 -10
  29. package/src/platforms/gametank/lib/gt/audio/acp_image.bin +0 -0
  30. package/src/platforms/gametank/lib/gt/audio/audio_coprocessor.c +55 -0
  31. package/src/platforms/gametank/lib/gt/audio/audio_coprocessor.h +34 -0
  32. package/src/platforms/gametank/lib/gt/audio/audio_fw.asm +223 -0
  33. package/src/platforms/gametank/lib/gt/audio/audio_fw_blob.s +8 -0
  34. package/src/platforms/gametank/lib/gt/audio/instruments.c +79 -0
  35. package/src/platforms/gametank/lib/gt/audio/instruments.h +25 -0
  36. package/src/platforms/gametank/lib/gt/audio/music.c +370 -0
  37. package/src/platforms/gametank/lib/gt/audio/music.h +35 -0
  38. package/src/platforms/gametank/lib/gt/audio/note_numbers.h +132 -0
  39. package/src/platforms/gametank/lib/gt/audio/scaled_sines.raw +0 -0
  40. package/src/platforms/gametank/lib/gt/audio/sine_256_-63_63.bin +0 -0
  41. package/src/platforms/gametank/lib/gt/banking.c +29 -0
  42. package/src/platforms/gametank/lib/gt/banking.h +8 -0
  43. package/src/platforms/gametank/lib/gt/banking2.s +41 -0
  44. package/src/platforms/gametank/lib/gt/crt0.s +102 -0
  45. package/src/platforms/gametank/lib/gt/draw_logo.s +55 -0
  46. package/src/platforms/gametank/lib/gt/feature/persist/persist.c +103 -0
  47. package/src/platforms/gametank/lib/gt/feature/persist/persist.h +13 -0
  48. package/src/platforms/gametank/lib/gt/feature/random/random.c +40 -0
  49. package/src/platforms/gametank/lib/gt/feature/random/random.h +18 -0
  50. package/src/platforms/gametank/lib/gt/feature/text/text.c +111 -0
  51. package/src/platforms/gametank/lib/gt/feature/text/text.h +25 -0
  52. package/src/platforms/gametank/lib/gt/gametank.c +12 -0
  53. package/src/platforms/gametank/lib/gt/gametank.h +80 -0
  54. package/src/platforms/gametank/lib/gt/gametank_logo.inc +393 -0
  55. package/src/platforms/gametank/lib/gt/gen/assets/assets_index.h +9 -0
  56. package/src/platforms/gametank/lib/gt/gen/assets/sdk_default.h +5 -0
  57. package/src/platforms/gametank/lib/gt/gen/bank_nums.h +11 -0
  58. package/src/platforms/gametank/lib/gt/gen/modules_enabled.h +4 -0
  59. package/src/platforms/gametank/lib/gt/gen/modules_enabled.inc +4 -0
  60. package/src/platforms/gametank/lib/gt/gfx/draw_direct.c +132 -0
  61. package/src/platforms/gametank/lib/gt/gfx/draw_direct.h +75 -0
  62. package/src/platforms/gametank/lib/gt/gfx/draw_queue.c +177 -0
  63. package/src/platforms/gametank/lib/gt/gfx/draw_queue.h +35 -0
  64. package/src/platforms/gametank/lib/gt/gfx/draw_util.s +157 -0
  65. package/src/platforms/gametank/lib/gt/gfx/gfx_sys.c +43 -0
  66. package/src/platforms/gametank/lib/gt/gfx/gfx_sys.h +46 -0
  67. package/src/platforms/gametank/lib/gt/gfx/sprites.c +216 -0
  68. package/src/platforms/gametank/lib/gt/gfx/sprites.h +41 -0
  69. package/src/platforms/gametank/lib/gt/init.c +9 -0
  70. package/src/platforms/gametank/lib/gt/input.c +26 -0
  71. package/src/platforms/gametank/lib/gt/input.h +20 -0
  72. package/src/platforms/gametank/lib/gt/interrupt.s +67 -0
  73. package/src/platforms/gametank/lib/gt/vectors.s +14 -0
  74. package/src/platforms/gametank/lib/gt/wait.s +53 -0
  75. package/src/platforms/gba/MENTAL_MODEL.md +22 -1
  76. package/src/playtest/playtest.js +174 -26
  77. package/src/playtest/resampler/build.sh +19 -0
  78. package/src/playtest/resampler/index.mjs +75 -0
  79. package/src/playtest/resampler/resampler.c +129 -0
  80. package/src/playtest/resampler/resampler.mjs +2 -0
  81. package/src/playtest/resampler/resampler.wasm +0 -0
  82. package/src/toolchains/arm-none-eabi-gcc/gcc.js +39 -188
  83. package/src/toolchains/asar/asar.js +10 -15
  84. package/src/toolchains/cc65/cc65.js +82 -92
  85. package/src/toolchains/cc65/da65.js +12 -17
  86. package/src/toolchains/cc65/preset-resolver.js +13 -2
  87. package/src/toolchains/cc65/presets/gametank/gametank.h +80 -0
  88. package/src/toolchains/cc65/presets/gametank/sdk.cfg +32 -0
  89. package/src/toolchains/cc65/presets/gametank/sdk.crt0.s +61 -0
  90. package/src/toolchains/cc65/presets/gametank/sdk.vectors.s +11 -0
  91. package/src/toolchains/cc65/presets/gametank/single-bank.cfg +28 -0
  92. package/src/toolchains/cc65/presets/gametank/single-bank.crt0.s +71 -0
  93. package/src/toolchains/cc65/presets/gametank/single-bank.vectors.s +12 -0
  94. package/src/toolchains/common/c-build.js +109 -0
  95. package/src/toolchains/common/gcc-toolchain.js +164 -0
  96. package/src/toolchains/common/wasm-tool.js +101 -0
  97. package/src/toolchains/dasm/dasm.js +12 -18
  98. package/src/toolchains/gba-c/gba-c.js +253 -305
  99. package/src/toolchains/genesis-c/genesis-c.js +196 -225
  100. package/src/toolchains/index.js +58 -4
  101. package/src/toolchains/m68k-elf-gcc/gcc.js +39 -202
  102. package/src/toolchains/mips-c/mips-c.js +68 -78
  103. package/src/toolchains/mips-elf-gcc/gcc.js +55 -118
  104. package/src/toolchains/rgbds/rgbds.js +7 -19
  105. package/src/toolchains/sdcc/sdcc.js +35 -26
  106. package/src/toolchains/sh-c/sh-c.js +44 -52
  107. package/src/toolchains/sh-elf-gcc/gcc.js +55 -110
  108. package/src/toolchains/sjasm/sjasm.js +10 -14
  109. package/src/toolchains/snes-c/snes-c.js +125 -150
  110. package/src/toolchains/tcc816/tcc816.js +10 -15
  111. package/src/toolchains/vasm68k/vasm68k.js +11 -16
  112. package/src/toolchains/wladx/wladx.js +5 -17
  113. package/src/toolchains/z80/binutils.js +5 -11
@@ -0,0 +1,370 @@
1
+ #include "music.h"
2
+ #include "gametank.h"
3
+ #include "note_numbers.h"
4
+ #include "banking.h"
5
+
6
+ #include "bank_nums.h"
7
+ #include "assets_index.h"
8
+
9
+ typedef struct music_state_t {
10
+ const unsigned char* cursor;
11
+ unsigned char bank;
12
+ unsigned char cfg; //file flags
13
+ unsigned char delay;
14
+ const unsigned char* repeat_ptr;
15
+ unsigned char flags; //playback flags
16
+ const Instrument* instruments[NUM_FM_CHANNELS];
17
+ } music_state_t;
18
+
19
+ #define MUSIC_STACK_SIZE 8
20
+
21
+ music_state_t music_state;
22
+ music_state_t music_stack[MUSIC_STACK_SIZE];
23
+ unsigned char music_stack_idx = 0;
24
+
25
+ void push_song_stack() {
26
+ music_stack[music_stack_idx++] = music_state;
27
+ if(music_stack_idx == MUSIC_STACK_SIZE) { music_stack_idx = 0; }
28
+ }
29
+
30
+ void pop_song_stack() {
31
+ if(music_stack_idx == 0) {
32
+ music_stack_idx = MUSIC_STACK_SIZE-1;
33
+ } else {
34
+ --music_stack_idx;
35
+ }
36
+ music_state = music_stack[music_stack_idx];
37
+ load_instrument(0, music_state.instruments[0]);
38
+ load_instrument(0, music_state.instruments[1]);
39
+ load_instrument(0, music_state.instruments[2]);
40
+ load_instrument(0, music_state.instruments[3]);
41
+ }
42
+
43
+ unsigned char channel_masks[NUM_FM_CHANNELS] = {1, 2, 4, 8};
44
+ signed char channel_note_offset[NUM_FM_CHANNELS] = {0, 0, 0, 0};
45
+ unsigned char audio_amplitudes[NUM_FM_OPS] = { 0, 0, 0, 0,
46
+ 0, 0, 0, 0,
47
+ 0, 0, 0, 0,
48
+ 0, 0, 0, 0 };
49
+ unsigned char env_initial[NUM_FM_OPS] = { 0x00, 0x00, 0x00, 0x00,
50
+ 0x00, 0x00, 0x00, 0x00,
51
+ 0x00, 0x00, 0x00, 0x00,
52
+ 0x00, 0x00, 0x00, 0x00 };
53
+ unsigned char env_decay[NUM_FM_OPS] = { 0x00, 0x00, 0x00, 0x00,
54
+ 0x00, 0x00, 0x00, 0x00,
55
+ 0x00, 0x00, 0x00, 0x00,
56
+ 0x00, 0x00, 0x00, 0x00 };
57
+ unsigned char env_sustain[NUM_FM_OPS] = { 0x00, 0x00, 0x00, 0x00,
58
+ 0x00, 0x00, 0x00, 0x00,
59
+ 0x00, 0x00, 0x00, 0x00,
60
+ 0x00, 0x00, 0x00, 0x00 };
61
+
62
+ unsigned char op_transpose[NUM_FM_OPS] = { 0, 0, 0, 0,
63
+ 28, 12, 0, 19,
64
+ 36, 0, 0, 0,
65
+ 0, 0, 0, 0 };
66
+
67
+ #define MUSIC_CFG_VELOCITY 1
68
+ #define MUSIC_CFG_PROGCHANGE 2
69
+
70
+ #define MUSIC_FLAG_POP_AT_END 1
71
+
72
+ const unsigned char* paused_cursor = 0;
73
+ unsigned char paused_bank = 0;
74
+ unsigned char paused_cfg = 0;
75
+ unsigned char paused_delay;
76
+ unsigned char music_mode = REPEAT_NONE;
77
+
78
+ unsigned char music_channel_mask;
79
+ unsigned char percussion_channel_mask;
80
+ unsigned char note_held_mask;
81
+ const unsigned char* sound_effect_ptr[NUM_FM_CHANNELS];
82
+ unsigned char sound_effect_bank[NUM_FM_CHANNELS];
83
+ unsigned char sound_effect_length[NUM_FM_CHANNELS];
84
+ unsigned char saved_feedback_value[NUM_FM_CHANNELS];
85
+ unsigned char sound_effect_priority[NUM_FM_CHANNELS];
86
+
87
+ void init_music() {
88
+ char i;
89
+ music_stack_idx = 0;
90
+ music_state.cursor = 0;
91
+ music_state.delay = 0;
92
+ music_channel_mask = 255;
93
+ note_held_mask = 0;
94
+ for(i = 0; i < NUM_FM_CHANNELS; ++i) {
95
+ sound_effect_length[i] = 0;
96
+ sound_effect_priority[i] = 0;
97
+ }
98
+ stop_music();
99
+ }
100
+
101
+ void load_instrument(char channel, const Instrument* instr) {
102
+ if(instr == ((Instrument*) 0xFFFF)) {
103
+ percussion_channel_mask |= channel_masks[channel];
104
+ return;
105
+ }
106
+ percussion_channel_mask &= ~channel_masks[channel];
107
+ music_state.instruments[channel] = instr;
108
+ channel_note_offset[channel] = instr->transpose;
109
+ aram[FEEDBACK_AMT + channel] = (instr->feedback << 3) + 128;
110
+ channel = channel << 2;
111
+ env_initial[channel] = instr->env_initial[0];
112
+ env_decay[channel] = instr->env_decay[0];
113
+ env_sustain[channel] = instr->env_sustain[0];
114
+ op_transpose[channel] = instr->op_transpose[0];
115
+ ++channel;
116
+ env_initial[channel] = instr->env_initial[1];
117
+ env_decay[channel] = instr->env_decay[1];
118
+ env_sustain[channel] = instr->env_sustain[1];
119
+ op_transpose[channel] = instr->op_transpose[1];
120
+ ++channel;
121
+ env_initial[channel] = instr->env_initial[2];
122
+ env_decay[channel] = instr->env_decay[2];
123
+ env_sustain[channel] = instr->env_sustain[2];
124
+ op_transpose[channel] = instr->op_transpose[2];
125
+ ++channel;
126
+ env_initial[channel] = instr->env_initial[3];
127
+ env_decay[channel] = instr->env_decay[3];
128
+ env_sustain[channel] = instr->env_sustain[3];
129
+ op_transpose[channel] = instr->op_transpose[3];
130
+ }
131
+
132
+ char n_mul;
133
+ void set_note(char ch, char n) {
134
+ n_mul = op_transpose[ch] + n;
135
+ n_mul += n_mul;
136
+ set_audio_param(PITCH_MSB + ch, pitch_table[n_mul]);
137
+ set_audio_param(PITCH_LSB + ch, pitch_table[n_mul + 1]);
138
+ ++ch;
139
+ n_mul = op_transpose[ch] + n;
140
+ n_mul += n_mul;
141
+ set_audio_param(PITCH_MSB + ch, pitch_table[n_mul]);
142
+ set_audio_param(PITCH_LSB + ch, pitch_table[n_mul + 1]);
143
+ ++ch;
144
+ n_mul = op_transpose[ch] + n;
145
+ n_mul += n_mul;
146
+ set_audio_param(PITCH_MSB + ch, pitch_table[n_mul]);
147
+ set_audio_param(PITCH_LSB + ch, pitch_table[n_mul + 1]);
148
+ ++ch;
149
+ n_mul = op_transpose[ch] + n;
150
+ n_mul += n_mul;
151
+ set_audio_param(PITCH_MSB + ch, pitch_table[n_mul]);
152
+ set_audio_param(PITCH_LSB + ch, pitch_table[n_mul + 1]);
153
+ }
154
+
155
+ void play_song(const unsigned char* song, char bank_num, char loop) {
156
+ char n;
157
+ push_song_stack();
158
+ music_state.bank = bank_num;
159
+ push_rom_bank();
160
+ change_rom_bank(music_state.bank);
161
+ music_state.cursor = song;
162
+
163
+ for(n = 0; n < NUM_FM_OPS; ++n) {
164
+ audio_amplitudes[n] = 0;
165
+ set_audio_param(AMPLITUDE+n, 128);
166
+ }
167
+
168
+ switch(loop) {
169
+ case REPEAT_NONE:
170
+ music_state.repeat_ptr = 0;
171
+ music_mode = REPEAT_NONE;
172
+ music_state.flags = 0;
173
+ break;
174
+ case REPEAT_LOOP:
175
+ music_state.repeat_ptr = music_state.cursor;
176
+ music_mode = REPEAT_LOOP;
177
+ music_state.flags = 0;
178
+ break;
179
+ case REPEAT_RESUME:
180
+ music_state.flags = MUSIC_FLAG_POP_AT_END;
181
+ break;
182
+ }
183
+
184
+ if(music_state.cursor) {
185
+ percussion_channel_mask = 0;
186
+ music_state.cfg = *(music_state.cursor++);
187
+ load_instrument(0, get_instrument_ptr(*(music_state.cursor++)));
188
+ load_instrument(1, get_instrument_ptr(*(music_state.cursor++)));
189
+ load_instrument(2, get_instrument_ptr(*(music_state.cursor++)));
190
+ load_instrument(3, get_instrument_ptr(*(music_state.cursor++)));
191
+ music_state.delay = *(music_state.cursor++);
192
+ }
193
+
194
+ pop_rom_bank();
195
+ }
196
+
197
+ void pause_music() {
198
+ push_song_stack();
199
+ music_state.cursor = 0;
200
+ note_held_mask = 0;
201
+ }
202
+
203
+ void unpause_music() {
204
+ pop_song_stack();
205
+ }
206
+
207
+ void tick_music() {
208
+ static unsigned char n, noteMask, ch;
209
+ register unsigned char a, op;
210
+ push_rom_bank();
211
+ for(n = 0; n < NUM_FM_CHANNELS; ++n) {
212
+ if(sound_effect_length[n]) {
213
+ --sound_effect_length[n];
214
+ if(sound_effect_length[n]) {
215
+
216
+ change_rom_bank(sound_effect_bank[n]);
217
+
218
+ op = n << 2;
219
+ set_audio_param(AMPLITUDE + op, (*(sound_effect_ptr[n]+0) << 3) + 128);
220
+ a = *(sound_effect_ptr[n]+4) << 1;
221
+ set_audio_param(PITCH_MSB + op, pitch_table[a]);
222
+ set_audio_param(PITCH_LSB + op, pitch_table[a+1]);
223
+
224
+ ++op;
225
+ set_audio_param(AMPLITUDE + op, (*(sound_effect_ptr[n]+1) << 3) + 128);
226
+ a = *(sound_effect_ptr[n]+5) << 1;
227
+ set_audio_param(PITCH_MSB + op, pitch_table[a]);
228
+ set_audio_param(PITCH_LSB + op, pitch_table[a+1]);
229
+
230
+ ++op;
231
+ set_audio_param(AMPLITUDE + op, (*(sound_effect_ptr[n]+2) << 3) + 128);
232
+ a = *(sound_effect_ptr[n]+6) << 1;
233
+ set_audio_param(PITCH_MSB + op, pitch_table[a]);
234
+ set_audio_param(PITCH_LSB + op, pitch_table[a+1]);
235
+
236
+ ++op;
237
+ set_audio_param(AMPLITUDE + op, (*(sound_effect_ptr[n]+3) << 3) + 128);
238
+ a = *(sound_effect_ptr[n]+7) << 1;
239
+ set_audio_param(PITCH_MSB + op, pitch_table[a]);
240
+ set_audio_param(PITCH_LSB + op, pitch_table[a+1]);
241
+
242
+ sound_effect_ptr[n] += 8;
243
+
244
+ } else {
245
+ op = n << 2;
246
+ set_audio_param(AMPLITUDE+(op+3), 128);
247
+ aram[FEEDBACK_AMT + n] = saved_feedback_value[n];
248
+ music_channel_mask |= channel_masks[n];
249
+ sound_effect_priority[n] = 0;
250
+ }
251
+ }
252
+ }
253
+
254
+ change_rom_bank(music_state.bank);
255
+ op = 0;
256
+ for(ch = 1; ch < 16; ch = ch << 1) {
257
+ if(ch & ~(music_channel_mask & note_held_mask)) {
258
+ op+=4;
259
+ continue;
260
+ }
261
+ for(a = 0; a < 4; ++a) {
262
+ if(((env_sustain[op] - audio_amplitudes[op]) ^ (env_decay[op])) & 0x80) {
263
+ audio_amplitudes[op] -= env_decay[op];
264
+ } else {
265
+ audio_amplitudes[op] = env_sustain[op];
266
+ }
267
+ set_audio_param(AMPLITUDE+op, (audio_amplitudes[op] >> 1) + 128);
268
+ ++op;
269
+ }
270
+ }
271
+
272
+ if(music_state.cursor) {
273
+ loadAudioEvent:
274
+ if(music_state.delay > 0) {
275
+ music_state.delay--;
276
+ } else {
277
+ noteMask = *(music_state.cursor++);
278
+ for(ch = 0; ch < NUM_FM_CHANNELS; ++ch) {
279
+ if(channel_masks[ch] & noteMask) {
280
+ n = *(music_state.cursor++);
281
+ if(music_state.cfg & MUSIC_CFG_VELOCITY)
282
+ a = *(music_state.cursor++);
283
+ if(channel_masks[ch] & percussion_channel_mask) {
284
+ if(n > 0) play_sound_effect(n - 1, ch);
285
+ } else if(channel_masks[ch] & music_channel_mask) {
286
+ op = ch << 2;
287
+ if(n > 0) {
288
+
289
+ set_note(op, n + channel_note_offset[ch]);
290
+ audio_amplitudes[op] = env_initial[op];
291
+ set_audio_param(AMPLITUDE+op, (audio_amplitudes[op] >> 1) + 128);
292
+ ++op;
293
+ audio_amplitudes[op] = env_initial[op];
294
+ set_audio_param(AMPLITUDE+op, (audio_amplitudes[op] >> 1) + 128);
295
+ ++op;
296
+ audio_amplitudes[op] = env_initial[op];
297
+ set_audio_param(AMPLITUDE+op, (audio_amplitudes[op] >> 1) + 128);
298
+ ++op;
299
+ if(music_state.cfg & MUSIC_CFG_VELOCITY)
300
+ audio_amplitudes[op] = a;
301
+ else
302
+ audio_amplitudes[op] = env_initial[op];
303
+ set_audio_param(AMPLITUDE+op, (audio_amplitudes[op] >> 1) + 128);
304
+ } else {
305
+ audio_amplitudes[op+3] = 0;
306
+ set_audio_param(AMPLITUDE+op+3, 128);
307
+ }
308
+ }
309
+ if(n) {
310
+ note_held_mask |= channel_masks[ch];
311
+ } else {
312
+ note_held_mask &= ~channel_masks[ch];
313
+ }
314
+ }
315
+ }
316
+ music_state.delay = *(music_state.cursor++);
317
+ if(music_state.delay == 0) {
318
+ if(music_state.flags & MUSIC_FLAG_POP_AT_END) {
319
+ pop_song_stack();
320
+ } else {
321
+ music_state.cursor = music_state.repeat_ptr;
322
+ if(music_state.cursor) {
323
+ music_state.cursor+=5; //skip cfg and instruments
324
+ music_state.delay = *(music_state.cursor++);
325
+ goto loadAudioEvent;
326
+ } else {
327
+ silence_all_channels();
328
+ }
329
+ }
330
+ } else {
331
+ --music_state.delay;
332
+ }
333
+ }
334
+ }
335
+
336
+ flush_audio_params();
337
+ pop_rom_bank();
338
+ }
339
+
340
+ void silence_all_channels() {
341
+ char n;
342
+ for(n = 0; n < NUM_FM_OPS; ++n) {
343
+ audio_amplitudes[n] = 0;
344
+ set_audio_param(AMPLITUDE+n, 128);
345
+ }
346
+ note_held_mask = 0;
347
+ }
348
+
349
+ void stop_music() {
350
+ music_state.cursor = 0;
351
+ silence_all_channels();
352
+ }
353
+
354
+ void play_sound_effect(char sfx_id, char channel) {
355
+ static char priority;
356
+ priority = channel & 0xF0;
357
+ channel &= 0x03;
358
+ if(priority < sound_effect_priority[channel]) return;
359
+ sound_effect_priority[channel] = priority;
360
+ push_rom_bank();
361
+ change_rom_bank(BANK_LOADERS);
362
+ sound_effect_bank[channel] = ASSET__sfx_bank_table[sfx_id];
363
+ sound_effect_ptr[channel] = ASSET__sfx_ptr_table[sfx_id];
364
+ change_rom_bank(sound_effect_bank[channel]);
365
+ sound_effect_length[channel] = *(sound_effect_ptr[channel]++) + 1;
366
+ saved_feedback_value[channel] = aram[FEEDBACK_AMT + channel];
367
+ aram[FEEDBACK_AMT + channel] = *(sound_effect_ptr[channel]++);
368
+ music_channel_mask &= ~(channel_masks[channel]);
369
+ pop_rom_bank();
370
+ }
@@ -0,0 +1,35 @@
1
+ #ifndef MUSIC_H
2
+ #define MUSIC_H
3
+
4
+ #include "audio_coprocessor.h"
5
+ #include "instruments.h"
6
+
7
+ #define REPEAT_NONE 0
8
+ #define REPEAT_LOOP 1
9
+ #define REPEAT_RESUME 2
10
+
11
+ #define SFX_PRIORITY(x) (x<<4)
12
+
13
+ void init_music();
14
+
15
+ void play_song(const unsigned char* song, char bank_num, char loop);
16
+
17
+ void tick_music();
18
+
19
+ void silence_all_channels();
20
+
21
+ void stop_music();
22
+
23
+ void pause_music();
24
+
25
+ void unpause_music();
26
+
27
+ void set_note(char ch, char n);
28
+
29
+ extern unsigned char audio_amplitudes[NUM_FM_OPS];
30
+
31
+ void load_instrument(char channel, const Instrument* instr);
32
+
33
+ void play_sound_effect(char sfx_id, char channel);
34
+
35
+ #endif
@@ -0,0 +1,132 @@
1
+ #ifndef NOTE_NUMBERS_H
2
+ #define NOTE_NUMBERS_H
3
+
4
+ #define RST 0
5
+ #define NUP 128
6
+
7
+ #define Cn1 24
8
+ #define Cs1 25
9
+ #define Df1 25
10
+ #define Dn1 26
11
+ #define Ds1 27
12
+ #define Ef1 27
13
+ #define En1 28
14
+ #define Fn1 29
15
+ #define Fs1 30
16
+ #define Gf1 30
17
+ #define Gn1 31
18
+ #define Gs1 32
19
+ #define Af1 32
20
+ #define An1 33
21
+ #define As1 34
22
+ #define Bf1 34
23
+ #define Bn1 35
24
+
25
+ #define Cn2 36
26
+ #define Cs2 37
27
+ #define Df2 37
28
+ #define Dn2 38
29
+ #define Ds2 39
30
+ #define Ef2 39
31
+ #define En2 40
32
+ #define Fn2 41
33
+ #define Fs2 42
34
+ #define Gf2 42
35
+ #define Gn2 43
36
+ #define Gs2 44
37
+ #define Af2 44
38
+ #define An2 45
39
+ #define As2 46
40
+ #define Bf2 46
41
+ #define Bn2 47
42
+
43
+ #define Cn3 48
44
+ #define Cs3 49
45
+ #define Df3 49
46
+ #define Dn3 50
47
+ #define Ds3 51
48
+ #define Ef3 51
49
+ #define En3 52
50
+ #define Fn3 53
51
+ #define Fs3 54
52
+ #define Gf3 54
53
+ #define Gn3 55
54
+ #define Gs3 56
55
+ #define Af3 56
56
+ #define An3 57
57
+ #define As3 58
58
+ #define Bf3 58
59
+ #define Bn3 59
60
+
61
+ #define Cn4 60
62
+ #define Cs4 61
63
+ #define Df4 61
64
+ #define Dn4 62
65
+ #define Ds4 63
66
+ #define Ef4 63
67
+ #define En4 64
68
+ #define Fn4 65
69
+ #define Fs4 66
70
+ #define Gf4 66
71
+ #define Gn4 67
72
+ #define Gs4 68
73
+ #define Af4 68
74
+ #define An4 69
75
+ #define As4 70
76
+ #define Bf4 70
77
+ #define Bn4 71
78
+
79
+ #define Cn5 72
80
+ #define Cs5 73
81
+ #define Df5 73
82
+ #define Dn5 74
83
+ #define Ds5 75
84
+ #define Ef5 75
85
+ #define En5 76
86
+ #define Fn5 77
87
+ #define Fs5 78
88
+ #define Gf5 78
89
+ #define Gn5 79
90
+ #define Gs5 80
91
+ #define Af5 80
92
+ #define An5 81
93
+ #define As5 82
94
+ #define Bf5 82
95
+ #define Bn5 83
96
+
97
+ #define Cn6 84
98
+ #define Cs6 85
99
+ #define Df6 85
100
+ #define Dn6 86
101
+ #define Ds6 87
102
+ #define Ef6 87
103
+ #define En6 88
104
+ #define Fn6 89
105
+ #define Fs6 90
106
+ #define Gf6 90
107
+ #define Gn6 91
108
+ #define Gs6 92
109
+ #define Af6 92
110
+ #define An6 93
111
+ #define As6 94
112
+ #define Bf6 94
113
+ #define Bn6 95
114
+
115
+ #define Cn7 96
116
+ #define Cs7 97
117
+ #define Df7 97
118
+ #define Dn7 98
119
+ #define Ds7 99
120
+ #define Ef7 99
121
+ #define En7 100
122
+ #define Fn7 101
123
+ #define Fs7 102
124
+ #define Gf7 102
125
+ #define Gn7 103
126
+ #define Gs7 104
127
+ #define Af7 104
128
+ #define An7 105
129
+ #define As7 106
130
+ #define Bf7 106
131
+ #define Bn7 107
132
+ #endif
@@ -0,0 +1,29 @@
1
+ #include "gametank.h"
2
+
3
+ //must be power of 2
4
+ #define BANK_STACK_SIZE 8
5
+ //must be BANK_STACK_SIZE-1
6
+ #define BANK_WRAP_MASK 7
7
+
8
+ unsigned char romBankMirror;
9
+ unsigned char romBankStack[BANK_STACK_SIZE];
10
+ unsigned char romBankStackIdx;
11
+
12
+ void bank_shift_out(unsigned char banknum);
13
+
14
+ void change_rom_bank(unsigned char banknum) {
15
+ if(banknum != romBankMirror)
16
+ bank_shift_out(banknum);
17
+ }
18
+
19
+ void push_rom_bank() {
20
+ romBankStackIdx = (romBankStackIdx + 1) & BANK_WRAP_MASK;
21
+ romBankStack[romBankStackIdx] = romBankMirror;
22
+ }
23
+
24
+ void pop_rom_bank() {
25
+ change_rom_bank(romBankStack[romBankStackIdx]);
26
+ if(romBankStackIdx == 0)
27
+ romBankStackIdx = BANK_STACK_SIZE;
28
+ --romBankStackIdx;
29
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef BANKING_H
2
+ #define BANKING_H
3
+
4
+ void push_rom_bank();
5
+ void change_rom_bank(unsigned char banknum);
6
+ void pop_rom_bank();
7
+
8
+ #endif
@@ -0,0 +1,41 @@
1
+ .export _bank_shift_out
2
+ .import _romBankMirror
3
+
4
+ ; ---------------------------------------------------------------
5
+ ; void __near__ bank_shift_out ()
6
+ ; ---------------------------------------------------------------
7
+
8
+ OutBits = $2801
9
+
10
+ .segment "CODE"
11
+
12
+ .proc _bank_shift_out: near
13
+ sta _romBankMirror;
14
+ stz OutBits
15
+ clc
16
+ rol
17
+ rol
18
+ rol
19
+ tay
20
+
21
+ .repeat 7
22
+ and #2
23
+ sta OutBits
24
+ ora #1
25
+ sta OutBits
26
+ tya
27
+ rol
28
+ tay
29
+ .endrepeat
30
+
31
+ and #2
32
+ sta OutBits
33
+ ora #1
34
+ sta OutBits
35
+ ora #4
36
+ sta OutBits
37
+ stz OutBits
38
+
39
+ rts
40
+
41
+ .endproc