/* FINAL DRAGON 4/25/05
BY JESSE HARRIS
THIS IS THE CONTROL MODULE FOR FINAL DRAGON
IT CALLS SUBBMODULES EVERY SCREEN REFRESH BASED ON GAME STATE
ALSO INTIALIZES MOST ARRAYS AND DATA STRUCTURES
CONTROLS BACKGROUND MUSIC BASED ON STATE
*/
//include modules here
#include <mygba.h>
#include <hel.h>
#include "modules.h"
#include "samples.h"
#include "myinit.h"
#include "mymenuinit.h"
#include "mymenu.h"
#include "mymenuexit.h"
#include "mymapinit.h"
#include "mymap.h"
#include "mystatus.h"
#include "mystatusinit.h"
#include "stuff.hpp"
#include "mytext.h"
#include "mytextinit.h"
#include "mybattle.h"
#include "mybattleinit.h"
#include "mtwister.h"
#include "myloadgame.h"
#include "mydeath.h"
#include "mywin.h"

//include gfx here

#include "gfx/test/ts1.cpp"
#include "gfx/test/ts1map1.cpp"
#include "gfx/test/ts1map2.cpp"
#include "gfx/test/ts1map3.cpp"
#include "gfx/test/ts2.cpp"
#include "gfx/test/ts2map1.cpp"
#include "gfx/test/ts3.cpp"
#include "gfx/test/ts3map1.cpp"
#include "gfx/test/ts3map2.cpp"
#include "gfx/test/ts3map3.cpp"
#include "gfx/test/ts3map4.cpp"
#include "gfx/test/ts4.cpp"
#include "gfx/test/ts4map1.cpp"
#include "gfx/test/ts5.cpp"
#include "gfx/test/ts5map1.cpp"
#include "gfx/test/ts5map2.cpp"
#include "gfx/test/ts5map3.cpp"
#include "gfx/test/ts5map4.cpp"
#include "gfx/test/ts5map5.cpp"
#include "gfx/test/ts5map6.cpp"
#include "gfx/test/ts5map7.cpp"
#include "gfx/test/ts6.cpp"
#include "gfx/test/ts6map1.cpp"

#include "gfx/monster/slimer.raw.c"
#include "gfx/monster/slimer.pal.c"
#include "gfx/monster/redslimer.raw.c"
#include "gfx/monster/redslimer.pal.c"
#include "gfx/monster/metalslimer.raw.c"
#include "gfx/monster/metalslimer.pal.c"

#include "gfx/monster/drakeer.raw.c"
#include "gfx/monster/drakeer.pal.c"
#include "gfx/monster/drakeemar.raw.c"
#include "gfx/monster/drakeemar.pal.c"
#include "gfx/monster/magidrakeer.raw.c"
#include "gfx/monster/magidrakeer.pal.c"

#include "gfx/monster/knightr.raw.c"
#include "gfx/monster/knightr.pal.c"
#include "gfx/monster/armoredknightr.raw.c"
#include "gfx/monster/armoredknightr.pal.c"
#include "gfx/monster/axeknightr.raw.c"
#include "gfx/monster/axeknightr.pal.c"

#include "gfx/monster/scorpionr.raw.c"
#include "gfx/monster/scorpionr.pal.c"

#include "gfx/monster/bluedragonr.raw.c"
#include "gfx/monster/bluedragonr.pal.c"

//end include gfx here

// these define are for quick reference to game state
//defines go here
#define GS_NEWGAME  0
#define GS_MENU     1
#define GS_MAP      2
#define GS_MENUEXIT 3
#define GS_MAPINIT  4
#define GS_STATUS   5
#define GS_TEXT     6
#define GS_BATTLE   7
#define GS_LOADGAME 8
#define GS_DEATH    9
#define GS_WIN     10
//end defines go here


//initialize varibles here

u8 g_NewFrame = 0;  //needed to keep track of if it is a new franme I.E. vblank interrupt just called
chandle g_hChannel; //for sounds effects
short g_State = 0;  //keeps track of gamestate for main loop
u8 sprites[127];      //global variable used to keep track of sprites
TMapScrollInfo MapInfo[0];  //global variable to be used by modules to track background info
int tempmain = 0;               //used in game state main look and temp vaiable
u16 delay = 0;  //used extensively to track keystroke reading delay between modules
short tempspritex[127];     //for sprite tracking
short tempspritey[127];     //"                 "
int seed = 0;  // for random number generator
const char * gsaveType = "SRAM_V113"; //for ensuring game is saved the proper type of ROM

//the array of map structs for use through the program
map maplist[18] =
{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{40, 40, (void*)ts1_cmap, (void*)&ts1_blockgfx, (u16 *)ts1_lookuptable, (short *)ts1_map2, (u16*)ts1_collisiontable, SIZEOF_16BIT(ts1_blockgfx), (short *)ts1_map2_sprite , SIZEOF_16BIT(ts1_map2_sprite) /4,1,0,      2, 19, 18,   3, 36, 25,    3, 36, 25,   3, 36, 25},
{40, 20, (void*)ts1_cmap, (void*)&ts1_blockgfx, (u16 *)ts1_lookuptable, (short *)ts1_map3, (u16*)ts1_collisiontable, SIZEOF_16BIT(ts1_blockgfx), (short *)ts1_map3_sprite , SIZEOF_16BIT(ts1_map3_sprite) /4,1,0,      0, 0, 0,   1, 19, 1,    0, 0, 0,   0, 0, 0},
{100, 100, (void*)ts2_cmap, (void*)&ts2_blockgfx, (u16 *)ts2_lookuptable, (short *)ts2_map1, (u16*)ts2_collisiontable, SIZEOF_16BIT(ts2_blockgfx), (short *)ts2_map1_sprite  , SIZEOF_16BIT(ts2_map1_sprite) /4,5,11,   0, 0, 0,   0, 0, 0,    0, 0, 0,   0, 0, 0},
{16, 16, (void*)ts1_cmap, (void*)&ts1_blockgfx, (u16 *)ts1_lookuptable, (short *)ts1_map1, (u16*)ts1_collisiontable, SIZEOF_16BIT(ts1_blockgfx), (short *)ts1_map1_sprite , SIZEOF_16BIT(ts1_map1_sprite) /4,1,0,      3, 44, 43,   3, 44, 43,    3, 44, 43,   3, 44, 43},
//5
{5, 40, (void*)ts3_cmap, (void*)&ts3_blockgfx, (u16 *)ts3_lookuptable, (short *)ts3_map1, (u16*)ts3_collisiontable, SIZEOF_16BIT(ts3_blockgfx), (short *)ts3_map1_sprite , SIZEOF_16BIT(ts3_map1_sprite) /4,3,4,       6, 12, 24,   3, 93, 5,    0, 0, 0,   0, 0, 0},
{25, 25, (void*)ts3_cmap, (void*)&ts3_blockgfx, (u16 *)ts3_lookuptable, (short *)ts3_map2, (u16*)ts3_collisiontable, SIZEOF_16BIT(ts3_blockgfx), (short *)ts3_map2_sprite , SIZEOF_16BIT(ts3_map2_sprite) /4,3,5,       10, 9, 19,   5, 2, 0,    11, 0, 17,   0, 0, 0},
{20, 20, (void*)ts4_cmap, (void*)&ts4_blockgfx, (u16 *)ts4_lookuptable, (short *)ts4_map1, (u16*)ts4_collisiontable, SIZEOF_16BIT(ts4_blockgfx), (short *)ts4_map1_sprite , SIZEOF_16BIT(ts4_map1_sprite) /4,2,8,       0, 0, 0,   9, 10, 0,    0, 0, 0,   0, 0, 0},
{20, 20, (void*)ts5_cmap, (void*)&ts5_blockgfx, (u16 *)ts5_lookuptable, (short *)ts5_map1, (u16*)ts5_collisiontable, SIZEOF_16BIT(ts5_blockgfx), (short *)ts5_map1_sprite , SIZEOF_16BIT(ts5_map1_sprite) /4,2,1,       14, 10, 19,   3, 20, 32,    13, 0, 17,   12, 19, 4},
{20, 20, (void*)ts6_cmap, (void*)&ts6_blockgfx, (u16 *)ts6_lookuptable, (short *)ts6_map1, (u16*)ts6_collisiontable, SIZEOF_16BIT(ts6_blockgfx), (short *)ts6_map1_sprite , SIZEOF_16BIT(ts6_map1_sprite) /4,2,7,       7, 9, 19,   3, 88, 82,    0, 0, 0,   0, 0, 0},
//10
{20, 20, (void*)ts3_cmap, (void*)&ts3_blockgfx, (u16 *)ts3_lookuptable, (short *)ts3_map3, (u16*)ts3_collisiontable, SIZEOF_16BIT(ts3_blockgfx), (short *)ts3_map3_sprite , SIZEOF_16BIT(ts3_map3_sprite) /4,3,6,       0, 0, 0,   6, 3, 0,    0, 0, 0,   0, 0, 0},
{20, 20, (void*)ts3_cmap, (void*)&ts3_blockgfx, (u16 *)ts3_lookuptable, (short *)ts3_map4, (u16*)ts3_collisiontable, SIZEOF_16BIT(ts3_blockgfx), (short *)ts3_map4_sprite , SIZEOF_16BIT(ts3_map4_sprite) /4,3,6,       0, 0, 0,   0, 0, 0,    0, 0, 0,   6, 24, 3},
{20, 20, (void*)ts5_cmap, (void*)&ts5_blockgfx, (u16 *)ts5_lookuptable, (short *)ts5_map2, (u16*)ts5_collisiontable, SIZEOF_16BIT(ts5_blockgfx), (short *)ts5_map2_sprite , SIZEOF_16BIT(ts5_map2_sprite) /4,2,2,       0, 0, 0,   0, 0, 0,    8, 0, 7,   15, 9, 5},
{20, 20, (void*)ts5_cmap, (void*)&ts5_blockgfx, (u16 *)ts5_lookuptable, (short *)ts5_map3, (u16*)ts5_collisiontable, SIZEOF_16BIT(ts5_blockgfx), (short *)ts5_map3_sprite , SIZEOF_16BIT(ts5_map3_sprite) /4,2,2,       0, 0, 0,   0, 0, 0,    16, 0, 7,   8, 19, 7},
{20, 20, (void*)ts5_cmap, (void*)&ts5_blockgfx, (u16 *)ts5_lookuptable, (short *)ts5_map4, (u16*)ts5_collisiontable, SIZEOF_16BIT(ts5_blockgfx), (short *)ts5_map4_sprite , SIZEOF_16BIT(ts5_map4_sprite) /4,2,2,       17, 4, 9,   8, 12, 0,    0, 0, 0,   0, 0, 0},
//15
{10, 10, (void*)ts5_cmap, (void*)&ts5_blockgfx, (u16 *)ts5_lookuptable, (short *)ts5_map5, (u16*)ts5_collisiontable, SIZEOF_16BIT(ts5_blockgfx), (short *)ts5_map5_sprite , SIZEOF_16BIT(ts5_map5_sprite) /4,2,3,       0, 0, 0,   0, 0, 0,    12, 0, 17,   0, 0, 0},
{10, 10, (void*)ts5_cmap, (void*)&ts5_blockgfx, (u16 *)ts5_lookuptable, (short *)ts5_map6, (u16*)ts5_collisiontable, SIZEOF_16BIT(ts5_blockgfx), (short *)ts5_map6_sprite , SIZEOF_16BIT(ts5_map6_sprite) /4,2,3,       0, 0, 0,   0, 0, 0,    0, 0, 0,   13, 19, 4},
{10, 10, (void*)ts5_cmap, (void*)&ts5_blockgfx, (u16 *)ts5_lookuptable, (short *)ts5_map7, (u16*)ts5_collisiontable, SIZEOF_16BIT(ts5_blockgfx), (short *)ts5_map7_sprite , SIZEOF_16BIT(ts5_map7_sprite) /4,2,3,       0, 0, 0,   14, 4, 0,    0, 0, 0,   0, 0, 0}

};
//array of text strings for use by NPCs
char * text[] =
{
//                          ><                          ><
"Welcome famed warrior.  Thisis the gnome town of Provencia.",//0
"You will find what you seek   in the ice cave.", //1
"I'm a gnome.",//2
"                                                                     Battle",  //3
"Nothing.",//4
"Welcome to the Ice Cave",//5
"Bring more crystals.  As yougain crystals, see me for   new items.",
"Please save us.",
"Please save my kingdom.",//8
"Here are swamp boots to aid your journey.",
//                          ><                          ><
"Welcome to Gnovia.",//10
"You adventures have been    saved for the future.",//11
"Welcome to the Inn.         Your health and magic have  now been recharged.",
"This city is over 1000 yearsold.",
"Gnomes love the earth.",//14
"We guard Gnovia castle.",//15
"We guard the Gnome king.",
//                          ><                          ><                          ><                          ><                          ><                          ><                          ><                          ><                          ><                          >
"I am Daidleus, the Gnome    King.  Please help us save  our kingdom from evil.      The great blue dragon, he   has killed many of our kind.He is found in the Castle ofDoom.  No one who has been  to the castle has lived to  tell about it.              Go and save us from evil.",
"I am Nortius, the Kings     offical scribe.  Your valor will be written in our      histoy books and be legend  for many future generations.",
"I am Damuz, the Kings seer. Our kingdoms future is      unclear, but it does not    take a seer to know you are our last hope.              Please see my brother in thesouth for he has the things you need to be successful inyour quest.",
"I am the Princess Lystell.  Please save our kingdom.",//20
"Here is the crystal you seek",//21
"Here are hiking boots to aidyour journey.",//22
"Here are desert shoes to aidyour journey.",
"Kill the blue dragon and    save Gnovia.",//24
//                          ><                          ><                          ><                          ><                          ><                          ><                          ><                          ><                          ><                          >
"The ice dungeon contains twocrystals and the fire       dungeon contains three      crystals.  Bring crystals tothe old man of the south forrewards that will help you  in your quest."
};

//array of textlengths for each entry, this may be able to be calculated on the fly but my search for an implementation turned up nothing
u16 textlength[] =
{
59,
44,
12,
76,
8,
23,//5
66,
15,
23,
41,
18,//10
49,
75,
33,
22,
23,//15
24,
277,
140,
235,
52,//20
28,
41,
41,
40,
182//25
};

//array for tracking monster datatypes globally
monster monsterlist[] =
{
{0,0,0,0,0,0,0,0,0},
{(void*)&drakeer_Bitmap[0],(void*)&drakeer_Bitmap[32 * 32 / 2],(void*)&drakeer_Bitmap[32 * 32 * 2 / 2],(void*)&drakeer_Bitmap[32 * 32 * 3 / 2],(void*)drakeer_Palette,0,25,120,"Drakee"}, //curhp, hp, exp
{(void*)&drakeemar_Bitmap[0],(void*)&drakeemar_Bitmap[32 * 32 / 2],(void*)&drakeemar_Bitmap[32 * 32 * 2 / 2],(void*)&drakeemar_Bitmap[32 * 32 * 3 / 2],(void*)drakeemar_Palette,0,35,200,"Red Drakee"},
{(void*)&magidrakeer_Bitmap[0],(void*)&magidrakeer_Bitmap[32 * 32 / 2],(void*)&magidrakeer_Bitmap[32 * 32 * 2 / 2],(void*)&magidrakeer_Bitmap[32 * 32 * 3 / 2],(void*)magidrakeer_Palette,0,45,360,"Dark Drakee"},
{(void*)&slimer_Bitmap[0],(void*)&slimer_Bitmap[32 * 32 / 2],(void*)&slimer_Bitmap[32 * 32 * 2 / 2],(void*)&slimer_Bitmap[32 * 32 * 3 / 2],(void*)slimer_Palette,0,7,16,"Slime"},
{(void*)&redslimer_Bitmap[0],(void*)&redslimer_Bitmap[32 * 32 / 2],(void*)&redslimer_Bitmap[32 * 32 * 2 / 2],(void*)&redslimer_Bitmap[32 * 32 * 3 / 2],(void*)redslimer_Palette,0,12,32,"Red Slime"},
//6   \/
{(void*)&metalslimer_Bitmap[0],(void*)&metalslimer_Bitmap[32 * 32 / 2],(void*)&metalslimer_Bitmap[32 * 32 * 2 / 2],(void*)&metalslimer_Bitmap[32 * 32 * 3 / 2],(void*)metalslimer_Palette,0,16,70,"Metal Slime"},
{(void*)&knightr_Bitmap[0],(void*)&knightr_Bitmap[32 * 32 / 2],(void*)&knightr_Bitmap[32 * 32 * 2 / 2],(void*)&knightr_Bitmap[32 * 32 * 3 / 2],(void*)knightr_Palette,0,55,500,"Knight"},
{(void*)&axeknightr_Bitmap[0],(void*)&axeknightr_Bitmap[32 * 32 / 2],(void*)&axeknightr_Bitmap[32 * 32 * 2 / 2],(void*)&axeknightr_Bitmap[32 * 32 * 3 / 2],(void*)axeknightr_Palette,0,65,900,"Axe Knight"},
{(void*)&armoredknightr_Bitmap[0],(void*)&armoredknightr_Bitmap[32 * 32 / 2],(void*)&armoredknightr_Bitmap[32 * 32 * 2 / 2],(void*)&armoredknightr_Bitmap[32 * 32 * 3 / 2],(void*)armoredknightr_Palette,0,90,1300,"Dark Knight"},
{(void*)&bluedragonr_Bitmap[0],(void*)&bluedragonr_Bitmap[32 * 32 / 2],(void*)&bluedragonr_Bitmap[32 * 32 * 2 / 2],(void*)&bluedragonr_Bitmap[32 * 32 * 3 / 2],(void*)bluedragonr_Palette,0,150,0,"Blue Dragon"},
//11  \/
{(void*)&scorpionr_Bitmap[0],(void*)&scorpionr_Bitmap[32 * 32 / 2],(void*)&scorpionr_Bitmap[32 * 32 * 2 / 2],(void*)&scorpionr_Bitmap[32 * 32 * 3 / 2],(void*)scorpionr_Palette,0,4,6,"Scorpion"}
};
//exp lookup table
u16 exptable[] =
{
0, 0, 30, 80, 160, 350, 600, 1000, 1800, 2500, 4500, 6500, 10000, 15000, 25000, 40000, 75000, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999, 999999
};
//the player struct, this is most important
player watashi=
{//19, 4, 2
    19,4,2   ,0,0,4, 12, 12, 4, 4, 0, 1, 0, 0
};
//array for easy music switching
Module * bgmusic[] =
{
(Module *)&mod_roni_orch,
(Module *)&mod_withoutw,
(Module *)&mod_ng,
(Module *)&mod_desolat,
(Module *)&mod_aqua, //4
(Module *)&mod_xmastoon,
(Module *)&mod_hear3
};

//text mode initialization stuff
TCustomTextInfo g_TextInfo= //for drawing letters 'n stuff
{
    // background to use
    2,
    // order of chars on bitmap.
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?ÖÄÜöäü,.-;: #^+*@!\"§%\%&/()=?|\\<>[]{}¹²³°"
};

//end intialize varibles here


MULTIBOOT

/*********************************************************************************
 * Prototypes
 ********************************************************************************/
void vblFunc(void);

/*********************************************************************************
 * main(void)
 *
 * This function is called when the program starts
 * Try to keep this as empty as possible
 ********************************************************************************/

int main(void)
{
    
    // Initialize HAMlib
    // Then we call the single most important function of ham, ham_Init .
    // This function must be called first thing when working with HAMlib,
    // because all ham_* functions will only work correctly after this has been called.
    // Behaviour of HAMlib is undefined if you comment this out.
    ham_Init();

    //for krawall init
    kragInit(KRAG_INIT_STEREO);
    ham_StartIntHandler(INT_TYPE_TIM1,(void *)&kradInterrupt);

    // Will, once activated, trigger the specified interrupt,
    // and then call the function specified
    ham_StartIntHandler(INT_TYPE_VBL, (void *)&vblFunc);

    while(true)
    {
        seed++;
        if(g_NewFrame)
        {
            //large SWITCH for calling proper submodule based on game state
            switch (g_State)
            {
                case GS_NEWGAME:      //display Splash screen
                myInit();
                g_State = GS_MENU;
                krapPlay(bgmusic[0],KRAP_MODE_LOOP,0);
                myMenuInit();
                break;
                
                case GS_MENU:      //display menu screen

                tempmain = myMenu();

                if(tempmain == 1)  //new game
                    {
                    g_State = GS_MENUEXIT;
                    krapSetMusicVol(0, 10);
                    sgenrand(seed);
                    }
                if(tempmain == 2)  //load game
                    {
                    if(myLoadGame())  //load successful
                        {
                        g_State = GS_MENUEXIT;
                        krapSetMusicVol(0, 10);
                        sgenrand(seed);
                        }
                    else  //load fail
                        {
                        delay = 0;
                        }
                    }
                break;

                case GS_MENUEXIT:      //display menu screen
                if(myMenuExit())
                    {
                    g_State = GS_MAPINIT;
                    }
                break;
                
                case GS_MAPINIT:      //initilize map screen
                if(myMapInit())
                    {
                    krapSetMusicVol(60, 0);
                    g_State = GS_MAP;
                    if(maplist[watashi.map].musicnum != watashi.musicnum)
                        {
                        watashi.musicnum = maplist[watashi.map].musicnum;
                        krapPlay(bgmusic[watashi.musicnum],KRAP_MODE_LOOP,0);
                        }
                    }
                break;

                case GS_MAP:      //display map screen
                tempmain = myMap();
                if(tempmain == 1) //pause
                    {
                    g_State = GS_STATUS;
                    krapPause(0);
                    myStatusInit();
                    }
                if(tempmain == 2) //map transition
                    {
                    g_State = GS_MAPINIT;
                    }
                if(tempmain == 3) //display text from NPC
                    {
                    g_State = GS_TEXT;
                    myTextInit();
                    }
                if(tempmain == 4) //battle
                    {
                    g_State = GS_BATTLE;
                    krapPlay(bgmusic[4],KRAP_MODE_LOOP,0);
                    myBattleInit();
                    }
                break;
                
                case GS_STATUS:      //display status screen
                if(myStatus())
                    {
                    g_State = GS_MAP; //exit to map
                    krapUnpause();
                    }
                break;
                
                case GS_TEXT:      //display status screen
                if(myText())
                    {
                    g_State = GS_MAP; //exit to map
                    }
                break;
                
                case GS_BATTLE:      //display status screen
                tempmain = myBattle();
                if(tempmain == 1)  //you leave battle
                {
                    krapPlay(bgmusic[watashi.musicnum],KRAP_MODE_LOOP,0);
                    g_State = GS_MAP;
                }
                if(tempmain == 2) //you win the battle
                {
                    krapPlay(bgmusic[6],KRAP_MODE_LOOP,0);
                }
                if(tempmain == 3)  //you die
                {
                    g_State = GS_DEATH;
                    krapPause(0);
                }
                if(tempmain == 4)  // you win the game
                {
                    g_State = GS_WIN;
                    krapPlay(bgmusic[0],KRAP_MODE_LOOP,0);
                }
                break;
                
                case GS_DEATH:      //display death screen
                if(myDeath())
                {
                   if(myLoadGame())  //try to restart at last save
                    {
                        g_State = GS_MAPINIT;
                    }
                    else  //fail to restart
                    {
                        delay = 0;
                    }
                }
                break;
                
                case GS_WIN:      //display win screen
                myWin();
                break;
            }
            //end SWITCH here
            g_NewFrame = 0; // changed to 0 after each verticle refresh
        }
    }

    return 0;
}

/*********************************************************************************
 * vblFunc(void)
 *
 * This function is called whenever the GBA is about
 * to draw a new picture onto the screen.
 ********************************************************************************/
void vblFunc(void)
{
    // Call this (preferably during a VBL interrupt) to commit your
    // ham_obj information to the hardware. Only after you did this your
    // sprite changes will appear on screen.
    ham_CopyObjToOAM();
    
    //for krawall(music)
    kramWorker();
    //set to truie for new frame
    g_NewFrame=1;
    
}


/* END OF FILE */
