//-----------------------------LICENSE NOTICE------------------------------------
//  This file is part of CPCtelera: An Amstrad CPC Game Engine
//  Copyright (C) 2018 ronaldo / Fremos / Cheesetea / ByteRealms (@FranGallegoBR)
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#include <cpctelera.h>
#include "main.h"
#include "menu.h"
#include "functions.h"
#include "game.h"
#include "absolutas.h"

const u8 paletteM0[16] = { HW_BLACK, HW_BRIGHT_WHITE , HW_BRIGHT_YELLOW, HW_PASTEL_CYAN, HW_BRIGHT_RED, HW_PURPLE, HW_BRIGHT_BLUE, HW_GREEN,
 HW_PINK, HW_CYAN, HW_ORANGE, HW_PASTEL_BLUE, HW_RED, HW_BRIGHT_GREEN, HW_WHITE, HW_PASTEL_MAGENTA    };
const u8 symphony[5] = {33,34,32,25,29};
u8 current_palette[16];
TEntity entities[MAX_ENTITIES]; 
u8 music_counter;
u8 music_playing;
i8 last_mov;
u8 day;
u8 screen;
u16 clock;
u8 frame;
u8 eod;
u8 energy;
u8 hiscore;
u8 reset_face;
u8 hour;
u8 possibleActivity;
u8 object;
u8 textPrinted;
u8 using2ndbtn;
u8 firstTime;
u16 telephone;
u8 vehicles;
u8 hintText; 
u8 hintTextTime; 
u8 carScreen;
u8 dropsCollected;
u8 baskets; 
u8 spiders; 
u8 hose;
u8 idle;
u8 note;
u8 symphony_idx;
u8 activities[ID_SPECIAL_MSG];
u8 bufferFrame1[96]; 
u8 bufferFrame2[96];
u8 current_map[MAP_WIDTH * MAP_HEIGHT];
u8* spriteset;
u8* faces;
u8 extra_char; 
u8 swiping; 
u8 pressed;


void waitBorder() {
   //Esperar a que el raster haya llegado al borde o al marco del área de juego
   for (;;) {
      if (music_counter == INT_OFFSCREEN) {
         break;
      }
   } 
   //cpct_waitVSYNC(); 
}

void playFX (u8 instrument, u8 note) {
// SFXPlay admite notas de 0 a 143, es decir 144 notas. Siendo 12 notas por octava, daría para 12 octavas
// Sin embargo, Arkos sólo muestra octavas de 0 a A
// Para obtener una nota hay que calcular
// ((octava * 12) + nota (teniendo en cuenta semitonos)) - 1. Por ejemplo E2 => (2 * 12) + 5 - 1

   cpct_akp_SFXInit (m_sfx);
   cpct_akp_SFXPlay (instrument, 15, note, 0, 0, AY_CHANNEL_C);
}

void playMusic(){
   //El reproductor Arkos hace uso de los registros auxiliares (AF',BC',...) por lo que si luego se hace uso
   //de funciones que hagan uso de ellos (como easytiles) puede corromperse el programa si llega la interrupción a medio proceso.
   //Por eso, es mejor curarse en salud y guardarlos siempre de manera manual antes de llamar a la reproducción de la música
   __asm
      PUSH AF
      PUSH BC
      PUSH DE
      PUSH HL
      PUSH IX
      PUSH IY
      EXX
      .db 0x08 ;; //EX AF,AF' para que no salte warning al compilar por creerse que es una cadena de carácter sin cerrar
      PUSH AF
      PUSH BC
      PUSH DE
      PUSH HL
   __endasm;
   cpct_akp_musicPlay();
   __asm
      POP HL
      POP DE
      POP BC
      POP AF
      .db 0x08 ;; //EX AF,AF'
      EXX
      POP IY
      POP IX
      POP HL
      POP DE
      POP BC
      POP AF
   __endasm;
}

void intHandler(){
   if ((music_counter == INT_OFFSCREEN || music_counter == INT_OFFSCREEN + 6) && !swiping) {
      //cpct_setBorder(HW_PINK);
      cpct_setVideoMode(1);
   }
   else {
      //cpct_setBorder(HW_BLACK);
      cpct_setVideoMode(0);
   }

   cpct_scanKeyboard_if();  //Para capturar teclado para quitar música o salir durante el juego

   //Las interrupciones se llaman 300 veces por segundo, la música debe sonar 50 veces por segundo (50hz)
   //por lo que sólo hay que llamar al siguiente bloque de música cada 6 veces
   if (music_counter == 0 || music_counter == 6) {   
      if (music_playing)
         playMusic();

      if (music_counter == 0)
         music_counter = 12;
   }

   music_counter--;
}

void setInterruptAtVSYNCStart(void *intHdl){
   //Asegurarnos que cambiamos la gestión de interrupciones al terminar VSync
   //pues el primero puede saltar si estamos a mitad de VSync. Por eso se pasan 2 interrupciones más y entra en espera.
   //(halt paraliza la ejecución hasta que se produzca una nueva interrupción)
   //Ahora es seguro que saltará de la espera al llegar el CRTC al VSync
   cpct_waitVSYNC();
   __asm
      halt 
      halt
   __endasm;
   //Nos aseguramos que CRTC estaba a mitad de pantalla
   cpct_waitVSYNC(); //Me aseguro que se espera al final del pintado de la pantalla para cambiar el código de la interrupción
   music_counter = 12;
   cpct_setInterruptHandler(intHdl);
}

void introText() {
   u8 i;

   for (i=0; i<8; i++) {
      //clearScreens();
      mydrawStringM1(&txt_intro1[0] + (39*i), cpctm_screenPtr(CPCT_VMEM_START, 0, 192));
      pausa(65535);
      fade();
   }

}

void main(void) {
   
   // Disable firmware, clear and colour screen (black)
   cpct_disableFirmware();
   music_playing = 0;
   music_counter = 12;
   setInterruptAtVSYNCStart(intHandler);
   
   updatePalette();
   cpct_setBorder(HW_BLACK);

   cpct_setDrawCharM1(2, 0);
   hiscore = 127;
   using2ndbtn = 0;
   firstTime = 0;  
   vehicles = 0;
   swiping = 0;

   introText();

   while (1) {
      resetValues();
      //Menu
      menu();
      //Juego
      game();
   }
   
}
