Name update

This commit is contained in:
Gus
2025-07-29 10:28:13 -03:00
committed by GitHub
parent df8e4eeecb
commit df79adba2e
2 changed files with 180 additions and 67 deletions

BIN
schematics.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@@ -11,6 +11,8 @@ HARDWARE:
- 1.3" OLED I2C Screen 128x64; - 1.3" OLED I2C Screen 128x64;
- 4 push buttons (with 1n4148 diode to prevent debounce); - 4 push buttons (with 1n4148 diode to prevent debounce);
NOTE: Disable the USB serial communication for more ROM space
by Gus Costa by Gus Costa
(GitHub: gusocosta) (GitHub: gusocosta)
(Reddit: gu-ocosta) (Reddit: gu-ocosta)
@@ -19,6 +21,8 @@ by Gus Costa
#include <GyverOLED.h> #include <GyverOLED.h>
#include "bitmaps.h" #include "bitmaps.h"
//Choose your screen protocol
//GyverOLED<SSD1306_128x64> oled;
GyverOLED<SSH1106_128x64> oled; GyverOLED<SSH1106_128x64> oled;
//Peripheral constants //Peripheral constants
@@ -28,6 +32,7 @@ const uint8_t bt_up = PA11;
const uint8_t bt_left = PA12; const uint8_t bt_left = PA12;
//Time vars and const //Time vars and const
bool timer_rolling = false;
const uint8_t check_pet_time = 5; //in sec const uint8_t check_pet_time = 5; //in sec
uint32_t draw_tick = 0; uint32_t draw_tick = 0;
uint8_t draw_tick_max = 100; uint8_t draw_tick_max = 100;
@@ -75,16 +80,23 @@ uint8_t pet_mood = 0; //0: normal, 1: happy, 2: sleep, 3:dead
uint8_t pet_doing = 0; //0: nothing, 1: eating tomato, 2: eating carrot, 3: eating mushroom, 4: eating chicken, 5: eating candy, 6: cleaning, 7: petting, 8: sleeping, 9: dead uint8_t pet_doing = 0; //0: nothing, 1: eating tomato, 2: eating carrot, 3: eating mushroom, 4: eating chicken, 5: eating candy, 6: cleaning, 7: petting, 8: sleeping, 9: dead
bool pet_alive = true; bool pet_alive = true;
bool pet_sleeping = false; bool pet_sleeping = false;
bool pet_poop = false; bool pet_poop = true;
uint8_t pet_ani = 0; uint8_t pet_ani = 0;
uint8_t food_check[5] = {0,0,0,0,0}; uint8_t food_check[5] = {0,0,0,0,0}; //0: tomato, 1: carrot, 2: mushroom, 3: chicken, 4: candy
bool happy_fail = false; //vars to check for evolution bool happy_fail = false; //vars to check for evolution
bool health_fail = false; //vars to check for evolution bool health_fail = false; //vars to check for evolution
//Name vars and consts
char ascii_alphabet[63] = {}; //all the alphabet. 26 Uppercases, 26 lowercases, 10 numbers and underscore
char name_letters_array[8] = {95,95,95,95,95,95,95,95}; //the characters that compose the pet's name
String pet_name = "";
uint8_t ascii_letter_count[8] = {62,62,62,62,62,62,62,62};
uint8_t name_letters_indicator = 0; //0 to 7 for the letters, 8 for the "Next" button
//UI vars and consts //UI vars and consts
uint32_t rng_comp = 0; uint32_t rng_comp = 0;
int rng_dir = 1; int rng_dir = 1;
uint8_t screen = 1; //0: name, 1: main, 2: status uint8_t screen = 0; //0: name, 1: main, 2: status
uint8_t sel = 0; uint8_t sel = 0;
uint8_t food_sel = 0; //0: tomato, 1: carrot, 2: mushroom, 3: chicken, 4: candy uint8_t food_sel = 0; //0: tomato, 1: carrot, 2: mushroom, 3: chicken, 4: candy
const uint8_t bottom_bar_size = 5; const uint8_t bottom_bar_size = 5;
@@ -118,47 +130,43 @@ const unsigned char* trex_up[1][2] = {{trex_up1, trex_up2}};
const unsigned char* trex_eyes[3][2] = {{trex_eye_n1, trex_eye_n2},{trex_eye_h1, trex_eye_h2},{trex_eye_s1, trex_eye_s2}}; const unsigned char* trex_eyes[3][2] = {{trex_eye_n1, trex_eye_n2},{trex_eye_h1, trex_eye_h2},{trex_eye_s1, trex_eye_s2}};
void setup() { void setup() {
Serial.begin(9600); delay(10);
pinMode(bt_left, INPUT_PULLUP); pinMode(bt_left, INPUT_PULLUP);
pinMode(bt_right, INPUT_PULLUP); pinMode(bt_right, INPUT_PULLUP);
pinMode(bt_up, INPUT_PULLUP); pinMode(bt_up, INPUT_PULLUP);
pinMode(bt_down, INPUT_PULLUP); pinMode(bt_down, INPUT_PULLUP);
//pinMode(buzz, OUTPUT);
oled.init(); oled.init();
oled.clear(); oled.clear();
bottom_bar_gen(); bottom_bar_gen();
age_gen(); age_gen();
alphabet_gen();
rng_comp = int(millis()+analogRead(PA0)); rng_comp = int(millis()+analogRead(PA0));
if (rng_comp % 2 == 0){pet_sex = 1;} if (rng_comp % 2 == 0){pet_sex = 1;}
} }
// Generates the bottom bar //========================================================================
void bottom_bar_gen(){ //============================ Name Functions ============================
bottom_bar_sel_size = 127 / bottom_bar_size; //========================================================================
for(uint8_t i = 0; i < bottom_bar_size; i++){
bottom_bar_pos[i] = (i* bottom_bar_sel_size) + ((bottom_bar_sel_size - 8)/2); void alphabet_gen(){
uint8_t char_count = 65;
for (uint8_t i=0; i<26; i++){ //Uppercase
ascii_alphabet[i] = char_count + i;
} }
char_count = 97;
for (uint8_t i=0; i<26; i++){ //Lowercase
ascii_alphabet[26 + i] = char_count + i;
}
char_count = 48;
for (uint8_t i=0; i<10; i++){ //numbers
ascii_alphabet[52 + i] = char_count + i;
}
ascii_alphabet[62] = 95; //add space
} }
// Make the age string on the status screen
void age_gen(){
if (pet_alive == true){
if (act_time[3]!=0){
pet_age = String(act_time[3]) + "D";
}
else if (act_time[2]!=0){
pet_age = String(act_time[2]) + "H";
}
else if (act_time[1]!=0){
pet_age = String(act_time[1]) + "m";
}
else{
pet_age = "0m";
}
}
}
//======================================================================== //========================================================================
//============================= Time Function ============================ //============================= Time Function ============================
//======================================================================== //========================================================================
@@ -215,10 +223,11 @@ void time_check(){
} }
} }
//========================================================================
//================================ Buttons ===============================
//========================================================================
void check_bt(){ void check_bt(){
//========================================================================
//=============================== Button Up ============================== //=============================== Button Up ==============================
//========================================================================
if (digitalRead(bt_up) == LOW){ if (digitalRead(bt_up) == LOW){
rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir; rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir;
rng_dir *= -1; rng_dir *= -1;
@@ -226,8 +235,30 @@ void check_bt(){
if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce
buttom_cooldown_millis = millis(); buttom_cooldown_millis = millis();
//Name Screen
if (screen == 0){
if(name_letters_indicator !=8){
ascii_letter_count[name_letters_indicator] = func_select(ascii_letter_count[name_letters_indicator], 62, 1);
name_letters_array[name_letters_indicator] = ascii_alphabet[ascii_letter_count[name_letters_indicator]];
}
else{
uint8_t letter_count = 0;
for(uint8_t i =0; i < 8; i++){ //Counting the written letters
if(name_letters_array[7-i] != 95){
letter_count = 7-i;
break;
}
}
for(uint8_t i =0; i <= letter_count; i++){ //Saving the name
pet_name += name_letters_array[i];
}
timer_rolling = true;
screen = 1;
}
}
//Main Screen //Main Screen
if (screen == 1){ else if (screen == 1){
if (pet_alive == true && doing_tick < millis()){ if (pet_alive == true && doing_tick < millis()){
if (sel == 0){ //Eating if (sel == 0){ //Eating
if (pet.hungry < 100){ if (pet.hungry < 100){
@@ -240,7 +271,7 @@ void check_bt(){
pet.happy += pet_eating_vars[pet_species][food_sel][3]; pet.happy += pet_eating_vars[pet_species][food_sel][3];
pet.sleep += pet_eating_vars[pet_species][food_sel][4]; pet.sleep += pet_eating_vars[pet_species][food_sel][4];
food_check[food_sel] += 1; food_check[food_sel] += 1; //0: tomato, 1: carrot, 2: mushroom, 3: chicken, 4: candy
pet_mood = 1; pet_mood = 1;
pet_sleeping = false; pet_sleeping = false;
} }
@@ -294,9 +325,7 @@ void check_bt(){
} }
} }
//========================================================================
//============================== Button Down ============================= //============================== Button Down =============================
//========================================================================
if (digitalRead(bt_down) == LOW){ if (digitalRead(bt_down) == LOW){
rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir; rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir;
rng_dir *= -1; rng_dir *= -1;
@@ -304,7 +333,16 @@ void check_bt(){
if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce
buttom_cooldown_millis = millis(); buttom_cooldown_millis = millis();
if (screen == 1){ //Name Screen
if (screen == 0){
if(name_letters_indicator !=8){
ascii_letter_count[name_letters_indicator] = func_select(ascii_letter_count[name_letters_indicator], 62, 0);
name_letters_array[name_letters_indicator] = ascii_alphabet[ascii_letter_count[name_letters_indicator]];
}
}
//Main Screen
else if (screen == 1){
if (pet_alive == true && doing_tick < millis()){ if (pet_alive == true && doing_tick < millis()){
if (sel == 0){ //Eating if (sel == 0){ //Eating
food_sel = func_select(food_sel, 4, 1); food_sel = func_select(food_sel, 4, 1);
@@ -313,20 +351,27 @@ void check_bt(){
} }
} }
//Status Screen
else if (screen == 2){
screen = 1;
}
} }
} }
//========================================================================
//============================== Button Left ============================= //============================== Button Left =============================
//========================================================================
if (digitalRead(bt_left) == LOW){ if (digitalRead(bt_left) == LOW){
rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir; rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir;
rng_dir *= -1; rng_dir *= -1;
if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce
buttom_cooldown_millis = millis(); buttom_cooldown_millis = millis();
//Name Screen
if (screen == 0){
name_letters_indicator = func_select(name_letters_indicator, 8, 0);
}
//Main Screen //Main Screen
if (screen == 1){ else if (screen == 1){
sel = func_select(sel, bottom_bar_size-1, 0); sel = func_select(sel, bottom_bar_size-1, 0);
} }
@@ -337,29 +382,32 @@ void check_bt(){
} }
} }
//========================================================================
//============================= Button Right ============================= //============================= Button Right =============================
//========================================================================
if (digitalRead(bt_right) == LOW){ if (digitalRead(bt_right) == LOW){
rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir; rng_comp += int(buttom_cooldown_millis - millis()) * rng_dir;
rng_dir *= -1; rng_dir *= -1;
if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce if(millis() > buttom_cooldown_millis + buttom_cooldown){ //debounce
buttom_cooldown_millis = millis(); buttom_cooldown_millis = millis();
//Name Screen
if (screen == 0){
name_letters_indicator = func_select(name_letters_indicator, 8, 1);
}
//Main Screen //Main Screen
if (screen == 1){ else if (screen == 1){
sel = func_select(sel, bottom_bar_size - 1, 1); sel = func_select(sel, bottom_bar_size - 1, 1);
} }
//Status Screen //Status Screen
else if (screen == 2){ else if (screen == 2){
screen = 1;
} }
} }
} }
} }
uint8_t func_select(uint8_t var, uint8_t max, uint8_t dir){ uint8_t func_select(uint8_t var, uint8_t max, uint8_t dir){ //dir 0: negative, 1:positive
if(dir > 0){ if(dir > 0){
if(var < max){var += 1;} if(var < max){var += 1;}
else{var = 0;} else{var = 0;}
@@ -439,7 +487,7 @@ void check_pet(){
if (pet.health <= 50){ if (pet.health <= 50){
health_fail = true; health_fail = true;
} }
if (pet.happy <= 70){ if (pet.happy <= 50){
happy_fail = true; happy_fail = true;
} }
@@ -453,11 +501,11 @@ void evolve(){
break; break;
case 1: case 1:
pet_species = 2; //evolve to Bunny pet_species = 2; //evolve to Bunny
if (happy_fail == false && food_check[0] == 0 && food_check[1] == 0 && food_check[2] == 0){ //evolve to T-Rex if (happy_fail == false && health_fail == false && food_check[0] == 0 && food_check[1] == 0 && food_check[2] == 0){ //(only eats chicken or candy) - food_check: 0: tomato, 1: carrot, 2: mushroom, 3: chicken, 4: candy
pet_species = 4; pet_species = 4; //evolve to T-Rex
} }
else if (health_fail == false && food_check[0] > 0 && food_check[1] > 0 && food_check[2] > 0 && food_check[3] == 0){ //evolve to Dino else if (health_fail == false && food_check[0] > 0 && food_check[1] > 0 && food_check[2] > 0 && food_check[3] == 0){ //(eats every vegetable. can eat candy too) - food_check: 0: tomato, 1: carrot, 2: mushroom, 3: chicken, 4: candy
pet_species = 3; pet_species = 3; //evolve to Dino
} }
break; break;
} }
@@ -472,6 +520,10 @@ void clamp_pet(){
if(pet.sleep > 200){pet.sleep = 200;} if(pet.sleep > 200){pet.sleep = 200;}
} }
//========================================================================
//================================ Misc ==================================
//========================================================================
void ani_check(){ void ani_check(){
if (pet_mood == 0) { if (pet_mood == 0) {
pet_ani = ani_tick % 2; pet_ani = ani_tick % 2;
@@ -487,6 +539,32 @@ void ani_check(){
} }
} }
// Generates the bottom bar
void bottom_bar_gen(){
bottom_bar_sel_size = 127 / bottom_bar_size;
for(uint8_t i = 0; i < bottom_bar_size; i++){
bottom_bar_pos[i] = (i* bottom_bar_sel_size) + ((bottom_bar_sel_size - 8)/2);
}
}
// Make the age string on the status screen
void age_gen(){
if (pet_alive == true){
if (act_time[3]!=0){
pet_age = String(act_time[3]) + "D";
}
else if (act_time[2]!=0){
pet_age = String(act_time[2]) + "H";
}
else if (act_time[1]!=0){
pet_age = String(act_time[1]) + "m";
}
else{
pet_age = "0m";
}
}
}
void resize(const uint8_t* bmp, uint16_t w, uint16_t h, int16_t x0, int16_t y0, uint8_t scale) { void resize(const uint8_t* bmp, uint16_t w, uint16_t h, int16_t x0, int16_t y0, uint8_t scale) {
if (!scale) return; // avoid divide-by-zero if (!scale) return; // avoid divide-by-zero
@@ -543,6 +621,30 @@ void draw(){
oled.setCursorXY(0, 0); oled.setCursorXY(0, 0);
oled.line(0, 10, 127, 10); oled.line(0, 10, 127, 10);
//========================================================================
//===============================Name Screen==============================
//========================================================================
if (screen == 0){
draw_sex(1, 16);
oled.setCursor(16,3);
oled.setScale(2);
draw_letter_scroll();
oled.setScale(1);
if (name_letters_indicator == 8){
oled.invertText(true);
}
oled.setCursorXY(91,55);
oled.print("Start!");
oled.invertText(false);
oled.rect(89,53,127,63,2);
if (name_letters_indicator == 8){
oled.line(90,54,90,63);
oled.line(90,54,127,54);
}
}
//======================================================================== //========================================================================
//===============================Main Screen============================== //===============================Main Screen==============================
//======================================================================== //========================================================================
@@ -564,7 +666,7 @@ void draw(){
} }
if (pet_poop == true){ if (pet_poop == true){
resize(icon_poop, 8, 8, 112, 32, 2); //bmp, w, h, x0, y0, scale resize(icon_poop, 8, 8, 104, 32, 2); //bmp, w, h, x0, y0, scale
} }
//draw bottom bar //draw bottom bar
@@ -582,6 +684,10 @@ void draw(){
oled.drawBitmap(bottom_bar_pos[i], 55, bottom_bar_icons[i-1], 8, 8, 0, invert_sprite); oled.drawBitmap(bottom_bar_pos[i], 55, bottom_bar_icons[i-1], 8, 8, 0, invert_sprite);
} }
} }
if (evolve_ani == true){
draw_explosion();
}
} }
//======================================================================== //========================================================================
@@ -589,14 +695,15 @@ void draw(){
//======================================================================== //========================================================================
else if(screen == 2){ else if(screen == 2){
//Draw Infos //Draw Infos
if (pet_sex == 0) {oled.drawBitmap(1, 16, icon_fem, 8, 8);} draw_sex(1, 16);
else {oled.drawBitmap(1, 16, icon_male, 8, 8);}
oled.setCursorXY(12, 16); oled.setCursorXY(12, 16);
oled.print(pet_all_species[pet_species]); oled.print(pet_name);
oled.setCursorXY(1, 28); oled.setCursorXY(1, 28);
oled.print(pet_all_species[pet_species]);
oled.setCursorXY(1, 40);
oled.print("Age: "); oled.print("Age: ");
oled.print(pet_age); oled.print(pet_age);
oled.setCursorXY(1, 40); oled.setCursorXY(1, 52);
oled.print("Lvl: "); oled.print("Lvl: ");
if(pet_lvl < 2){oled.print(pet_lvl);} if(pet_lvl < 2){oled.print(pet_lvl);}
else{oled.print("MAX");} else{oled.print("MAX");}
@@ -625,21 +732,14 @@ void draw(){
oled.rect(66 + (i*13), 18 + (34 - (34 * pet.happy)/100), 70 + (i*13), 52); oled.rect(66 + (i*13), 18 + (34 - (34 * pet.happy)/100), 70 + (i*13), 52);
} }
} }
//Draw Back Button
oled.rect(0, 55, 6, 63);
oled.setCursor(1, 7);
oled.invertText(true);
oled.print("<");
oled.invertText(false);
}
if (evolve_ani == true){
draw_explosion();
} }
oled.update(); oled.update();
} }
void draw_sex(uint8_t x, uint8_t y){
if (pet_sex == 0) {oled.drawBitmap(x, y, icon_fem, 8, 8);}
else {oled.drawBitmap(x, y, icon_male, 8, 8);}
}
//Solving the sprite puzzle //Solving the sprite puzzle
void draw_pet(){ void draw_pet(){
uint8_t animation_eyes; uint8_t animation_eyes;
@@ -715,9 +815,22 @@ void draw_explosion(){
} }
} }
void draw_letter_scroll(){
for(uint8_t i=0; i<8; i++){
if (i == name_letters_indicator){
oled.invertText(true);
}
oled.print(name_letters_array[i]);
oled.invertText(false);
}
}
void loop() { void loop() {
check_bt(); check_bt();
if (timer_rolling == true){
time_check(); time_check();
}
if(millis() > draw_tick + draw_tick_max){ //controls the screens refresh to save some battery if(millis() > draw_tick + draw_tick_max){ //controls the screens refresh to save some battery
draw_tick = millis(); draw_tick = millis();