Pokitto turn based strategy game.

Dependencies:   PokittoLib

Revision:
2:af768faf5329
Parent:
1:189e78ff65b1
--- a/wars.cpp	Tue Dec 05 03:24:36 2017 +0000
+++ b/wars.cpp	Sat Dec 09 20:49:10 2017 +0000
@@ -1,9 +1,21 @@
 #include "Pokitto.h"
 #include "warsprites.h"
+uint16_t dark_pal[16];
 #include "warfont.cpp"
 #include <vector>
 #include <stdint.h>
 
+Pokitto::Core game;
+Pokitto::Display disp;
+Pokitto::Buttons btn;
+
+void init_dark_palette() {
+    for (uint8_t c=1;c<15;c++) {
+        dark_pal[c] = disp.interpolateColor(sprite_pal[c], sprite_pal[0], 100);
+    }
+}
+
+bool loading;
 float solids[64] {
     0,1,1,1,1,0,0,0,
     0,0,1,0,1,0,0,0,
@@ -87,13 +99,17 @@
     return (1-t)*a + t*b;
 }
 
+float lerp(float a, float b, float t) {
+    return (1-t)*a + t*b;
+}
+
 enum GameState {MAIN, PAUSE, MENU} State = MENU;
 
 #define KEY_REPEAT 5
 
 #define TASK_MOVE 0
-#define TASK_ITEM 1
-#define TASK_ATTACK 2
+#define TASK_ITEM 2
+#define TASK_ATTACK 1
 #define TASK_WAIT 3
 #define TASK_NONE 4
 #define TEAM_USER 0
@@ -104,18 +120,14 @@
 uint8_t current_task = TASK_NONE;
 static char task_names[4][7] {
     {"MOVE"},
+    {"ATTACK"},
     {"ITEM"},
-    {"ATTACK"},
     {"WAIT"},
 };
 int task_colors[4] {
     11,9,6,8
 };
 
-Pokitto::Core game;
-Pokitto::Display disp;
-Pokitto::Buttons btn;
-
 #define SW disp.width
 #define SH disp.height
 
@@ -264,6 +276,9 @@
         return (dist(x, y, dx, dy)<=range);
     }
 };
+Hero * cursor_hero = NULL;
+Hero * current_hero = NULL;
+vector<Hero> * hptr;
 
 void DrawCursorHeroUI (Hero * h, int x, int y) {
     int bw = 24;
@@ -352,16 +367,41 @@
 
 #define MAP_WIDTH 12
 #define MAP_HEIGHT 12
-int Map[MAP_HEIGHT][MAP_WIDTH];
-void loadTileMap() {
-    fileOpen("file_out.war",FILE_MODE_BINARY);
+int Map[MAP_HEIGHT][MAP_WIDTH] {
+{0,8,0,5,10,8,8,1,8,8,0,8},
+{1,0,0,21,15,14,8,0,8,0,1,0},
+{0,8,0,8,10,5,8,8,0,9,8,8},
+{0,1,8,0,10,5,1,8,8,8,0,8},
+{8,0,9,0,18,7,3,3,3,4,8,1},
+{0,8,8,0,0,5,0,0,0,12,8,13},
+{0,0,1,8,8,5,8,1,8,11,0,5},
+{8,0,8,0,8,5,8,0,0,10,0,5},
+{8,8,0,8,1,21,6,30,6,15,6,22},
+{8,0,0,8,8,0,0,5,8,12,0,0},
+{0,1,8,9,0,8,1,5,8,18,3,3},
+{0,0,8,8,8,8,0,5,8,0,8,0},
+};
+
+void loadTileMap(char * filename) {
+    disp.fillLCD(disp.palette[0]);
+    disp.directBitmap(110-16,176/2-16,sprites[72],4,2);
+    int inc = 220/144;
+    #ifdef POK_SIM
+        game.wait(20);
+    #endif
+    pokInitSD();
+    fileOpen(filename,FILE_MODE_BINARY);
     for (int i = 0; i<144; i++) {
         int x = i%MAP_WIDTH;
         int y = (i-x)/MAP_WIDTH;
         //fileSetPosition(i);
         Map[y][x] = (int)filePeek(i);
+        #ifdef POK_SIM
+            game.wait(10);
+        #endif // POK_SIM
+        disp.directRectangle(inc*(i*2),0,inc,8,disp.palette[15]);
     }
-    //fileClose();
+    fileClose();
 }
 
 void saveTileMap() {
@@ -451,13 +491,139 @@
     }
 }
 
+struct PauseMenu {
+    char items[3][12];
+    unsigned int selected_item;
+    Transition lb; //letterbox
+    PauseMenu() {
+        lb.off_val=0;
+        lb.on_val=16;
+        lb.enabled=true;
+        lb.val = lb.off_val;
+        selected_item = 0;
+        strcpy(items[0], "RESUME");
+        strcpy(items[1], "END TURN");
+        strcpy(items[2], "QUIT GAME");
+    };
+    void endTurn(vector<Hero> * _heros) {
+        for (int i=0; i<0+_heros->size(); i++) {
+            _heros->at(i).NewTurn();
+        }
+    };
+    void update() {
+        lb.update();
+        for (int i = 1; i<15; i++) {
+            disp.palette[i] = disp.interpolateColor(disp.palette[i],dark_pal[i], 80);
+        }
+        if (btn.pressed(BTN_DOWN)) {
+            selected_item++;
+            selected_item%=3;
+        }
+        else if (btn.pressed(BTN_UP)) {
+            selected_item--;
+            selected_item%=3;
+        }
+
+        if (btn.pressed(BTN_A)) {
+            lb.val = lb.off_val;
+            disp.load565Palette(sprite_pal);
+            switch (selected_item) {
+            case 0:
+                State = MAIN;
+            break;
+            case 1:
+                current_team=(current_team+1) % 2;
+                endTurn(hptr);
+                State = MAIN;
+            break;
+            case 2:
+                State = MENU;
+                game.filemenu();
+            break;
+            }
+        }
+    };
+    void draw() {
+        //disp.fillRoundRect()
+        DrawTileMap(map_x, map_y, current_hero);
+        disp.setColor(0);
+        disp.fillRect(0,0,SW,lb.val);
+        disp.fillRect(0,SH-lb.val,SW,lb.on_val);
+        disp.setColor(15);
+        disp.setCursor(0,lb.val+2);
+        disp.println("PAUSED");
+        disp.print("CURRENT TEAM ");
+        disp.println(current_team);
+        disp.println(selected_item);
+        for (int i=0;i<3; i++) {
+            int color = 0;
+            if (selected_item==i) {
+                color = 15;
+            }
+            disp.setColor(color);
+            disp.print(32, 32+ (i*6), items[i]);
+        }
+    };
+};
+
+struct LevelList {
+    int pos;
+    int files;
+    char * fname;
+    LevelList() {
+        pokInitSD();
+        pos = 0;
+        files = 0;
+        fname = getFirstFile("war");
+        files++;
+        while(fname!=NULL) {
+            fname = getNextFile("war");
+            files++;
+        }
+        fname = getFirstFile("war");
+    };
+
+    void update() {
+        if (btn.pressed(BTN_DOWN)) {
+            fname = getNextFile("war");
+            if (fname==NULL) {
+                fname = getFirstFile("war");
+            }
+        }
+        if (btn.pressed(BTN_A)&&fname!=NULL) {
+            loadTileMap(fname);
+        }
+    };
+    void draw() {
+        disp.setFont(font5x7);
+        disp.bgcolor=0;
+        disp.clear();
+        disp.setColor(15);
+        disp.setCursor(2,2);
+        disp.print((int)files);
+        disp.print(" MAPS FOUND");
+        disp.print(2,SH/2-3, fname);
+        disp.setFont(fontWAR);
+
+        disp.bgcolor = 12;
+    };
+
+};
+#define MENU_STATE_MAIN 0
+#define MENU_STATE_LEVEL 1
 struct MainMenu {
+    int state;
     struct Transition trans;
     char items[3][10];
     int selected_item;
+    int box_x;
+    int box_target;
     MainMenu() {
-        trans.off_val=-16;
-        trans.on_val = 24;
+        state = MENU_STATE_MAIN;
+        box_x = 0;
+        box_target = 0;
+        trans.off_val=SH+16;
+        trans.on_val = SH-12;
         trans.val=trans.off_val;
         trans.enabled=true;
         strcpy(items[0], "CAMPAIGN");
@@ -465,12 +631,18 @@
         strcpy(items[2], "OPTIONS");
         selected_item = 0;
     };
-    void update() {
+    void update(LevelList *l) {
+        switch (state) {
+        case MENU_STATE_MAIN:
+        box_x = lerp(box_x, box_target, 0.50);
+        trans.update();
         if (btn.pressed(BTN_RIGHT)) {
             selected_item = min(selected_item + 1, 2);
+            trans.val=trans.off_val;
         }
         if (btn.pressed(BTN_LEFT)) {
             selected_item = max(selected_item - 1, 0);
+            trans.val=trans.off_val;
         }
 
         if (btn.pressed(BTN_A)) {
@@ -480,42 +652,83 @@
             case (1):   //SKIRMISH
                 disp.clear();
                 disp.print("LOADING");
-                pokInitSD();
-                loadTileMap();
+                //pokInitSD();
+                //loadTileMap("file_out.war");
                 State = MAIN;
                 break;
             case (2):   //OPTIONS
+                state = MENU_STATE_LEVEL;
                 break;
             }
         }
+        break;
+        case (MENU_STATE_LEVEL):
+            if (btn.pressed(BTN_B)) {
+                state = MENU_STATE_MAIN;
+            }
+            l->update();
+        break;
+        }//SWITCH
     };
-    void draw() {
+    void draw(LevelList *l) {
+        switch (state) {
+        case (MENU_STATE_MAIN):
+        disp.bgcolor=0;
         disp.clear();
-        trans.update();
         disp.setColor(15);
-        disp.print(2,trans.val,"POKIT WARS");
-        disp.print(2,SH/2, items[selected_item]);
+        disp.print(2,2,"POKIT WARS");
+        disp.print(SW/2-(strlen(items[selected_item])*6/2),trans.val, items[selected_item]);
+        disp.fillRoundRect(box_x, SH/2, 16, 16,2);
+        for (int i=0; i<3; i++) {
+            int x = (SW/4)*(i+1)-8;
+            int spr = 64+i;
+            if (i==selected_item) {
+                box_target = x;
+                if (box_x-2<x&&box_x+2>x) {
+                    box_x = x;
+                }
+            }
+            disp.drawBitmap(x, SH/2, sprites[spr]);
+        }
+        disp.bgcolor=12;
+        break;
+        case (MENU_STATE_LEVEL):
+            l->draw();
+        break;
+        }//SWITCH
     };
 };
 
 int main() {
     MainMenu main_menu;
+    PauseMenu pause_menu;
     Transition tTrans(66,96,false);
     Transition itemlist(40,72,false);
     game.begin();
+    game.initClock();
+    game.initRandom();
     game.setFrameRate(30);
     disp.invisiblecolor = 12;
     disp.bgcolor=12;
     disp.persistence = 1;
+    disp.directbgcolor = disp.palette[0];
+    disp.directcolor = disp.palette[15];
     disp.load565Palette(sprite_pal);
+    init_dark_palette();
     disp.setFont(fontWAR);
     map_x=0;
     map_y=0;
     cursor_x=4;
     cursor_y=6;
     vector<Hero> heros;
+    hptr = &heros;
     pokInitSD();
-    loadTileMap();
+
+    char dir[3];
+    strcpy(dir, "War");
+
+    LevelList level_menu;
+
     /*
     heros.push_back(Hero(4,5,ID_SOLDIER, TEAM_USER));
     heros.push_back(Hero(5,6,ID_SOLDIER, TEAM_USER));
@@ -531,16 +744,16 @@
         heros.push_back(Hero(random(0,MAP_WIDTH-1),random(0,MAP_HEIGHT-1),ID_SOLDIER, team));
     }
 
-    Hero * cursor_hero = NULL;
-    Hero * current_hero = NULL;
+    //Hero * cursor_hero = NULL;
+    //Hero * current_hero = NULL;
     Item itest(52, 3, 3);
 
     while (game.isRunning()) {
         if (game.update()) {
             switch (State) {
             case MENU:
-                main_menu.update();
-                main_menu.draw();
+                main_menu.update(&level_menu);
+                main_menu.draw(&level_menu);
             break;
             case MAIN:
             tTrans.update();
@@ -663,10 +876,9 @@
             }
             if (btn.pressed(BTN_C)&& !current_hero) {
                 //heros.push_back(Hero(cursor_x,cursor_y,0,0));
-                current_team=(current_team+1) % 2;
-                for (int i=0;i<heros.size();i++) heros[i].NewTurn();
+                //for (int i=0;i<heros.size();i++) heros[i].NewTurn();
                 State = PAUSE;
-                disp.print("PAUSED");
+                //disp.print("PAUSED");
                 //tTrans.toggle();
             }
             if (cursor_hero&&cursor_hero!=current_hero&&current_task) {
@@ -684,10 +896,8 @@
             //disp.print(" ");
             break;
             case PAUSE:
-                if (btn.pressed(BTN_C)) {
-                    State = MAIN;
-                }
-                disp.print(isThisFileOpen("file_out.war"));
+                pause_menu.update();
+                pause_menu.draw();
             break;
         }//GAME STATE SWITCH