diff --git a/game-ctrl/buttons.c b/game-ctrl/buttons.c index fbbdb08..b52a99d 100644 --- a/game-ctrl/buttons.c +++ b/game-ctrl/buttons.c @@ -84,27 +84,22 @@ void buttonsExec(void *handle) { if (buttonsMoveLeftPressed()) { stoneMoveLeft(); - soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsMoveRightPressed()) { stoneMoveRight(); - soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsRotateLeftPressed()) { stoneRotateLeft(); - soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsRotateRightPressed()) { stoneRotateRight(); - soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsMoveDownPressed()) { stoneMoveDown(); - soundCtrl(SOUND_MOTION); buttonPressed = 1; } diff --git a/game-ctrl/config.c b/game-ctrl/config.c index 37bd0dd..a5e69b2 100644 --- a/game-ctrl/config.c +++ b/game-ctrl/config.c @@ -7,9 +7,11 @@ #include "eeprom.h" #include "display.h" #include "shapes.h" +#include "sound.h" static bool configChanged = false; +static bool muted = false; static void configHandleFlash() { uint8_t color = eepromReadFlashColor(); @@ -50,7 +52,26 @@ static void configHandleBrightness() { } } -void (*configHandler[])(void) = { configHandleFlash, configHandleResetHighScore, configHandleBrightness }; +static void configHandleAmplitude() { + displaySetValue(eepromReadAmplitude()); + if (muted) { + muted = false; + soundCtrl(SOUND_START); + soundCtrl(SOUND_UNMUTE); + } + + if (buttonsConfig2Pressed()) { + configChanged = true; + uint8_t amplitude = eepromReadAmplitude() + 1; + if (amplitude > 15) { + amplitude = 0; + } + eepromSetAmplitude(amplitude); + soundCtrl(SOUND_COMMAND + SOUND_SUBCMD_AMPLITUDE + amplitude); + } +} + +void (*configHandler[])(void) = { configHandleFlash, configHandleResetHighScore, configHandleBrightness,configHandleAmplitude }; void configExec(void *handle) { @@ -62,7 +83,14 @@ void configExec(void *handle) { miniCanvasClear(); canvasClear(); - miniCanvasSetPixel(configState, 0, _red); + if (! muted) { + muted = true; + soundCtrl(SOUND_MUTE); + } + + uint8_t row = configState / 3; + uint8_t column = configState % 3; + miniCanvasSetPixel(column, row, _red); } if (buttonsConfig1Pressed()) { diff --git a/game-ctrl/eeprom.c b/game-ctrl/eeprom.c index d8a42b6..87be004 100644 --- a/game-ctrl/eeprom.c +++ b/game-ctrl/eeprom.c @@ -4,7 +4,7 @@ #include "spi.h" -#define MAGIC 0xb001 +#define MAGIC 0xb002 #define HIGHSCORE_ADDR 0x00 #define DUMMY 0x00 #define CMD_READ 0b00000011 @@ -18,6 +18,7 @@ typedef struct { uint16_t highScore; uint8_t flashColor; uint8_t brightness; + uint8_t amplitude; } t_configBlock; typedef union { @@ -93,3 +94,11 @@ void eepromSetBrightness(uint8_t v) { buf.v.brightness = v; } +uint8_t eepromReadAmplitude() { + return buf.v.amplitude; +} + +void eepromSetAmplitude(uint8_t v) { + buf.v.amplitude = v; +} + diff --git a/game-ctrl/eeprom.h b/game-ctrl/eeprom.h index dde1b9e..aa8f8e2 100644 --- a/game-ctrl/eeprom.h +++ b/game-ctrl/eeprom.h @@ -5,13 +5,15 @@ void eepromInit(); +void eepromCommit(); uint16_t eepromReadHighScore(); void eepromSetHighScore(uint16_t v); uint8_t eepromReadFlashColor(); void eepromSetFlashColor(uint8_t v); uint8_t eepromReadBrightness(); void eepromSetBrightness(uint8_t v); -void eepromCommit(); +uint8_t eepromReadAmplitude(); +void eepromSetAmplitude(uint8_t v); diff --git a/game-ctrl/game.c b/game-ctrl/game.c index eeb15ce..583c86a 100644 --- a/game-ctrl/game.c +++ b/game-ctrl/game.c @@ -24,13 +24,15 @@ static uint16_t delayFactor(uint16_t level) { } typedef enum { + e_BootWait, e_Start, e_NewStone, e_Down, e_DownDelay, e_ClearRowInit, e_ClearRowNext, e_ClearRowCheck, e_ClearRowFlash, e_ClearRowFlashDelay, e_ClearRowWipe, e_GameOver, e_GameOverFill, e_GameOverWipe, e_GameOverDelay } state_t; void gameExec(void *handle) { - static state_t state = e_Start; + static state_t state = e_BootWait; + static uint16_t bootWaitTime = 2500 / GAME_CYCLE_TIME; static uint8_t gameOverDelay; static uint8_t rowIndex; static uint16_t proceedDelay; @@ -46,6 +48,12 @@ void gameExec(void *handle) { #endif // --- engine begin ------------------------------------------------------- switch (state) { + case e_BootWait: + bootWaitTime -= 1; + if (bootWaitTime == 0) { + state = e_Start; + } + break; // --- phase: game -------------------------------------------------------- case e_Start: canvasClear(); diff --git a/game-ctrl/main.c b/game-ctrl/main.c index ccde948..d1ee30a 100644 --- a/game-ctrl/main.c +++ b/game-ctrl/main.c @@ -14,6 +14,7 @@ #include "display.h" #include "eeprom.h" #include "config.h" +#include "sound.h" int main() { @@ -34,6 +35,7 @@ int main() { displayInit(); myRandInit(); canvasInit(); + soundInit(); buttonsInit(); if (isConfigMode()) { diff --git a/game-ctrl/sound.c b/game-ctrl/sound.c index 1cde5e0..94da718 100644 --- a/game-ctrl/sound.c +++ b/game-ctrl/sound.c @@ -1,10 +1,12 @@ #include #include "sound.h" #include "spi.h" +#include "eeprom.h" void soundInit() { + soundCtrl(SOUND_COMMAND + SOUND_SUBCMD_AMPLITUDE + eepromReadAmplitude()); } diff --git a/sound-driver/Makefile b/sound-driver/Makefile index ecdce2a..35b038d 100644 --- a/sound-driver/Makefile +++ b/sound-driver/Makefile @@ -12,7 +12,7 @@ ASFLAGS=$(COMMONFLAGS) -D__ASSEMBLER__ LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include -$(ARTIFACT).elf: main.o scheduler.o spi.o spi_init.o sequencer.o melody_tetris.o melody_tusch1.o psg.o mute.o melody_pling.o +$(ARTIFACT).elf: main.o scheduler.o spi.o spi_init.o sequencer.o melody_tetris.o melody_tusch1.o psg.o mute.o melody_pling.o config.o $(CC) -o $@ $(LDFLAGS) $^ $(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt diff --git a/sound-driver/config.c b/sound-driver/config.c new file mode 100644 index 0000000..3112bd6 --- /dev/null +++ b/sound-driver/config.c @@ -0,0 +1,19 @@ +#include +#include "config.h" + + +typedef struct { + uint8_t amplitude; +} config_t; + +config_t config; + + +void configSetAmplitude(uint8_t v) { + config.amplitude = v; +} + +uint8_t configGetAmplitude() { + return config.amplitude; +} + diff --git a/sound-driver/config.h b/sound-driver/config.h new file mode 100644 index 0000000..f3e4b95 --- /dev/null +++ b/sound-driver/config.h @@ -0,0 +1,11 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + + +#include + +void configSetAmplitude(uint8_t v); +uint8_t configGetAmplitude(); + + +#endif // _CONFIG_H_ diff --git a/sound-driver/melody_pling.c b/sound-driver/melody_pling.c index ea02f9b..ebb583e 100644 --- a/sound-driver/melody_pling.c +++ b/sound-driver/melody_pling.c @@ -1,8 +1,11 @@ #include +#include #include #include "psg.h" #include "sequencer.h" #include "scheduler.h" +#include "config.h" + const t_tone plingVoice1[] = { { .octave = e_O_5, .note = e_C, .length = e_L_1_16, .legato = false, .staccato = false }, @@ -18,13 +21,15 @@ const t_tone plingVoice1[] = { }; t_melodies pling = { - .melodies = { { .amplitude = 12, .tones = plingVoice1 } }, + .melodies = { { .tones = plingVoice1 } }, + .amplitude = 12, .numOfMelodies = 1, .pace = 200, .chip = 1 }; void playPling() { + pling.amplitude = MIN((configGetAmplitude() + 4), 15); sequencerPlayMelodies(&pling); } diff --git a/sound-driver/melody_tetris.c b/sound-driver/melody_tetris.c index 75a7e3f..f06bff6 100644 --- a/sound-driver/melody_tetris.c +++ b/sound-driver/melody_tetris.c @@ -1,8 +1,10 @@ #include +#include #include #include "psg.h" #include "sequencer.h" #include "scheduler.h" +#include "config.h" /* @@ -924,7 +926,8 @@ const t_tone voice3[] = { #define INITIAL_PACE 160 t_melodies tetrisTheme = { - .melodies = { { .amplitude = 8, .tones = voice1 }, { .amplitude = 8, .tones = voice2 }, { .amplitude = 8, .tones = voice3 } }, + .melodies = { { .tones = voice1 }, { .tones = voice2 }, { .tones = voice3 } }, + .amplitude = 8, .numOfMelodies = 3, .pace = INITIAL_PACE, .chip = 0 @@ -932,6 +935,7 @@ t_melodies tetrisTheme = { void playMelodyTetris() { tetrisTheme.pace = INITIAL_PACE; // reset to start value each time + tetrisTheme.amplitude = MIN((configGetAmplitude() + 4), 15); sequencerPlayMelodies(&tetrisTheme); } diff --git a/sound-driver/melody_tetris.h b/sound-driver/melody_tetris.h index f9d7394..37f6a7e 100644 --- a/sound-driver/melody_tetris.h +++ b/sound-driver/melody_tetris.h @@ -5,5 +5,6 @@ void playMelodyTetris(); void stopMelodyTetris(); void playMelodyTetrisFaster(); +void playMelodyTetrisAmplitude(uint8_t a); #endif // _MELODY_TETRIS_H_ diff --git a/sound-driver/melody_tusch1.c b/sound-driver/melody_tusch1.c index 043d1a2..320b2e4 100644 --- a/sound-driver/melody_tusch1.c +++ b/sound-driver/melody_tusch1.c @@ -1,9 +1,10 @@ #include +#include #include #include "psg.h" #include "sequencer.h" #include "scheduler.h" -#include "melody_tetris.h" +#include "config.h" const t_tone tusch1voice1[] = { { .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = true }, @@ -72,15 +73,16 @@ const t_tone tusch1voice3[] = { }; t_melodies tusch1 = { - .melodies = { { .amplitude = 12, .tones = tusch1voice1 }, { .amplitude = 12, .tones = tusch1voice2 }, { .amplitude = 12, .tones = tusch1voice3 } }, + .melodies = { { .tones = tusch1voice1 }, { .tones = tusch1voice2 }, { .tones = tusch1voice3 } }, + .amplitude = 12, .numOfMelodies = 3, .pace = 200, .chip = 1 }; void playTusch1() { + tusch1.amplitude = MIN((configGetAmplitude() + 4), 15); sequencerPlayMelodies(&tusch1); -// playMelodyTetrisFaster(); } diff --git a/sound-driver/sequencer.c b/sound-driver/sequencer.c index 1e4cf14..573ea6f 100644 --- a/sound-driver/sequencer.c +++ b/sound-driver/sequencer.c @@ -59,7 +59,7 @@ void sequencerExec(void *handle) { if (melody->tones[melody->idx].length == e_L_EndMark) { melody->idx = 0; } - psgPlayTone(melodies->chip, channel, melody->amplitude, melody->tones[melody->idx].octave, melody->tones[melody->idx].note); + psgPlayTone(melodies->chip, channel, melodies->amplitude, melody->tones[melody->idx].octave, melody->tones[melody->idx].note); melody->lengthCnt = (melody->tones[melody->idx].staccato) ? (calcLength(melodies, melody->tones[melody->idx].length) / 2) : calcLength(melodies, melody->tones[melody->idx].length); diff --git a/sound-driver/sequencer.h b/sound-driver/sequencer.h index 7411ae9..c46a3c7 100644 --- a/sound-driver/sequencer.h +++ b/sound-driver/sequencer.h @@ -44,7 +44,6 @@ typedef struct { uint16_t idx; uint16_t lengthCnt; t_sequencerState state; - uint8_t amplitude; const t_tone *tones; } t_melody; @@ -53,6 +52,7 @@ typedef struct { typedef struct { uint8_t slotMask; uint8_t chip; + uint8_t amplitude; uint8_t taskId; uint16_t quarterLength; uint8_t numOfMelodies; diff --git a/sound-driver/soundCodes.h b/sound-driver/soundCodes.h index 72f4824..48ecba4 100644 --- a/sound-driver/soundCodes.h +++ b/sound-driver/soundCodes.h @@ -8,7 +8,9 @@ #define SOUND_GAMEOVER 0x08 #define SOUND_FANFARE 0x10 #define SOUND_LOCK 0x20 -#define SOUND_MOTION 0x40 -#define SOUND_PLING 0x80 +#define SOUND_PLING 0x40 +#define SOUND_COMMAND 0x80 + +#define SOUND_SUBCMD_AMPLITUDE 0x40 #endif // _SOUND_CODES_H_ diff --git a/sound-driver/spi.S b/sound-driver/spi.S index 6b9288f..ef57f24 100644 --- a/sound-driver/spi.S +++ b/sound-driver/spi.S @@ -6,12 +6,21 @@ receive_isr: bit #UCB0RXIFG, &UC0IFG jz receive_isr_no_data + bit #SOUND_COMMAND, &cmd + jnz receive_isr_no_data bis UCB0RXBUF, &cmd receive_isr_no_data: reti .global spiCmdHandler spiCmdHandler: +spiCmdHandler_0: + bit #SOUND_COMMAND, &cmd + jz spiCmdHandler_1 + ;; insert a call here + call #spiCommandDispatcher + mov.b #0, &cmd + ret spiCmdHandler_1: bit #SOUND_MUTE, &cmd jz spiCmdHandler_2 @@ -44,11 +53,6 @@ spiCmdHandler_6: ;; insert a call here bic #SOUND_LOCK, &cmd spiCmdHandler_7: - bit #SOUND_MOTION, &cmd - jz spiCmdHandler_8 - ;; insert a call here - bic #SOUND_MOTION, &cmd -spiCmdHandler_8: bit #SOUND_PLING, &cmd jz spiCmdHandler_end call #playPling diff --git a/sound-driver/spi_init.c b/sound-driver/spi_init.c index fdef72c..ddcf472 100644 --- a/sound-driver/spi_init.c +++ b/sound-driver/spi_init.c @@ -4,9 +4,10 @@ #include "scheduler.h" #include "spi.h" #include "soundCodes.h" +#include "config.h" -uint8_t cmd; +volatile uint8_t cmd; void spiInit() { // SPI slave @@ -25,7 +26,14 @@ void spiInit() { UC0IE |= UCB0RXIE; cmd = SOUND_IDLE; - schAdd(spiCmdHandler, NULL, 0, 100); + schAdd(spiCmdHandler, NULL, 0, 5); } +void spiCommandDispatcher() { + cmd &= ~SOUND_COMMAND; + if (cmd & SOUND_SUBCMD_AMPLITUDE) { + cmd &= ~SOUND_SUBCMD_AMPLITUDE; + configSetAmplitude(cmd); + } +}