diff --git a/README.md b/README.md index 37e8047..92047d6 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,20 @@ This was ported from the [TWANG fork](https://github.com/bdring/TWANG) by bdring - **SSID:** TWANG_AP - **Password:** esp32rocks - **URL:** 192.168.4.1 +- You can update these settings over wifi + - LED Brightness + - Audio Volume + - Joystick Deadzone (removes drift) + - Attack Threshold (twang sensitivity) + - Lives Per Level -**Coming Soon:** -- Wireless features - - ~~A wireless version of the serial port features of TWANG. I think the easiest way is to make it a Wifi access point with a simple web page interface. This allows control by any smartphone or computer with no client side work required.~~ + +![](http://www.buildlog.net/blog/wp-content/uploads/2018/03/20180328_122254.jpg) + +Coming Soon:** + +- Wireless features~~ - 2 Player features by linking controllers. TBD - Digitized Audio - Currently the port uses the same square wave tones of the the Arduino version. diff --git a/TWANG32.ino b/TWANG32.ino index 5a26193..9ec721f 100644 --- a/TWANG32.ino +++ b/TWANG32.ino @@ -6,7 +6,7 @@ TWANG was originally created by Critters https://github.com/Critters/TWANG - It was inspired by Robin Baumgarten's Line Wobbler Game_Audio + It was inspired by Robin Baumgarten's Line Wobbler Game */ @@ -287,22 +287,21 @@ void loop() { // LEVEL COMPLETE tickWin(mm); }else if(stage == BOSS_KILLED){ - tickBossKilled(mm); - //tickComplete(mm); + tickBossKilled(mm); } else if (stage == GAMEOVER) { - if (stageStartTime+GAMEOVER_FADE_DURATION > mm) - { - tickGameover(mm); - } - else - { - FastLED.clear(); - save_game_stats(false); - //score = 0; // reset the score - levelNumber = 0; - lives = user_settings.lives_per_level; - loadLevel(); - } + if (stageStartTime+GAMEOVER_FADE_DURATION > mm) + { + tickGameover(mm); + } + else + { + FastLED.clear(); + save_game_stats(false); // boss not killed + //score = 0; // reset the score + levelNumber = 0; + lives = user_settings.lives_per_level; + loadLevel(); + } } FastLED.show(); @@ -318,8 +317,8 @@ void loop() { void loadLevel(){ // leave these alone updateLives(); - cleanupLevel(); - playerAlive = 1; + cleanupLevel(); + playerAlive = 1; lastLevel = false; // this gets changed on the boss level /// Defaults...OK to change the following items in the levels below @@ -874,6 +873,7 @@ void tickBossKilled(long mm) // boss funeral } SFXcomplete(); }else{ + save_game_stats(true); // true = boss was killed nextLevel(); } } @@ -1017,12 +1017,7 @@ bool inLava(int pos){ return false; } -void updateLives(){ - // Updates the life LEDs to show how many lives the player has left - //for(int i = 0; ii?HIGH:LOW); - //} - +void updateLives(){ drawLives(); } diff --git a/settings.h b/settings.h index e70e116..d4336da 100644 --- a/settings.h +++ b/settings.h @@ -10,20 +10,36 @@ #define EEPROM_SIZE 256 // LEDS -#define BRIGHTNESS 150 +#define DEFAULT_BRIGHTNESS 150 +#define MIN_BRIGHTNESS 10 +#define MAX_BRIGHTNESS 255 // PLAYER const uint8_t MAX_PLAYER_SPEED = 10; // Max move speed of the player const uint8_t LIVES_PER_LEVEL = 3; // default lives per level +#define MIN_LIVES_PER_LEVEL 3 +#define MAX_LIVES_PER_LEVEL 9 // JOYSTICK #define JOYSTICK_ORIENTATION 1 // 0, 1 or 2 to set the axis of the joystick #define JOYSTICK_DIRECTION 1 // 0/1 to flip joystick direction -#define ATTACK_THRESHOLD 30000 // The threshold that triggers an attack -#define JOYSTICK_DEADZONE 8 // Angle to ignore +#define DEFAULT_ATTACK_THRESHOLD 30000 // The threshold that triggers an attack +#define MIN_ATTACK_THRESHOLD 20000 +#define MAX_ATTACK_THRESHOLD 30000 + + +#define DEFAULT_JOYSTICK_DEADZONE 8 // Angle to ignore +#define MIN_JOYSTICK_DEADZONE 3 +#define MAX_JOYSTICK_DEADZONE 12 // AUDIO -#define MAX_VOLUME 180 // 0 to 255 +#define DEFAULT_VOLUME 180 // 0 to 255 +#define MIN_VOLUME 0 +#define MAX_VOLUME 255 + + + + #define DAC_AUDIO_PIN 25 // should be 25 or 26 only enum ErrorNums{ @@ -78,12 +94,7 @@ settings_t user_settings; char readBuffer[READ_BUFFER_LEN]; uint8_t readIndex = 0; -void settings_init() { - - //if (!EEPROM.begin(EEPROM_SIZE)) - //{ - // Serial.println("failed to initialize EEPROM"); - //} +void settings_init() { settings_eeprom_read(); show_settings_menu(); @@ -187,11 +198,12 @@ void change_setting(char *line) { switch (param) { case 'B': // brightness - if(newValue >=5 && newValue <=255) { + if(newValue >= MIN_BRIGHTNESS && newValue <= MAX_BRIGHTNESS) { user_settings.led_brightness = (uint8_t)newValue; settings_eeprom_write(); - delay(1000); - ESP.restart(); // this one requires a restart right now + FastLED.setBrightness(user_settings.led_brightness); + //delay(1000); + //ESP.restart(); // this one requires a restart right now } else { printError(ERR_SETTING_RANGE); @@ -200,7 +212,7 @@ void change_setting(char *line) { break; case 'S': // sound - if (newValue >=0 && newValue < 255) + if (newValue >=MIN_VOLUME && newValue <= MAX_VOLUME) user_settings.audio_volume = (uint8_t)newValue; else { printError(ERR_SETTING_RANGE); @@ -209,7 +221,7 @@ void change_setting(char *line) { break; case 'D': // deadzone, joystick - if(newValue >=3 && newValue <=12) + if(newValue >=MIN_JOYSTICK_DEADZONE && newValue <=MAX_JOYSTICK_DEADZONE) user_settings.joystick_deadzone = (uint8_t)newValue; else { printError(ERR_SETTING_RANGE); @@ -218,7 +230,7 @@ void change_setting(char *line) { break; case 'A': // attack threshold, joystick - if(newValue >=20000 && newValue <=35000) + if(newValue >=MIN_ATTACK_THRESHOLD && newValue <=MAX_ATTACK_THRESHOLD) user_settings.attack_threshold = (uint16_t)newValue; else { printError(ERR_SETTING_RANGE); @@ -249,12 +261,12 @@ void change_setting(char *line) { void reset_settings() { user_settings.settings_version = SETTINGS_VERSION; - user_settings.led_brightness = BRIGHTNESS; + user_settings.led_brightness = DEFAULT_BRIGHTNESS; - user_settings.joystick_deadzone = JOYSTICK_DEADZONE; - user_settings.attack_threshold = ATTACK_THRESHOLD; + user_settings.joystick_deadzone = DEFAULT_JOYSTICK_DEADZONE; + user_settings.attack_threshold = DEFAULT_ATTACK_THRESHOLD; - user_settings.audio_volume = MAX_VOLUME; + user_settings.audio_volume = DEFAULT_VOLUME; user_settings.lives_per_level = LIVES_PER_LEVEL; @@ -297,10 +309,6 @@ void show_settings_menu() { Serial.println(" ? to show current settings"); Serial.println(" R to reset everything to defaults)"); Serial.println(" P to reset play statistics)"); - //Serial.println(" E to write changes to eeprom)"); - //Serial.println(" ! to restart with current settings"); - - show_game_stats(); } void show_game_stats() @@ -314,10 +322,8 @@ void show_game_stats() Serial.print("Boss kills: ");Serial.println(user_settings.boss_kills); } -void settings_eeprom_read() -{ - Serial.println("Begin EEPROM Read"); - +void settings_eeprom_read() { + EEPROM.begin(EEPROM_SIZE); uint8_t ver = EEPROM.read(0); @@ -338,9 +344,11 @@ void settings_eeprom_read() temp[i] = EEPROM.read(i); } + EEPROM.end(); + memcpy((char*)&user_settings, temp, sizeof(user_settings)); - EEPROM.end(); + } @@ -351,10 +359,7 @@ void settings_eeprom_write() { EEPROM.begin(EEPROM_SIZE); uint8_t temp[sizeof(user_settings)]; - memcpy(temp, (uint8_t*)&user_settings, sizeof(user_settings)); - - Serial.println("Writing settings..."); - + memcpy(temp, (uint8_t*)&user_settings, sizeof(user_settings)); for (int i=0; i +#include "settings.h" const char* ssid = "TWANG_AP"; const char* passphrase = "esp32rocks"; WiFiServer server(80); +char linebuf[80]; +int charcount=0; + void ap_setup() { bool ret; @@ -19,14 +23,13 @@ void ap_setup() { */ ret = WiFi.softAP(ssid, passphrase, 2, 0); - Serial.println("\r\nWiFi AP online ..."); + //Serial.println("\r\nWiFi AP online ..."); server.begin(); } void sendStatsPage(WiFiClient client) { - Serial.println("printUploadForm"); // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); @@ -36,6 +39,7 @@ void sendStatsPage(WiFiClient client) { client.println(""); client.println("

TWANG32 Play Stats

"); client.println(""); + client.print("

Adjustable Settings

"); + + client.print(""); + + client.print(""); + + client.print(""); + + client.print(""); + + client.print(""); + + client.print(""); + + client.print("
Brightness
Sound Volume
Joystick Deadzone (3-12)
Attack Sensitivity (20000-35000)
Lives Per Level (3-9)
"); + client.println(""); client.println(""); client.println(); @@ -57,9 +86,73 @@ void ap_client_check(){ int stat; WiFiClient client = server.available(); // listen for incoming clients - if (client) { // if you get a client, - sendStatsPage(client); - Serial.println("printUploadForm"); - } + //if (client) { // if you get a client, + // sendStatsPage(client); + // Serial.println("printUploadForm"); + //} + bool currentLineIsBlank = true; + + while (client.connected()) { + if (client.available()) { + char c = client.read(); + //Serial.write(c); + linebuf[charcount]=c; + if (charcount 0) + { + String line = String(linebuf); + + int start = line.indexOf('=', 0) + 1; + int finish = line.indexOf('H', start)-1; + String val = line.substring(start, finish); + // if it is not numeric, it will convert to 0. + // The constrain functions will make it 0 or the min value + + if (strstr(linebuf,"B=") > 0){ // typically look like this "GET /?S=100 HTTP/1.1" + user_settings.led_brightness = constrain(val.toInt(), MIN_BRIGHTNESS, MAX_BRIGHTNESS); + FastLED.setBrightness(user_settings.led_brightness); + settings_eeprom_write(); + } + else if (strstr(linebuf,"S=") > 0){ + //String val = line.substring(start, finish); + user_settings.audio_volume = constrain(val.toInt(), MIN_VOLUME, MAX_VOLUME); + settings_eeprom_write(); + } + else if (strstr(linebuf,"D=") > 0){ + user_settings.joystick_deadzone = constrain(val.toInt(), MIN_JOYSTICK_DEADZONE, MAX_JOYSTICK_DEADZONE); + settings_eeprom_write(); + } + else if (strstr(linebuf,"A=") > 0){ + user_settings.attack_threshold = constrain(val.toInt(), MIN_ATTACK_THRESHOLD, MAX_ATTACK_THRESHOLD); + settings_eeprom_write(); + } + else if (strstr(linebuf,"L=") > 0){ + user_settings.lives_per_level = constrain(val.toInt(), MIN_LIVES_PER_LEVEL, MAX_LIVES_PER_LEVEL); + settings_eeprom_write(); + } + } + + // you're starting a new line + currentLineIsBlank = true; + memset(linebuf,0,sizeof(linebuf)); + charcount=0; + } else if (c != '\r') { + // you've gotten a character on the current line + currentLineIsBlank = false; + } + + } + } }