#include <coleco.h>
#include <getput1.h>
#include <string.h>

#define chrgen  0x0000
#define coltab  0x2000
#define chrtab  0x1800
#define sprtab  0x3800
#define sprgen  0x1b00

/* EXTERN TABLES - TABLES.C */
extern const byte title[];

char ecran[256];

byte monstre[5];
byte choixperso;
byte personnage[5];

/* VIE, FORCE, FORCE BRUTE, DEFENSE, GAIN D'ENERGIE */

static const char* const humainsnoms[]={"GUERRIER","FORGERON","VOLEUR","PAYSANNE"};
static const char* const monstresnoms[]={
 "SQUELLETTE",
 "ZOMBIE",
 "GOULE",
 "FANTOME",
 "VAMPIRE",
 "TROLL",
 "DRAGON",
 "LOUP-GAROUP",
 "GOBELIN",
 "ORQUE",
 "MOMIE",
 "BALROG",
 "GEANT",
 "DEMON",
 "MINOTAURE",
 "CHIMERE", 
 "SPHYNX",
 "CENTAURE",
 "MEDUSE",
 "SORCIER"
};

static const byte humains[] = {
 36,7,0,6,0, /* GUERRIER */
 42,6,0,5,0, /* FORGERON */
 50,5,0,4,0, /* VOLEUR */
 99,4,0,3,0  /* PAYSANNE */
};

static const byte monstres[] = {
 4,3,0,4,0,   /* SQUELLETTE */
 5,3,0,5,0,   /* ZOMBIE */
 5,3,1,6,0,   /* GOULE */
 4,3,1,8,0,   /* FANTOME */
 5,6,0,8,2,   /* VAMPIRE */
 12,6,0,6,0,  /* TROLL */
 15,6,1,7,0,  /* DRAGON */
 5,3,0,5,0,   /* LOUP-GAROU */
 2,3,1,4,0,   /* GOBELIN */
 3,6,0,5,0,   /* ORQUE */
 6,3,0,8,0,   /* MOMIE */
 10,6,0,9,0,  /* BALROG */
 12,6,0,6,0,  /* GEANT */
 9,6,1,7,1,   /* DEMON */
 6,5,2,7,0,   /* MINOTAURE */
 6,3,0,4,0,   /* CHIMERE */
 6,6,0,4,0,   /* SPHYNX */
 6,9,0,4,0,   /* CENTAURE */
 6,3,0,6,0,   /* MEDUSE */
 4,3,0,5,0    /* SORCIER */
};

static const byte spr1[] = {
 0x0,0x0,0x0,0x1,0x2,0x2,0x2,0x2,0x4,0x4,0x4,0x5,0x5,0xA,0x3A,0x46,
 0x39,0x46,0xBA,0x41,0x40,0x80,0x80,0x87,0x88,0x96,0xAA,0x2D,0x22,0x4C,0x48,0x2E,
 0x80,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x83,0x84,0x8B,0xA,0xA,0x12,0x12,0x13,
 0x0,0x0,0x2,0x1D,0x21,0x19,0x9,0xE9,0x19,0xAA,0x49,0xA,0x12,0x12,0x93,0x55,
 0x0,0x0,0x0,0x0,0x0,0x1,0x2,0xE1,0x13,0x94,0x9B,0xAA,0xAA,0xB2,0x33,0x32,
 0x0,0x0,0x20,0x50,0x90,0x48,0xB0,0xE0,0x18,0x90,0x90,0x98,0xA8,0xA8,0x28,0xB8,
 0x81,0x7C,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
 0xE1,0x3E,0xC,0xC3,0x30,0xF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
 0x8,0x7,0x0,0xC0,0x20,0xC0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
 0xA5,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
 0x1,0xFE,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
 0x88,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};

/* Init Sprites Pattern */
static void init_contour(void)
{
 byte i,j,x;
 disable_nmi ();
 put_vram (sprtab,spr1,0xc0);
 j = 0; x=59;
 for (i=0;i<3;i++)
 {
  sprites[i].x = x;
  sprites[i].y = 25;
  sprites[i].pattern = j;
  sprites[i].colour = 1;
  sprites[i+3].x = x;
  sprites[i+3].y = 25 + 16;
  sprites[i+3].pattern = 12 + j;
  sprites[i+3].colour = 1;
  j += 4;
  x += 16;
 }
 enable_nmi ();
}

void nmi()
{
}

void scroll_up()
{
  delay(1);
  disable_nmi();
  get_vram(chrtab+32,ecran,256);
  put_vram(chrtab,ecran,256);
  get_vram(chrtab+288,ecran,256);
  put_vram(chrtab+256,ecran,256);
  get_vram(chrtab+544,ecran,224);
  put_vram(chrtab+512,ecran,224);
  fill_vram(chrtab+736,32,32);
  enable_nmi();
}

void print2(char *s1,char *s2)
{
 int i;
 i = strlen(s1);
 while (i>30)
 {
  scroll_up();
  disable_nmi();
  put_vram(chrtab+737,s1,30);
  enable_nmi();
  s1 += 30;
  i -= 30;
 }
  scroll_up(); 
  disable_nmi();
  print_at (1,23,s1);
  enable_nmi();
  print_at (i+1,23,s2);
}

void print(char *s)
{
 int i;
 i = strlen(s);
 while (i>30)
 {
  scroll_up();
  disable_nmi();
  put_vram(chrtab+737,s,30);
  enable_nmi();
  s += 30;
  i -= 30;
 }
  scroll_up(); 
  disable_nmi();
  print_at (1,23,s);
  enable_nmi();
}

/*****************************************/
/* Wave -> CV sounds  by Daniel Bienvenu */
/*****************************************/
static const byte snd_s[] = {
  0x41,0x0f,0x82,0x10,0x11,0x1f,
  0x50};

const sound_t snd_table[]= {
	{snd_s, SOUNDAREA1}
	};

void boing3 (void)
{
 play_sound(1);
}
/*  LENGTH  =  16 */

/* SHOW TITLE SCREEN AND WAIT FOR FIRE BUTTON */
void show_title (void)
{
	disable_nmi();
	screen_off();
	screen_mode_2_bitmap();
	show_picture (title);
	init_contour();
	update_sprites (6,sprgen);
	screen_on();
	enable_nmi();
}

/* joystick: */
/* Joypad : 0x80 = fire (right), 0x40 = fire (left), 0x8 = left, 0x4 = down, 0x2 = right, 0x1 = up */

static void init_vdp (void)
{
	disable_nmi();
	screen_mode_2_text();
    screen_off();
	fill_vram (0,0,0x4000);
	load_ascii();
    duplicate_pattern();
	fill_vram(coltab,0x91,6144);
	vdp_out (7,0xf1);
	screen_on ();
	enable_nmi ();
}

void scroll_up_screen(void)
{
 byte i;
 for (i=0;i<23;i++)
 {
  scroll_up();
 }
}

void histoire(void)
{

 init_vdp();

 print ("HISTOIRE");
 scroll_up();
 /*     0    5   10   15   20   25   30   35   40   45   50   55   60   65   70   75   80   85   90*/
 print (" Depuis des siecles, des gens  tentent en vain  de ravir le  tresor  du  chateau  pres de  votre village.");
 scroll_up();
 print (" Les plus vieux affirment que  les  restes   de  precedents  explorateurs  defendent  eux  memes le tresor qu'ils n'ont  pu s'emparer.");
 scroll_up();
 print (" La nuit, des cris  horribles  venant du chateau  empechent  les gens de dormir.");
 scroll_up();
 print (" Selon la  legende, les  cris  cesseront  quand il n'y aura  plus de tresor au chateau.");
 scroll_up();
 print (" C'est a vous  maintenant  de  tenter votre chance.");
 scroll_up();
 pause();

 scroll_up_screen();
 center_string (10,"BONNE CHANCE");
 delay(70);
 center_string (12,"VOUS EN AUREZ BESOIN");
 delay(70);

 scroll_up_screen();
}

byte decision(byte j)
{
 byte i = 0;

 while (i==0 || i>j)
 {
  i = keypad_1;
  delay(1);
 }

 while (i==keypad_1);

 return i;
}

void pointdevie(byte i)
{

 char s[3];
 s[0] = '0' + (i / 10);
 s[1] = '0' + (i % 10);
 s[2] = 0x0;

 print ("POINTS DE VIE");
 print (s);
 
}

void attaque(byte i)
{

 char s[3];
 s[0] = '0' + (i / 10);
 s[1] = '0' + (i % 10);
 s[2] = 0x0;

 print ("ATTAQUE");
 print (s);
 
}

void bataille(void)
{
 byte nomonstre;
 byte coup;
 byte j,k;

 nomonstre = rnd_byte(1,20);
 nomonstre--;

 for(j=0;j<5;j++)
 {
  k = nomonstre*5;
  k += j;
  monstre[j] = monstres[k];
 }

 print ("** Combat **");
 scroll_up();
 scroll_up();
 print ((void*)humainsnoms[choixperso]);
 pointdevie(personnage[0]);
 scroll_up();
 print (" - contre - ");
 scroll_up();
 print ((void*)monstresnoms[nomonstre]);
 pointdevie(monstre[0]);
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();

 pause();

 scroll_up_screen();

 if (rnd_byte(0,1)==1) goto tourhumain; else goto tourmonstre;

tourhumain:
 scroll_up();
 print("A vous :");

 delay(10);

 coup = rnd_byte(1,10);
 if (coup<monstre[3])
 {
  print("Manque!");
 }
 else
 {
  coup = rnd_byte(1,personnage[1])+personnage[2];
  attaque(coup);
  if (coup<3) print ("Coup faible"); else print ("Bon Coup!");
  if (monstre[0]>coup) monstre[0] -= coup; else monstre[0]=0;
  pointdevie(monstre[0]);
 }

 delay(50);

 if (monstre[0]==0) {print2("Vous avez tue le ",(void*)monstresnoms[nomonstre]); goto fin;} else goto tourmonstre;

tourmonstre:
 scroll_up();
 print("Au monstre :");

 delay(10);

 coup = rnd_byte(1,10);
 if (coup<personnage[3])
 {
  print("Manque!");
 }
 else
 {
  coup = rnd_byte(1,monstre[1])+monstre[2];
  attaque(coup);
  if (coup<3) print ("Coup faible!"); else print ("Bon Coup!");
  if (personnage[0]>coup){personnage[0] -= coup;} else personnage[0]=0;
  pointdevie(personnage[0]);
  if (monstre[4]!=0)
  {
   print("Le monstre augmente ses..");
   monstre[0] += monstre[4];
   pointdevie(monstre[0]);
  }
 }

 delay(50);

 if (personnage[0]==0) {print("Vous etes mort!"); goto fin;} else goto tourhumain;

fin:

 scroll_up();

 pause();

}

void choix(void)
{
 byte i;
 byte j,k;
 print ("Choix de personnage");
 scroll_up();
 print (" 1 - GUERRIER");
 print (" 2 - FORGERON");
 print (" 3 - VOLEUR");
 print (" 4 - PAYSANNE");
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 i = decision(4);
 i--;
 choixperso = i;
 for(j=0;j<5;j++)
 {
  k = choixperso*5;
  k += j;
  personnage[j] = humains[k];
 }
 print ((void*)humainsnoms[i]);
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 scroll_up();
 pause();
 
}

void main(void)
{

 byte i;
    
    set_snd_table(snd_table);

restart:

 show_title();

 delay(15);
 boing3();
 pause();

 /* initialise name table */
/*
 set_default_name_table (chrtab);
 vdp_out (3,0xff);
 vdp_out (4,0x03);
*/
 histoire();

 choix();

 i = (personnage[1] >> 1) + 3;
 while(i!=0 && personnage[0]!=0)
 {
  i--;
  bataille();
  if (personnage[0]!=0)
  {
   scroll_up_screen();
   if (rnd_byte(0,3)==3)
   {
    print("POTION MAGIQUE DE VITALITE");
    scroll_up();
    personnage[0] += rnd_byte(1,4) + 3;
    pointdevie(personnage[0]);
   }
   else
   {
    if (rnd_byte(0,3)==3)
    {
     if (personnage[2] < 3)
     {
      print("AMULETTE MAGIQUE DE FORCE");
      scroll_up();
      personnage[2] += 2;
      scroll_up();
      scroll_up();
     }
    }
    else
    {
     print("VOUS N'AVEZ RIEN TROUVE!");
     scroll_up();
     scroll_up();
     scroll_up();
    }
   }
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    pause();
    scroll_up_screen();
  }
 }

 if (personnage[0]!=0)
 {
   scroll_up_screen();
   print("VOUS ETES RENDU AU CHATEAU!");
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   print("TIEN! UNE FONTAINE?!");
   print("VOUS BUVEZ UN PEU D'EAU?");
   print("1 - OUI / 2 - NON");
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   i = decision(2);
   if (i==1)
   {
    if (rnd_byte(0,3)>0)
    {
     print("L'EAU VOUS FAIT DU BIEN!");
     scroll_up();
     personnage[0] += rnd_byte(0,7)+10;
     pointdevie(personnage[0]);
    }
    else
    {
     print("L'EAU ETAIT MAUVAISE!");
     scroll_up();
     i = rnd_byte(1,3);
     if (personnage[0]>i) personnage[0] -= i; else personnage[0] = 1;
     pointdevie(personnage[0]);
    }
   }
   scroll_up();
   scroll_up();
   print("VOUS ENTREZ DANS LE CHATEAU!");
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   pause();


 i = personnage[1] >> 1;
 while(i!=0 && personnage[0]!=0)
 {
  i--;
  bataille();
  if (personnage[0]!=0)
  {
   scroll_up_screen();
   if (rnd_byte(0,3)==3)
   {
    print("POTION MAGIQUE DE VITALITE");
    scroll_up();
    personnage[0] += rnd_byte(1,4) + 4;
    pointdevie(personnage[0]);
   }
   else
   {
    if (rnd_byte(0,3)==3)
    {
     if (personnage[3] < 6)
     {
      print("AMULETTE MAGIQUE DE DEFENCE");
      scroll_up();
      personnage[3] += 2;
      scroll_up();
      scroll_up();
     }
    }
    else
    {
     print("VOUS N'AVEZ RIEN TROUVE!");
     scroll_up();
     scroll_up();
     scroll_up();
    }
   }
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    scroll_up();
    pause();
    scroll_up_screen();
  }
 }

  if (personnage[0]!=0)
  {
   print (" ** VOUS AVEZ TROUVE LE **");
   print ("       ** TRESOR! **");
   scroll_up();
   print (" FUYEZ AVANT LE RETOUR DU ");
   print ("            DRAGON ");
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   scroll_up();
   pause();
   scroll_up_screen();
  }
   
 }

 goto restart;

}

/* Keypad : 0,1,2,3...9  10=* et 11=#  */
/* Joypad : 0x80 = fire (right), 0x40 = fire (left), 0x8 = left, 0x4 = down, 0x2 = right, 0x1 = up */
/* SPRITES COOR XY SCREEN */
/* 0 ................. 255
 -1
  .
  .
  .   Sprites - CoorXY
  .
  .
 174 */
/* GRAFX SCREEN COOR XY */
/* 0 ................. 255
  0
  .
  .
  .
  .
  .
 191 */
/* TEXT SCREEN COOR XY */
/* 0 ................. 31
  0
  .
  .
  .
  .
  .
  23 */