123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- #include <SPI.h>
- #include <GD.h>
- // ----------------------------------------------------------------------
- // controller: buttons on Arduino pins 3,4,5,6 with 7 grounded
- // ----------------------------------------------------------------------
- static void controller_init()
- {
- // Configure input pins with internal pullups
- byte i;
- for (i = 3; i < 7; i++) {
- pinMode(i, INPUT);
- digitalWrite(i, HIGH);
- }
- // drive pin 7 low
- pinMode(7, OUTPUT);
- digitalWrite(7, 0);
- }
- #define CONTROL_LEFT 1
- #define CONTROL_RIGHT 2
- #define CONTROL_UP 4
- #define CONTROL_DOWN 8
- static byte controller_sense()
- {
- byte r = 0;
- if (!digitalRead(5))
- r |= CONTROL_DOWN;
- if (!digitalRead(4))
- r |= CONTROL_UP;
- if (!digitalRead(6))
- r |= CONTROL_LEFT;
- if (!digitalRead(3))
- r |= CONTROL_RIGHT;
- return r;
- }
- #define FLOCAL 2
- #define SEL_local() digitalWrite(FLOCAL, LOW)
- #define UNSEL_local() digitalWrite(FLOCAL, HIGH)
- struct dirent {
- char name[12];
- uint16_t length;
- uint32_t addr;
- };
- static uint32_t flash_readn(byte *dst, uint32_t src, size_t n)
- {
- SEL_local();
- SPI.transfer(0x03);
- SPI.transfer((byte)(src >> 16));
- SPI.transfer((byte)(src >> 8));
- SPI.transfer((byte)(src >> 0));
- while (n--) {
- *dst++ = SPI.transfer(0);
- src++;
- if ((511 & (uint16_t)src) == 264)
- src = src - 264 + 512;
- }
- UNSEL_local();
- return src;
- }
- uint16_t samp_len;
- uint32_t samp_ptr;
- static dirent de;
- static byte find_name(uint32_t &ptr, uint16_t &len, uint32_t dirptr, char *name)
- {
- while (true) {
- dirptr = flash_readn((byte*)&de, dirptr, sizeof(de));
- if (de.name[0] == 0)
- return 0; // end of dir, no match found
- if (strcmp(de.name, name) == 0) {
- len = de.length;
- ptr = de.addr;
- return 1;
- }
- }
- }
- static byte ninstruments;
- static dirent instruments[32];
- struct active {
- byte instrument;
- uint32_t addr;
- uint16_t pos, length;
- uint16_t x, y;
- };
- #define NACTIVE 3
- static active playing[NACTIVE];
- struct active *findidle()
- {
- byte i;
- for (i = 0; i < NACTIVE; i++)
- if (playing[i].addr == 0)
- return &playing[i];
- return NULL;
- }
- static void kickoff(byte i)
- {
- active *p = findidle();
- if (p) {
- p->addr = instruments[i].addr;
- p->pos = 0;
- p->length = instruments[i].length;
- p->x = 0;
- p->y = 16 + 16 * i;
- }
- }
- static void fromflash(uint16_t dst, uint32_t src, uint16_t len)
- {
- while (len--) {
- byte v;
- src = flash_readn(&v, src, 1);
- GD.wr(dst++, v);
- }
- }
- static byte sprstr(int x, int y, byte spr, const char *txt)
- {
- char c;
- while ((c = *txt++) != 0) {
- GD.sprite(spr++, x, y, (c - ' ') >> 2, 8 + ((c & 3) << 1), 0);
- x += 11;
- }
- return spr;
- }
- // add all samples from dir
- void add_samples(uint32_t dir)
- {
- dirent *pi = &instruments[ninstruments];
- while (dir = flash_readn((byte*)pi, dir, sizeof(*pi)), pi->name[0]) {
- pi++, ninstruments++;
- }
- }
- void setup()
- {
- Serial.begin(1000000); // JCB
- controller_init();
- GD.begin();
- GD.ascii();
- pinMode(FLOCAL, OUTPUT);
- UNSEL_local();
- GD.wr(IOMODE, 'F');
- uint32_t assetroot = 512L * 640;
- uint32_t dk;
- uint16_t dkl;
- find_name(dk, dkl, assetroot, "voice");
- add_samples(dk);
- find_name(dk, dkl, assetroot, "drumkit");
- add_samples(dk);
- byte i;
- for (i = 0; i < ninstruments; i++) {
- byte x = (50 - strlen(instruments[i].name)) >> 1;
- GD.putstr(x, 2 + i, instruments[i].name);
- }
- uint32_t sd;
- uint16_t sdl;
- if (1) {
- find_name(dk, dkl, assetroot, "pickups");
- find_name(sd, sdl, dk, "pal");
- fromflash(RAM_SPRPAL, sd, sdl);
- find_name(sd, sdl, dk, "img");
- fromflash(RAM_SPRIMG, sd, sdl);
- }
- }
- #include "soundbuffer.h"
- #define SOUNDBUFFER 0x3f00
- int cursor;
- void loop()
- {
- GD.microcode(soundbuffer_code, sizeof(soundbuffer_code));
- byte writepointer = 0;
- for (;;) {
- active *p;
- byte i;
- byte readpointer = GD.rd(COMM+0);
- byte fullness = writepointer - readpointer;
- while (fullness < 254) {
- char total = 0;
- for (p = playing, i = 0; i < NACTIVE; p++, i++) {
- if (p->addr) {
- char v;
- p->addr = flash_readn((byte*)&v, p->addr, 1);
- total += (v >> 1);
- if (++p->pos >= p->length)
- p->addr = 0;
- }
- }
- GD.wr(SOUNDBUFFER + writepointer++, total);
- fullness++;
- }
- GD.waitvblank();
- GD.sprite(0, 142, 11 + 8 * cursor, 47, 0, 0);
- GD.sprite(1, 238, 11 + 8 * cursor, 47, 0, 2);
- static byte prev;
- byte press;
- press = controller_sense();
- press = random(16);
- if (prev == 0) {
- if (press & CONTROL_DOWN)
- cursor = min(ninstruments - 1, cursor + 1);
- if (press & CONTROL_UP)
- cursor = max(0, cursor - 1);
- if (press & (CONTROL_RIGHT | CONTROL_LEFT))
- kickoff(cursor);
- }
- prev = press;
- }
- }
|