//fire with 8 custom chars on 2x16 lcd demo 
//Yaroslaw Turbin 26-10-2024
//https://vk.com/ldirko
//https://www.reddit.com/user/ldirko/
//https://twitter.com/ldir_ko
//https://www.youtube.com/c/ldirldir

#include <Wire.h>
#include <hd44780.h>                       
#include <hd44780ioClass/hd44780_I2Cexp.h> 

hd44780_I2Cexp lcd; 

const int LCD_COLS = 16;
const int LCD_ROWS = 2;


#include <FastLED.h> 

byte symb[8] ={};

#define NUM_ROWS  8
#define NUM_COLS  40


byte firebuff[320];

void fire2021 (){
  int  a = millis();
  int  a1 = a/3;
  int index = 0;
  
  for (byte j = 0; j < NUM_ROWS; j++) { 
    for (byte i = 0; i < NUM_COLS; i++) {
      byte color = qsub8 (inoise8 (i * 50, j * 50+a, a1), abs8(j - (NUM_ROWS-1)) * 255 / (NUM_ROWS+10));
      // color = i*16+j*16+a1/2;  //for tests 
      if (color>96) firebuff[index]=255; 
               else firebuff[index]=0;
      index++;
    }
  }
}


void convertbuff (int offset, byte *symbol){
  byte bits = 0;
  for (byte j = 0; j < 8; j++){

    bits = 0;
    for (byte i = 0; i < 5; i++){
      byte color = firebuff[offset+j*NUM_COLS+i];
      bits<<=1;
      if (color) {bits |= 0b00000001;}
    }
    
    symbol[j]=bits;  
  }
}


void FPS(){
  static int frame = 0;
  static double currenttime = millis();
  frame++;

  if ((millis()-currenttime)>8000) {
    Serial.print(F("FPS: "));
    Serial.println(frame/8);
    frame = 0;
    currenttime = millis();
  }
}

 
int main(){
  init();
  Serial.begin(115200);
  lcd.init();                  
  lcd.backlight();
  lcd.noCursor();
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("WORLD IN FIRE");
  lcd.setCursor(0, 1);
  lcd.print(" \1\2\3\4\5\6\7 \1\2\3\4\5\6\7");
  lcd.setCursor(0, 1);
  lcd.write(byte(0));
  lcd.setCursor(8, 1);
  lcd.write(byte(0)); 

  for(;;){  
    fire2021();
    for (byte i = 0; i < 8; i++){
      convertbuff(i*5, symb);
      lcd.createChar(i, symb);
    }
    // FPS();
  }
}