Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "game.h"
  2. #include "hero.h"
  3. #include "PHL.h"
  4. #include "qda.h"
  5. #include "ini.h"
  6. #include "titlescreen.h"
  7. #include "options.h"
  8. #include "inventory.h"
  9. #include "object.h"
  10. #include "effect.h"
  11. #include "text.h"
  12. #include "stagedata.h"
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #ifdef EMSCRIPTEN
  17. #include <emscripten.h>
  18. #endif
  19.  
  20. int gameStep();
  21. void gameDraw(char doDrawHud);
  22.  
  23. void freeArrays();
  24. void drawHud();
  25. int getTileType(int valx, int valy);
  26.  
  27. void loadUncommonImages();
  28.  
  29. char forceGameExit = 0;
  30.  
  31. int drawhp;
  32. int NumOfSounds = 43;
  33. int NumOfImages = 14;
  34.  
  35. char autoSave = 1;
  36. int levelStartFlag = 0;
  37.  
  38. char tilesetStrings[9][12] = {"stage01.bmp",
  39.                                                           "stage02.bmp",
  40.                                                           "stage02.bmp",
  41.                                                           "stage03.bmp",
  42.                                                           "stage04.bmp",                                                       
  43.                                                           "stage03.bmp",
  44.                                                           "stage02.bmp",                                                         
  45.                                                           "stage05.bmp",                                                         
  46.                                                           "stage08.bmp" };
  47.                                                        
  48. char musicStrings[9][14] = { "midi/main01",
  49.                                                          "midi/main02",
  50.                                                          "midi/main02",
  51.                                                          "midi/main05",
  52.                                                          "midi/main03",                                                  
  53.                                                          "midi/main05",                                                  
  54.                                                          "midi/main02",                                                  
  55.                                                          "midi/main04",                                                  
  56.                                                          "midi/main06" };
  57.                                                        
  58. int collisionTiles[16][12];
  59. PHL_Surface images[15];
  60. PHL_Sound       sounds[43];
  61. PHL_Music       bgmMusic;
  62. PHL_Music       bgmSecret;
  63. PHL_Music       bgmGameover;
  64. Object* objects[MAX_OBJECTS];
  65. Effect* effects[MAX_EFFECTS];
  66. Weapon* weapons[MAX_WEAPONS];
  67. Enemy* enemies[MAX_ENEMIES];
  68. Platform* platforms[MAX_PLATFORMS];
  69.  
  70. int secretTimer;
  71. unsigned long playTime;
  72.  
  73. Door* lastDoor;
  74. int quakeTimer;
  75. int bellFlag;
  76. int bossFlag;
  77. int bossDefeatedFlag;
  78. int roomSecret;
  79. char roomDarkness;
  80.  
  81. int itemGotX;
  82. int itemGotY;
  83.  
  84. PHL_Background background, foreground;
  85.  
  86. unsigned char hasWeapon[5];
  87. unsigned char hasItem[28];
  88. unsigned char hasKey[8];
  89.  
  90. unsigned char flags[60];
  91.  
  92. double cutInTimer = 240;
  93. int transitionTimer = 0;
  94. int level = 0;
  95. int screenX = 5,
  96.         screenY = 2;
  97.  
  98. #ifdef _SDL
  99. char savename[4096];
  100. char savemap[4096];
  101. #endif
  102.  
  103. #ifdef EMSCRIPTEN
  104. extern int fileSynched;
  105. int em_state = -2;
  106. void em_loop_fn(void* arg)
  107. {
  108.         if(!PHL_MainLoop()) {
  109.         emscripten_cancel_main_loop();
  110.         }
  111.  
  112.         int result;
  113.         switch (em_state) {
  114.                 case -2: if(fileSynched) em_state++;
  115.                                  break;
  116.                 case -1: em_state++;
  117.                                 // need to delay loading of init to let synchof files happens
  118.                                 iniInit();
  119.                                 //Load Resources
  120.                                 loadText();    
  121.                                 loadResources();
  122.                                  break;
  123.                 case 0:
  124.                                 PHL_StopMusic();
  125.                                 titleScreenSetup();
  126.                                 ++em_state;
  127.                                 break;
  128.                 case 1: result = titleEMStep();
  129.                                 if (result == 3) {
  130.                                         em_state = 100;
  131.                                 } else if(result!=-1) {
  132.                                         if(result==2)
  133.                                                 em_state = 60;
  134.                                         else {
  135.                                                 //Reset game state
  136.                                                 gameSetup();
  137.                                                
  138.                                                 //Load Game
  139.                                                 if (result == 1)
  140.                                                 {
  141.                                                         if (fileExists(savename) == 1) {
  142.                                                                 loadSave(savename);
  143.                                                         }else if (fileExists(savemap) == 1) {
  144.                                                                 loadSave(savemap);                                     
  145.                                                         }
  146.                                                 }
  147.                                                 ++em_state;
  148.                                         }
  149.                                 }
  150.                                 break;
  151.                 case 2:
  152.                                 //Update resources, depending on level
  153.                                 loadUncommonImages();
  154.                                 PHL_FreeSurface(images[imgTiles]);
  155.                                 images[imgTiles] = PHL_LoadQDA(tilesetStrings[level]);
  156.                                
  157.                                 PHL_FreeMusic(bgmMusic);
  158.                                 bgmMusic = PHL_LoadMusic(musicStrings[level], 1);
  159.  
  160.                                 loadScreen();
  161.                                 em_state = 10;
  162.                                 break;
  163.                 case 10:        // main game loop
  164.                                 PHL_MainLoop();
  165.                                 PHL_ScanInput();       
  166.                                 result = gameStep();
  167.                                 if(!result)
  168.                                         em_state = 20;
  169.                                 else {
  170.                                         if(result!=-1)
  171.                                                 em_state = result;
  172.                                         else {
  173.                                                 PHL_StartDrawing();                                    
  174.                                                 gameDraw(1);                                   
  175.                                                 PHL_EndDrawing();
  176.                                         }
  177.                                 }
  178.                                 break;
  179.                 case 20:        // game ended
  180.                         roomDarkness = 0;      
  181.                         freeArrays();
  182.                        
  183.                         //Erase temp save if it exists
  184.                         if (fileExists(savename))
  185.                         {
  186.                                 remove(savename);
  187.                                 #ifdef EMSCRIPTEN
  188.                                 EM_ASM(
  189.                                         FS.syncfs(false,function () {
  190.                                                 Module.print("File sych'd")
  191.                                         });
  192.                                 );
  193.                                 #endif
  194.                         }
  195.                         em_state = 0;
  196.                         break;
  197.                 case 30:        // option menu
  198.                                 optionsSetup(0);
  199.                                 ++em_state;
  200.                                 // fall thru
  201.                 case 31:
  202.                                 result = optionsEMStep();
  203.                                
  204.                                 //Reset Game
  205.                                 if (result == 1)
  206.                                         em_state = 20;
  207.                                 else if (result == 3) {
  208.                                         em_state = 100;
  209.                                 } else if (result!=-1)
  210.                                         em_state = 10;
  211.                                 break;
  212.                 case 40:
  213.                                 inventorySetup();
  214.                                 ++em_state;
  215.                 case 41:
  216.                                 result = inventoryEMStep();
  217.                                 if(result==0)
  218.                                         em_state = 10;
  219.                                 break;
  220.                 case 50:
  221.                                 result = getItemEMStep();
  222.                                 if(result==0)
  223.                                         em_state = 10;
  224.                                 break;
  225.                 case 60:        // option menu
  226.                                 optionsSetup(1);
  227.                                 ++em_state;
  228.                                 // fall thru
  229.                 case 61:
  230.                                 result = optionsEMStep();
  231.                                
  232.                                 if (result!=-1)
  233.                                         em_state = 0;
  234.                                 break;
  235.                 case 100:
  236.                                 /*
  237.                                 //Free Resources
  238.                                 textFree();
  239.                                 freeResources();
  240.                                
  241.                                 //Deinit services
  242.                                 PHL_Deinit();
  243.                                 // end
  244.                                 emscripten_cancel_main_loop();
  245.                                 */
  246.                                 em_state = 0;   // no quitting, as it make no sense in a browser (just kill the tab)
  247.                                 break;
  248.         }
  249.  
  250. }
  251. #endif
  252.  
  253. void game()
  254. {
  255. #ifdef _SDL
  256.         #if defined(__amigaos4__) || defined(__MORPHOS__)
  257.         const char* home = "PROGDIR:";
  258.         #elif defined(EMSCRIPTEN)
  259.         const char* home = "hcl_data/";
  260.         #elif defined(_KOLIBRI)
  261.         const char* home = KOS_TMP_DIR;
  262.         #else
  263.         const char* home = getenv("HOME");
  264.         #endif
  265.         if(home)
  266.         {
  267.                 strcpy(savename, home);
  268.                 #if defined(__amigaos4__) || defined(__MORPHOS__)
  269.                 strcat(savename, ".hydracastlelabyrinth/");
  270.                 #elif !defined(EMSCRIPTEN)
  271.                 strcat(savename, "/.hydracastlelabyrinth/");
  272.                 #endif
  273.                 strcpy(savemap, savename);
  274.                 strcat(savename, "save.tmp");
  275.                 strcat(savemap, "save.map");
  276.         } else {
  277.                 strcpy(savename, "data/save.tmp");
  278.                 strcpy(savemap, savemap);
  279.         }
  280. #endif
  281.         //Setup services
  282.         printf("DBG:0\n");
  283.         PHL_Init();
  284.         if(1!=initQDA())
  285.         {
  286.                 printf("DBG:QDA FAILED\n");
  287.         }
  288.         printf("DBG: 1\n");    
  289.         textInit();
  290.         printf("DBG: 2\n");
  291.         #ifdef EMSCRIPTEN
  292.         emscripten_set_main_loop_arg(em_loop_fn, NULL, -1, 1);
  293.         #else
  294.         iniInit();
  295.         printf("DBG: 3\n");
  296.         //Load Resources
  297.         loadText();    
  298.         printf("DBG: 4\n");
  299.         loadResources();
  300.         printf("DBG: 5\n");
  301.  
  302.  
  303.         while (PHL_MainLoop())
  304.         {              
  305.                 //Titlescreen
  306.                 int titleScreenResult = titleScreen();
  307.                 printf("DBG: titleScreen()\n");
  308.                 //Exit game
  309.                 if (titleScreenResult == 3) {
  310.                         PHL_GameQuit();
  311.                 }
  312.  
  313.                 // Options
  314.                 else if(titleScreenResult == 2) {
  315.                         int optionsResult = options(1);
  316.                        
  317.                         //Exit Game
  318.                         if (optionsResult == 3) {
  319.                                 PHL_GameQuit();
  320.                         }
  321.                 }
  322.                 //Game Start
  323.                 else{
  324.                         //Reset game state
  325.                         gameSetup();
  326.                        
  327.                         //Load Game
  328.                         if (titleScreenResult == 1)
  329.                         {
  330.                                 if (fileExists(savename) == 1) {
  331.                                         loadSave(savename);
  332.                                 }else if (fileExists(savemap) == 1) {
  333.                                         loadSave(savemap);                                     
  334.                                 }
  335.                         }
  336.                        
  337.                         //Update resources, depending on level
  338.                         loadUncommonImages();
  339.                        
  340.                         /*printf("\nTiles are ");
  341.                         if (images[imgTiles].pxdata == NULL) {
  342.                                 printf("not loaded.");
  343.                         }else{
  344.                                 printf("loaded.");
  345.                         }*/
  346.                         PHL_FreeSurface(images[imgTiles]);
  347.                         images[imgTiles] = PHL_LoadQDA(tilesetStrings[level]);
  348.                        
  349.                         PHL_FreeMusic(bgmMusic);
  350.                         bgmMusic = PHL_LoadMusic(musicStrings[level], 1);
  351.  
  352.                         loadScreen();
  353.                        
  354.                         //In game main loop
  355.                         char gameLoop = 1;
  356.                        
  357.                         while (PHL_MainLoop() == 1 && gameLoop == 1) {
  358.                                 PHL_ScanInput();
  359.                                
  360.                                 int gameResult = gameStep();
  361.                                
  362.                                 if (gameResult != -1) {
  363.                                         gameLoop = 0;
  364.                                 }
  365.                                
  366.                                 if (gameLoop == 1) {
  367.                                         PHL_StartDrawing();                                    
  368.                                         gameDraw(1);                                   
  369.                                         PHL_EndDrawing();
  370.                                 }
  371.                         }
  372.                        
  373.                         //Game end (return to titlescreen)
  374.                         roomDarkness = 0;      
  375.                         freeArrays();
  376.                        
  377.                         //Erase temp save if it exists
  378.                         if (fileExists(savename))
  379.                         {
  380.                                 #ifdef _SDL
  381.                                 remove(savename);
  382.                                 #else
  383.                                 char fullPath[128];
  384.                                 strcpy(fullPath, "");
  385.                                 #ifdef _3DS
  386.                                 strcat(fullPath, "sdmc:/3ds/appdata/HydraCastleLabyrinth/");
  387.                                 #endif
  388.                                 strcat(fullPath, savename);
  389.                                 remove(fullPath);
  390.                                 #endif
  391.                                 #ifdef EMSCRIPTEN
  392.                                 EM_ASM(
  393.                                         FS.syncfs(false,function () {
  394.                                                 Module.print("File sych'd")
  395.                                         });
  396.                                 );
  397.                                 #endif
  398.                         }
  399.                 }
  400.         }
  401.        
  402.         //Free Resources
  403.         textFree();
  404.         freeResources();
  405.        
  406.         //Deinit services
  407.         PHL_Deinit();
  408.         #endif
  409. }
  410.  
  411. void loadImages()
  412. {
  413.         images[imgTiles]                = PHL_LoadQDA(tilesetStrings[level]);
  414.         images[imgEnemies]              = PHL_LoadQDA("ene01.bmp");
  415.         images[imgHud]                  = PHL_LoadQDA("status.bmp");
  416.         images[imgMisc20]               = PHL_LoadQDA("chr20.BMP");
  417.         images[imgMisc32]               = PHL_LoadQDA("chr32.BMP");
  418.         images[imgHero]                 = PHL_LoadQDA("mychr.bmp");
  419.         images[imgItems]                = PHL_LoadQDA("items.bmp");
  420.         images[imgExplosion]    = PHL_LoadQDA("chr64.BMP");
  421.         images[imgBoss]                 = PHL_LoadQDA("boss01.bmp");
  422.         //images[imgMisc2040]   = PHL_LoadQDA("chr20x40.BMP");
  423.         images[imgFontKana]     = PHL_LoadQDA("font8x8-kana.bmp");
  424.         images[imgBoldFont]     = PHL_LoadQDA("font8x8-01.bmp");
  425.         //images[imgDark]               = PHL_LoadQDA("dark.bmp");
  426.         //images[imgMisc6020]   = PHL_LoadQDA("chr60x20.bmp");
  427.         //images[imgHud].colorKey = PHL_NewRGB(0, 0, 0);
  428.         //PHL_SetColorKey(images[imgHud], 0, 0, 0);
  429.         images[imgTitle01]              = PHL_LoadQDA("title01.BMP");
  430. }
  431.        
  432. void loadResources()
  433. {      
  434.         //Loading Images
  435.         loadImages();
  436.         puts("DBG loadResources1");
  437.         //Load Sounds  
  438.         sounds[sndBee01]        = PHL_LoadSound("wav/bee01.wav");      
  439.         sounds[sndBell01]       = PHL_LoadSound("wav/bell01.wav");
  440.         sounds[sndBom01]        = PHL_LoadSound("wav/bom01.wav");
  441.         sounds[sndBom02]        = PHL_LoadSound("wav/bom02.wav");
  442.         sounds[sndBom03]        = PHL_LoadSound("wav/bom03.wav");
  443.         sounds[sndDoor00]       = PHL_LoadSound("wav/door00.wav");
  444.         sounds[sndFire01]       = PHL_LoadSound("wav/fire01.wav");
  445.         sounds[sndGas01]        = PHL_LoadSound("wav/gas01.wav");
  446.         sounds[sndGet01]        = PHL_LoadSound("wav/get01.wav");
  447.         sounds[sndGet02]        = PHL_LoadSound("wav/get02.wav");
  448.         sounds[sndHit01]        = PHL_LoadSound("wav/hit01.wav");
  449.         sounds[sndHit02]        = PHL_LoadSound("wav/hit02.wav");
  450.         sounds[sndHit03]        = PHL_LoadSound("wav/hit03.wav");
  451.         sounds[sndHit04]        = PHL_LoadSound("wav/hit04.wav");
  452.         sounds[sndHit05]        = PHL_LoadSound("wav/hit05.wav");
  453.         sounds[sndHit06]        = PHL_LoadSound("wav/hit06.wav");
  454.         sounds[sndHit07]        = PHL_LoadSound("wav/hit07.wav");      
  455.         sounds[sndJump01]       = PHL_LoadSound("wav/jump01.wav");
  456.         sounds[sndJump02]       = PHL_LoadSound("wav/jump02.wav");
  457.         sounds[sndNg]           = PHL_LoadSound("wav/ng.wav");
  458.         sounds[sndOk]           = PHL_LoadSound("wav/ok.wav");
  459.         sounds[sndPi01]         = PHL_LoadSound("wav/pi01.wav");
  460.         sounds[sndPi02]         = PHL_LoadSound("wav/pi02.wav");
  461.         sounds[sndPi03]         = PHL_LoadSound("wav/pi03.wav");
  462.         sounds[sndPi04]         = PHL_LoadSound("wav/pi04.wav");
  463.         sounds[sndPi05]         = PHL_LoadSound("wav/pi05.wav");
  464.         sounds[sndPi06]         = PHL_LoadSound("wav/pi06.wav");
  465.         sounds[sndPi07]         = PHL_LoadSound("wav/pi07.wav");
  466.         sounds[sndPi08]         = PHL_LoadSound("wav/pi08.wav");
  467.         sounds[sndPi09]         = PHL_LoadSound("wav/pi09.wav");
  468.         sounds[sndPi10]         = PHL_LoadSound("wav/pi10.wav");
  469.         sounds[sndPower01]      = PHL_LoadSound("wav/power01.wav");
  470.         sounds[sndPower02]      = PHL_LoadSound("wav/power02.wav");
  471.         sounds[sndShot01]       = PHL_LoadSound("wav/shot01.wav");
  472.         sounds[sndShot02]       = PHL_LoadSound("wav/shot02.wav");
  473.         sounds[sndShot03]       = PHL_LoadSound("wav/shot03.wav");
  474.         sounds[sndShot04]       = PHL_LoadSound("wav/shot04.wav");
  475.         sounds[sndShot05]       = PHL_LoadSound("wav/shot05.wav");
  476.         sounds[sndShot06]       = PHL_LoadSound("wav/shot06.wav");
  477.         sounds[sndShot07]       = PHL_LoadSound("wav/shot07.wav");
  478.         sounds[sndStep01]       = PHL_LoadSound("wav/step01.wav");
  479.         sounds[sndWater01]      = PHL_LoadSound("wav/water01.wav");
  480.         sounds[sndWolf01]       = PHL_LoadSound("wav/wolf01.wav");
  481.         puts("DBG loadResources2");
  482.         //Load Music
  483.         bgmSecret = PHL_LoadMusic("midi/nazo", 0);
  484.         puts("DBG loadResources3");
  485.         bgmGameover = PHL_LoadMusic("midi/gameover", 0);
  486.         puts("DBG loadResources4");
  487. }
  488.  
  489. void freeImages()
  490. {
  491.         int i;
  492.  
  493.         //Free graphics
  494.         for (i = 0; i < NumOfImages; i++) {
  495.                 PHL_FreeSurface(images[i]);
  496.         }
  497. }
  498.  
  499. void freeResources()
  500. {
  501.         //Free sounds
  502.         int i;
  503.         for (i = 0; i < NumOfSounds; i++) {
  504.                 PHL_FreeSound(sounds[i]);
  505.         }
  506.        
  507.         //Free Music
  508.         PHL_FreeMusic(bgmMusic);
  509.         PHL_FreeMusic(bgmGameover);
  510.         PHL_FreeMusic(bgmSecret);
  511.  
  512.         freeImages();
  513. }
  514.  
  515. void gameSetup()
  516. {      
  517.         //Reset Flags
  518.         {
  519.                 quakeTimer = 0;
  520.                 secretTimer = 0;
  521.                 roomDarkness = 0;
  522.                
  523.                 bellFlag = 0;
  524.                 bossFlag = 0;
  525.                 bossDefeatedFlag = 0;
  526.                
  527.                 int i;
  528.                 for (i = 0; i < 60; i++) {
  529.                         flags[i] = 0;
  530.                 }
  531.         }
  532.        
  533.         //Save Data
  534.         {
  535.                 playTime = 0;
  536.                
  537.                 //Inventory    
  538.                 int i;
  539.                 for (i = 0; i < 5; i++) {
  540.                         hasWeapon[i] = 0;
  541.                 }
  542.                
  543.                 for (i = 0; i < 28; i++) {
  544.                         hasItem[i] = 0;
  545.                 }
  546.                
  547.                 for (i = 0; i< 8; i++) {
  548.                         hasKey[i] = 0;
  549.                 }
  550.         }
  551.                
  552.         //Room Data
  553.         {
  554.                 roomSecret = 0;
  555.                 level = 0;
  556.                 screenX = 5;
  557.                 screenY = 2;
  558.         }
  559.        
  560.         //Hero Setup
  561.         {
  562.                 heroSetup();
  563.                 drawhp = herohp;
  564.         }      
  565.        
  566.         //Reset object arrays
  567.         freeArrays();
  568.        
  569.         //Setup screen transition
  570.         cutInTimer = 240;
  571. }
  572.  
  573. int gameStep()
  574. {      
  575.         //Manage Timers
  576.         {
  577.                 playTime += 1;
  578.                
  579.                 secretCountdown();
  580.                        
  581.                 if (quakeTimer > 0) {
  582.                         quakeTimer -= 1;
  583.                 }
  584.                
  585.                 if (cutInTimer > 0) {
  586.                         cutInTimer -= 5;
  587.                        
  588.                         //Play music when the transition ends
  589.                         if (cutInTimer <= 0 && bossDefeatedFlag == 0 && bossFlag == 0) {
  590.                                 PHL_PlayMusic(bgmMusic);
  591.                         }
  592.                 }
  593.         }
  594.        
  595.         //Hero step
  596.         {
  597.                 //End game if hero died
  598.                 if (heroStep() == 1) {         
  599.                         return 0;
  600.                 }
  601.         }
  602.        
  603.         //Menu button presses
  604.         {
  605.                 if (getHeroState() <= 5 && cutInTimer <= 0) {
  606.                         if (btnSelect.pressed == 1)
  607.                         {
  608.                                 #ifdef EMSCRIPTEN
  609.                                 optionsSetup(0);
  610.                                 return 31;
  611.                                 #else                                          
  612.                                 int optionsResult = options(0);
  613.                                
  614.                                 //Reset Game
  615.                                 if (optionsResult == 1) {
  616.                                         return 0;
  617.                                 }
  618.                                 //Exit Game
  619.                                 if (optionsResult == 3) {
  620.                                         PHL_GameQuit();
  621.                                         return 1;
  622.                                 }
  623.                                 #endif
  624.                         }else if (btnStart.pressed == 1) {     
  625.                                 #ifdef EMSCRIPTEN
  626.                                 return 40;
  627.                                 #else
  628.                                 inventory();
  629.                                 #endif
  630.                         }
  631.                 }
  632.         }
  633.        
  634.         //Objects steps
  635.         {
  636.                 int i;
  637.                 for (i = 0; i < MAX_PLATFORMS; i++) {
  638.                         if (platforms[i] != NULL) {
  639.                                 platformStep(platforms[i]);
  640.                         }
  641.                 }
  642.                
  643.                 for (i = 0; i < MAX_OBJECTS; i++) {
  644.                         if (objects[i] != NULL) {
  645.                                 objects[i]->objectStep(objects[i]->data);
  646.                         }
  647.                 }
  648.                
  649.                 for (i = 0; i < MAX_WEAPONS; i++) {
  650.                         if (weapons[i] != NULL) {
  651.                                 weaponStep(weapons[i]);
  652.                         }
  653.                 }
  654.                
  655.                 for (i = 0; i < MAX_EFFECTS; i++) {
  656.                         if (effects[i] != NULL) {
  657.                                 effectStep(effects[i]);
  658.                         }
  659.                 }
  660.  
  661.                 for (i = 0; i < MAX_ENEMIES; i++) {
  662.                         if (enemies[i] != NULL) {
  663.                                 enemies[i]->enemyStep(enemies[i]->data);
  664.                         }
  665.                 }
  666.         }
  667.        
  668.         if (forceGameExit == 1) {
  669.                 forceGameExit = 0;
  670.                 return 0;
  671.         }
  672.        
  673.         return -1;
  674. }
  675.  
  676. void gameDraw(char doDrawHud)
  677. {      
  678.         PHL_DrawBackground(background, foreground);
  679.        
  680.         int i;
  681.         //Draw water/lava top effects
  682.         for (i = 0; i < MAX_EFFECTS; i++) {
  683.                 if (effects[i] != NULL) {
  684.                         if (effects[i]->depth == -1) {
  685.                                 effectDraw(effects[i]);
  686.                         }
  687.                 }
  688.         }
  689.        
  690.         for (i = 0; i < MAX_PLATFORMS; i++) {
  691.                 if (platforms[i] != NULL) {
  692.                         platformDraw(platforms[i]);
  693.                 }
  694.         }
  695.        
  696.         for (i = 0; i < MAX_OBJECTS; i++) {
  697.                 if (objects[i] != NULL) {
  698.                         objects[i]->objectDraw(objects[i]->data);
  699.                 }
  700.         }
  701.        
  702.         for (i = 0; i < MAX_WEAPONS; i++) {
  703.                 if (weapons[i] != NULL) {
  704.                         weaponDraw(weapons[i]);
  705.                 }
  706.         }      
  707.        
  708.         //Draw effects under
  709.         for (i = 0; i < MAX_EFFECTS; i++) {
  710.                 if (effects[i] != NULL) {
  711.                         if (effects[i]->depth == 0) {
  712.                                 effectDraw(effects[i]);
  713.                         }
  714.                 }
  715.         }
  716.        
  717.         //Draw enemies backwards, so bullets and such are underneath their spawners
  718.         //for (i = MAX_ENEMIES - 1; i >= 0; i--) {
  719.         for (i = 0; i < MAX_ENEMIES; i++) {
  720.                 if (enemies[i] != NULL) {
  721.                         enemies[i]->enemyDraw(enemies[i]->data);
  722.                 }
  723.         }
  724.        
  725.         //Not Death, draw death later
  726.         if (getHeroState() != 8) {
  727.                 heroDraw();
  728.         }
  729.        
  730.         //Draw effects over
  731.         for (i = 0; i < MAX_EFFECTS; i++) {
  732.                 if (effects[i] != NULL) {
  733.                         if (effects[i]->depth == 1) {
  734.                                 effectDraw(effects[i]);
  735.                         }
  736.                 }
  737.         }
  738.        
  739.         //Draw Darkness
  740.         if (roomDarkness == 1) {
  741.                 int cornerX = herox - 160,
  742.                         cornerY = heroy + 20 - 160;
  743.                
  744.                 PHL_DrawSurfacePart(cornerX, cornerY, 320 * hasItem[18], 0, 320, 320, images[imgDark]);
  745.                
  746.                 //Top darkness rectangle
  747.                 if (cornerY > 0) {
  748.                         PHL_DrawRect(0, 0, 640, cornerY, PHL_NewRGB(10, 0, 0));
  749.                 }
  750.                 //Bottom darkness rectangle
  751.                 if (cornerY + 320 < 480) {
  752.                         PHL_DrawRect(0, cornerY + 320, 640, 480, PHL_NewRGB(10, 0, 0));
  753.                 }
  754.                
  755.                 //Left rectangle
  756.                 if (cornerX > 0) {
  757.                         PHL_DrawRect(0, cornerY, cornerX, 320, PHL_NewRGB(10, 0, 0));
  758.                 }
  759.                 //Right rectangle
  760.                 if (cornerX + 320 < 640) {
  761.                         PHL_DrawRect(cornerX + 320, cornerY, 640 - cornerX + 320, 320, PHL_NewRGB(10, 0, 0));
  762.                 }              
  763.         }
  764.        
  765.         //Draw death over darkness
  766.         if (getHeroState() == 8) {
  767.                 heroDraw();
  768.         }
  769.        
  770.         if (doDrawHud == 1) {
  771.                 drawHud();
  772.         }
  773.        
  774.         //cut-in transition
  775.         {
  776.                 if (cutInTimer > 0)     {
  777.                         PHL_DrawRect(0, 0, 640, cutInTimer, PHL_NewRGB(0, 0, 0));
  778.                         PHL_DrawRect(0, 240 + (240 - cutInTimer), 640, 480, PHL_NewRGB(0, 0, 0));              
  779.                 }
  780.         }
  781.        
  782. }
  783. #ifdef EMSCRIPTEN
  784. static int em_itemNum;
  785. static char getItemTimer;
  786. void getItemSetup(int itemNum)
  787. {
  788.         setHeroState(6);
  789.         setHeroImageIndex(0);
  790.        
  791.         char getItemTimer = 0;
  792. }
  793. int getItemEMStep()
  794. {
  795.         int itemNum = em_itemNum;
  796.         char loop = 1;
  797.         PHL_MainLoop();
  798. #else
  799. void getItem(int itemNum)
  800. {
  801.         setHeroState(6);
  802.         setHeroImageIndex(0);
  803.        
  804.         char getItemTimer = 0;
  805.         char loop = 1;
  806.        
  807.         while (PHL_MainLoop() && loop == 1)
  808. #endif
  809.         {
  810.                 secretCountdown();
  811.                 //Get Item Step        
  812.                 if (getItemTimer == 0) {
  813.                         setHeroImageIndex(getHeroImageIndex() + 0.3);
  814.                         if (getHeroImageIndex() > 3) {
  815.                                 getItemTimer = 1;
  816.                         }
  817.                 }else if (getItemTimer == 1) {
  818.                         //Wait for input
  819.                         PHL_ScanInput();
  820.                        
  821.                         if (btnAccept.pressed == 1 || btnFaceDown.pressed == 1 || btnFaceRight.pressed == 1 ||
  822.                                 btnFaceUp.pressed == 1 || btnFaceLeft.pressed == 1 || btnStart.pressed == 1) {
  823.                                 getItemTimer = 2;
  824.                         }
  825.                 }else if (getItemTimer == 2) {
  826.                         setHeroImageIndex(getHeroImageIndex() + 0.3);
  827.                         if (getHeroImageIndex() >= 7) {
  828.                                 loop = 0;
  829.                                
  830.                                 setHeroState(0);
  831.                                 setHeroImageIndex(0);
  832.                         }
  833.                 }              
  834.                
  835.                 //Get Item Draw
  836.                 {
  837.                         PHL_StartDrawing();
  838.                        
  839.                         gameDraw(1);
  840.                        
  841.                         if (getHeroImageIndex() >= 3) {
  842.                                 char tempDarkness = roomDarkness;
  843.                                 roomDarkness = 0;
  844.                                
  845.                                 PHL_DrawRect(140, 208, 360, 64, PHL_NewRGB(255, 255, 255));
  846.                                 PHL_DrawRect(142, 210, 356, 60, PHL_NewRGB(0, 20, 0));
  847.                                
  848.                                 PHL_DrawRect(148, 216, 48, 48, PHL_NewRGB(255, 255, 255));
  849.                                 PHL_DrawRect(152, 220, 40, 40, PHL_NewRGB(119, 166, 219));
  850.                                 //Image
  851.                                 PHL_DrawSurfacePart(152, 220, itemGotX, itemGotY, 40, 40, images[imgItems]);
  852.                                 //Text
  853.                                 {
  854.                                         int drawX = 196, drawY = 216;
  855.                                         int twoLayers = 0;
  856.                                         if (itemName[itemNum]->length + found->length + 2 > 17) {
  857.                                                 twoLayers = 1;
  858.                                                 drawY -= 8;
  859.                                         }
  860.                                         drawX = drawCharacter(17, 2, drawX, drawY);
  861.                                         drawX = drawText(itemName[itemNum], drawX, drawY);
  862.                                         drawX = drawCharacter(18, 2, drawX, drawY);
  863.                                         if (twoLayers == 1) {
  864.                                                 drawX = 204;
  865.                                                 drawY += 24;
  866.                                         }
  867.                                         drawText(found, drawX, drawY);
  868.                                 }
  869.                                
  870.                                 roomDarkness = tempDarkness;
  871.                         }
  872.                                                
  873.                         PHL_EndDrawing();
  874.                 }
  875.         }      
  876. #ifdef EMSCRIPTEN
  877.         return loop;
  878. #endif
  879. }
  880.  
  881. void saveScreen()
  882. {
  883.         PHL_PlaySound(sounds[sndPower02], CHN_SOUND);
  884.         herohp = maxhp;
  885.         setHeroHsp(0);
  886.        
  887.         int saveTimer = 60;
  888.         char loop = 1;
  889.        
  890.         while (PHL_MainLoop() && loop == 1)
  891.         {
  892.                 PHL_StartDrawing();
  893.  
  894.                 gameDraw(1);
  895.                
  896.                 PHL_DrawRect(140, 208, 360, 64, PHL_NewRGB(255, 255, 255));
  897.                 PHL_DrawRect(142, 210, 356, 60, PHL_NewRGB(0, 0, 255));
  898.                 drawTextCentered(saving, 320, 216);
  899.                
  900.                 saveTimer -= 1;
  901.                 if (saveTimer <= 0) {
  902.                         loop = 0;
  903.                 }
  904.                
  905.                 PHL_EndDrawing();
  906.         }
  907.        
  908.         if (writeSave(savemap) == 1)
  909.         {
  910.                 if (fileExists(savename))
  911.                 {
  912.                         char fullPath[128];
  913.                         strcpy(fullPath, "");
  914.                         #ifdef _3DS
  915.                                 strcat(fullPath, "sdmc:/3ds/appdata/HydraCastleLabyrinth/");
  916.                         #endif
  917.                         strcat(fullPath, savename);
  918.                         remove(fullPath);
  919.                         #ifdef EMSCRIPTEN
  920.                         EM_ASM(
  921.                                 FS.syncfs(false,function () {
  922.                                         Module.print("File sych'd")
  923.                                 });
  924.                         );
  925.                         #endif
  926.                 }
  927.         }
  928. }
  929.  
  930. //Result screen and credits
  931. void gameEnding()
  932. {
  933.         int timer = 0;
  934.         char exitLoop = 0;
  935.        
  936.         //Result screen
  937.         {
  938.                 PHL_StopMusic();
  939.                 PHL_FreeMusic(bgmMusic);
  940.                 bgmMusic = PHL_LoadMusic("midi/allclear", 0);
  941.                 PHL_PlayMusic(bgmMusic);
  942.                
  943.                 //Calculate completion percentage
  944.                 char treasureString[11];
  945.                 {
  946.                         int itemCount = 0;
  947.                         int ALLITEMS = 41;
  948.                        
  949.                         int i;
  950.                         for (i = 0; i < 5; i++) {
  951.                                 itemCount += hasWeapon[i];
  952.                         }
  953.                        
  954.                         for (i = 0; i < 28; i++) {
  955.                                 itemCount += hasItem[i];
  956.                         }
  957.                        
  958.                         for (i = 0; i < 8; i++) {
  959.                                 itemCount += hasKey[i];
  960.                         }
  961.                        
  962.                         sprintf(treasureString, "%d%%", itemCount * 100 / ALLITEMS);
  963.                 }
  964.                
  965.                 //Calculate time               
  966.                 char timeString[12];
  967.                 {
  968.                         int hours = playTime / 216000;
  969.                         int minutes = (playTime % 216000) / 3600;
  970.                         int seconds = ((playTime % 216000) % 3600) / 60;
  971.                        
  972.                         sprintf(timeString, "%02d:%02d:%02d", hours, minutes, seconds);
  973.                 }              
  974.                
  975.                 int transTimer = 0;
  976.                
  977.                 while (PHL_MainLoop() && exitLoop == 0)
  978.                 {
  979.                         timer += 1;
  980.                         if (timer >= 500) {
  981.                                 transTimer += 8;
  982.                         }
  983.                        
  984.                         if (transTimer >= 360) {
  985.                                 exitLoop = 1;
  986.                         }
  987.                        
  988.                         //Animate Effects
  989.                         int i;
  990.                         for (i = 0; i < MAX_EFFECTS; i++) {
  991.                                 if (effects[i] != NULL) {
  992.                                         effectStep(effects[i]);
  993.                                 }
  994.                         }
  995.                        
  996.                         PHL_StartDrawing();
  997.                        
  998.                         gameDraw(0);
  999.                        
  1000.                         PHL_DrawTextBoldCentered("--- ALL CLEAR! ---", 320, 64, YELLOW);
  1001.                        
  1002.                         PHL_DrawTextBoldCentered("TIME", 320, 128, YELLOW);
  1003.                         PHL_DrawTextBoldCentered(timeString, 320, 144, WHITE);
  1004.                        
  1005.                         PHL_DrawTextBoldCentered("TREASURE", 320, 192, YELLOW);
  1006.                         PHL_DrawTextBoldCentered(treasureString, 320, 208, WHITE);
  1007.                        
  1008.                         //transition
  1009.                         if (transTimer > 0)     {
  1010.                                 PHL_DrawRect(0, 0, 640, transTimer, PHL_NewRGB(0, 0, 0));
  1011.                                 PHL_DrawRect(0, 240 + (240 - transTimer), 640, 480, PHL_NewRGB(0, 0, 0));              
  1012.                         }
  1013.                        
  1014.                         PHL_EndDrawing();                      
  1015.                 }
  1016.         }
  1017.  
  1018.         //Credits
  1019.         {
  1020.                 timer = 0;
  1021.                 exitLoop = 0;
  1022.                
  1023.                 PHL_StopMusic();
  1024.                 PHL_FreeMusic(bgmMusic);
  1025.                 bgmMusic = PHL_LoadMusic("midi/ending", 0);
  1026.                 PHL_PlayMusic(bgmMusic);
  1027.                
  1028.                 int timer = 0;
  1029.                 double viewY = 0;
  1030.                 int maxViewY = 2200;
  1031.                 double imageIndex = 0;
  1032.                
  1033.                 while (PHL_MainLoop() && exitLoop == 0)
  1034.                 {                      
  1035.                         timer += 1;
  1036.                         if (timer >= 2220) {
  1037.                                 exitLoop = 1;
  1038.                         }
  1039.                        
  1040.                         viewY += 1;
  1041.                         if (viewY >= maxViewY - 480) {
  1042.                                 viewY = maxViewY - 480;
  1043.                         }
  1044.                        
  1045.                         imageIndex += 0.1;
  1046.                         if (imageIndex >= 2) {
  1047.                                 imageIndex -= 2;
  1048.                         }
  1049.                        
  1050.                         PHL_StartDrawing();
  1051.                        
  1052.                         PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0));
  1053.                        
  1054.                         if (exitLoop == 0) {
  1055.                                 PHL_DrawTextBoldCentered("- STAFF -", 320, 480 - viewY, YELLOW);
  1056.                                
  1057.                                 PHL_DrawTextBoldCentered("SPRITES", 320, 560 - viewY, YELLOW);
  1058.                                 PHL_DrawTextBoldCentered("BUSTER", 320, 576 - viewY, WHITE);
  1059.                                
  1060.                                 PHL_DrawTextBoldCentered("PROGRAM", 320, 640 - viewY, YELLOW);
  1061.                                 PHL_DrawTextBoldCentered("BUSTER", 320, 656 - viewY, WHITE);
  1062.                                
  1063.                                 PHL_DrawTextBoldCentered("MUSIC", 320, 720 - viewY, YELLOW);
  1064.                                 PHL_DrawTextBoldCentered("MATAJUUROU", 320, 736 - viewY, WHITE);
  1065.                                
  1066.                                 PHL_DrawTextBoldCentered("TEST PLAYER", 320, 800 - viewY, YELLOW);
  1067.                                 PHL_DrawTextBoldCentered("ZAC", 320, 816 - viewY, WHITE);
  1068.                                                        
  1069.                                 PHL_DrawTextBoldCentered("- SPECIAL THANKS -", 320, 912 - viewY, YELLOW);                      
  1070.                                                        
  1071.                                 PHL_DrawTextBoldCentered("QUADRUPLE D", 320, 992 - viewY, YELLOW);
  1072.                                 PHL_DrawTextBoldCentered("SANDMAN", 320, 1008 - viewY, WHITE);
  1073.                                                                                
  1074.                                 PHL_DrawTextBoldCentered("KBGM", 320, 1072 - viewY, YELLOW);
  1075.                                 PHL_DrawTextBoldCentered("KR.SHIN", 320, 1088 - viewY, WHITE);         
  1076.                                                        
  1077.                                 PHL_DrawTextBoldCentered("KBGMPLAYER", 320, 1152 - viewY, YELLOW);
  1078.                                 PHL_DrawTextBoldCentered("NARUTO", 320, 1168 - viewY, WHITE);
  1079.                                                        
  1080.                                 PHL_DrawTextBoldCentered("SOUND EFFECT", 320, 1232 - viewY, YELLOW);
  1081.                                 PHL_DrawTextBoldCentered("OSABISHIYUUKI", 320, 1248 - viewY, WHITE);
  1082.                                                        
  1083.                                 PHL_DrawTextBoldCentered("EDGE", 320, 1312 - viewY, YELLOW);
  1084.                                 PHL_DrawTextBoldCentered("TAKABO", 320, 1328 - viewY, WHITE);
  1085.                                
  1086.                                 PHL_DrawTextBoldCentered("THE END", 320, maxViewY - 284 - viewY, YELLOW);
  1087.                                 PHL_DrawSurfacePart(300, maxViewY - 256 - viewY, (int)imageIndex * 40, 280, 40, 80, images[imgHero]);
  1088.                         }
  1089.                        
  1090.                         PHL_EndDrawing();
  1091.                 }
  1092.                
  1093.         }
  1094.        
  1095.         forceGameExit = 1;
  1096.        
  1097. }
  1098.  
  1099. //Black screen between screens
  1100. void screenTransition()
  1101. {
  1102.         char timer = 15;
  1103.        
  1104.         while (PHL_MainLoop() && timer > 0)
  1105.         {
  1106.                 PHL_StartDrawing();
  1107.                
  1108.                 PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0));
  1109.                 timer -= 1;
  1110.                
  1111.                 PHL_EndDrawing();
  1112.         }
  1113.        
  1114.         if (autoSave == 1) {
  1115.                 writeSave(savename);
  1116.         }
  1117. }
  1118.  
  1119. void enterDoor()
  1120. {      
  1121.         //Is not leaving boss room prematurely
  1122.         bossFlag = 0;
  1123.  
  1124.         level = lastDoor->warplevel;
  1125.        
  1126.         screenX = lastDoor->warpcoords % 12;
  1127.         screenY = lastDoor->warpcoords / 12;
  1128.        
  1129.         herox = lastDoor->warpx;
  1130.         heroy = lastDoor->warpy;
  1131.  
  1132.         PHL_StopMusic();
  1133.         PHL_FreeMusic(bgmMusic);
  1134.  
  1135.         if (level == 0) {
  1136.                 //Free uncommon images
  1137.                 PHL_FreeSurface(images[imgMisc2040]);
  1138.                 PHL_FreeSurface(images[imgMisc6020]);
  1139.                 PHL_FreeSurface(images[imgDark]);
  1140.         }else{
  1141.                 bgmMusic = PHL_LoadMusic("midi/start", 0);
  1142.                 PHL_PlayMusic(bgmMusic);
  1143.                
  1144.                 int timer = 125;               
  1145.                 while (PHL_MainLoop() && timer > 0)
  1146.                 {
  1147.                         timer -= 1;
  1148.                        
  1149.                         PHL_StartDrawing();
  1150.                        
  1151.                         PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0));
  1152.                         drawTextCentered(dungeon[level - 1], 320, 216);
  1153.                        
  1154.                         PHL_EndDrawing();
  1155.                 }
  1156.                
  1157.                 PHL_StopMusic();
  1158.                 PHL_FreeMusic(bgmMusic);
  1159.                
  1160.                 loadUncommonImages();
  1161.         }
  1162.        
  1163.         //Reload tileset
  1164.         PHL_FreeSurface(images[imgTiles]);
  1165.         images[imgTiles] = PHL_LoadQDA(tilesetStrings[level]);
  1166.        
  1167.         bgmMusic = PHL_LoadMusic(musicStrings[level], 1);
  1168.        
  1169.         changeScreen(0, 0);
  1170.        
  1171.         PHL_PlayMusic(bgmMusic);
  1172. }
  1173.  
  1174. void loadScreen()
  1175. {
  1176.         //Stop music if you leave a boss room early
  1177.         if (bossFlag == 1) {
  1178.                 PHL_StopMusic();
  1179.                 PHL_FreeMusic(bgmMusic);
  1180.                
  1181.                 bgmMusic = PHL_LoadMusic(musicStrings[level], 1);
  1182.                 PHL_PlayMusic(bgmMusic);
  1183.         }
  1184.        
  1185.         bossDefeatedFlag = bossFlag = 0;
  1186.         roomDarkness = 0;
  1187.        
  1188.         screenTransition();
  1189.        
  1190.         int fileNum = stage[level][(screenY * 12) + screenX];
  1191.        
  1192.         //Cycle through this process twice. Once for the backgroud, and one for the foreground
  1193.         int cycle = 0;
  1194.         for (cycle = 0; cycle < 2; cycle++)
  1195.         {
  1196.                 //Build file string
  1197.                 char toChar[4];
  1198.                 sprintf(toChar, "%03d", fileNum);
  1199.                
  1200.                 char dest[80];
  1201.                 strcpy(dest, "");
  1202.                 #ifdef _3DS
  1203.                         strcat(dest, "romfs:/map/");
  1204.                 #elif defined(__amigaos4__) || defined(__MORPHOS__)
  1205.                         strcat(dest, "PROGDIR:data/map/");
  1206.                 #elif defined(_SDL)
  1207.                         strcat(dest, "data/map/");
  1208.                 #else
  1209.                         strcat(dest, "romfs/map/");
  1210.                 #endif
  1211.                 strcat(dest, toChar);
  1212.                
  1213.                 //load background on first pass
  1214.                 if (cycle == 0) {
  1215.                         strcat(dest, "a");
  1216.                 }
  1217.                 strcat(dest, ".map");
  1218.                
  1219.                 //Read file
  1220.                 FILE* file;
  1221.                 if ((file = fopen(dest, "rb")))
  1222.                 {
  1223.                         char* memblock;
  1224.                         int size;
  1225.                        
  1226.                         fseek(file, 0, SEEK_END);
  1227.                         size = ftell(file);
  1228.                         memblock = (char*)malloc(size);
  1229.                         fseek(file, 0, SEEK_SET);
  1230.                         if(fread(memblock, 1, size, file) != size)
  1231.                                 printf("Warning, could not read %s correctly\n", dest);
  1232.                         fclose(file);
  1233.                        
  1234.                         //Load data
  1235.                         int count = 162; //Level data starts 118
  1236.                         int xx, yy;
  1237.                         int valx = 0, valy = 0;
  1238.                         int raw;
  1239.                         for (yy = 0; yy < 12; yy++) {
  1240.                                 for (xx = 0; xx < 16; xx++) {
  1241.                                         raw = (unsigned)memblock[count];
  1242.                                         valx = raw & 0x0F;
  1243.                                         valy = raw & 0xF0;
  1244.                                         valy >>= 4;
  1245.                                        
  1246.                                         if (cycle == 0) {
  1247.                                                 background.tileX[xx][yy] = valx;
  1248.                                                 background.tileY[xx][yy] = valy;
  1249.                                         }else if (cycle == 1) {
  1250.                                                 foreground.tileX[xx][yy] = valx;
  1251.                                                 foreground.tileY[xx][yy] = valy;
  1252.                                                
  1253.                                                 collisionTiles[xx][yy] = getTileType(valx, valy);
  1254.                                                 //Breakable blocks
  1255.                                                 if (valy == 11 && (valx == 0 || valx == 1 || valx == 2)) {
  1256.                                                         int secret = 0;
  1257.                                                         if (valx == 2) {
  1258.                                                                 secret = 1;
  1259.                                                         }
  1260.                                                         createDestroyable(xx * 40, yy * 40, secret);
  1261.                                                 }
  1262.                                                
  1263.                                                 //Lava
  1264.                                                 if (valx == 2 && valy == 1) {
  1265.                                                         createEffect(10, xx * 40, yy * 40);
  1266.                                                         foreground.tileX[xx][yy] = 0;
  1267.                                                         foreground.tileY[xx][yy] = 0;
  1268.                                                 }
  1269.                                                
  1270.                                                 //Water
  1271.                                                 if (valx == 6 && valy == 1) {
  1272.                                                         createEffect(11, xx * 40, yy * 40);
  1273.                                                         foreground.tileX[xx][yy] = 0;
  1274.                                                         foreground.tileY[xx][yy] = 0;
  1275.                                                 }
  1276.                                         }
  1277.                                        
  1278.                                         count += 2;
  1279.                                 }
  1280.                                 count += 12;
  1281.                         }
  1282.                        
  1283.                         free(memblock);
  1284.                        
  1285.                 }else{
  1286.                         PHL_ErrorScreen("Map file was not found");
  1287.                 }              
  1288.         }
  1289.         PHL_UpdateBackground(background, foreground);
  1290.        
  1291.         //Load file
  1292.         //Build file string            
  1293.         char toChar[4];
  1294.         sprintf(toChar, "%03d", fileNum);
  1295.        
  1296.         char dest[30];
  1297.         #ifdef _3DS
  1298.                 strcpy(dest, "romfs:/obj/");
  1299.         #elif defined(__amigaos4__) || defined(__MORPHOS__)
  1300.                 strcpy(dest, "PROGDIR:data/obj/");
  1301.         #elif defined(_SDL)
  1302.                 strcpy(dest, "data/obj/");
  1303.         #else
  1304.                 strcpy(dest, "romfs/obj/");
  1305.         #endif
  1306.        
  1307.        
  1308.         //Add a 0 if needed
  1309.         /*
  1310.         if (fileNum < 100) {
  1311.                 strcat(dest, "0");
  1312.         }
  1313.         */
  1314.         strcat(dest, toChar);
  1315.         strcat(dest, ".dat");
  1316.        
  1317.         FILE* file;
  1318.         if ((file = fopen(dest, "rb"))) {
  1319.                 unsigned char* memblock;
  1320.                 int size;
  1321.                        
  1322.                 fseek(file, 0, SEEK_END);
  1323.                 size = ftell(file);
  1324.                 memblock = (unsigned char*)malloc(size);
  1325.                 fseek(file, 0, SEEK_SET);
  1326.                 if(fread(memblock, 1, size, file) != size)
  1327.                         printf("Warning: could not read %s correctly\n", dest);
  1328.                
  1329.                 int count = 0;
  1330.                 while (count < size) {
  1331.                         int type = memblock[count];
  1332.                        
  1333.                         if (type <= 10)
  1334.                         {                      
  1335.                                 if (type == 0 || type == 9) { //Blue/Red Slime
  1336.                                         createSlime(memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3], memblock[count + 4]);
  1337.                                 }
  1338.                                 else if (type == 1) { //Bat (grey/red)
  1339.                                         createBat(memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3]);
  1340.                                 }
  1341.                                 else if (type == 2) { //Slug
  1342.                                         createSlug(memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3]);
  1343.                                 }
  1344.                                 else if (type == 3) { //Knight
  1345.                                         createKnight(memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3]);
  1346.                                 }
  1347.                                 else if (type == 4) { //Rhyno head
  1348.                                         createHead(0, memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3], memblock[count+4], memblock[count+5]);
  1349.                                 }
  1350.                                 else if (type == 5) { //Dragon head
  1351.                                         createHead(2, memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3], memblock[count+4], memblock[count+5]);
  1352.                                 }
  1353.                                 else if (type == 6) { //Goblin/medusa head
  1354.                                         createHead(1, memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3], memblock[count+4], memblock[count+5]);
  1355.                                 }
  1356.                                 else if (type == 7) { //Demon head
  1357.                                         createHead(3, memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3], memblock[count+4], memblock[count+5]);
  1358.                                 }
  1359.                                 else if (type == 10) { //Fireball head
  1360.                                         createHead(4, memblock[count+1] * 20, memblock[count+2] * 20, 1, memblock[count+3], memblock[count+4]);
  1361.                                 }
  1362.                         }
  1363.                        
  1364.                         else if (type <= 20)
  1365.                         {
  1366.                                 if (type == 11) { //Poison Gas
  1367.                                         createGas(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1368.                                 }
  1369.                                 else if (type == 12) { //Flying skull
  1370.                                         createSkull(memblock[count+1] * 20, memblock[count+2] * 20);
  1371.                                 }
  1372.                                 else if (type == 13) { //Fish
  1373.                                         createFish(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1374.                                 }
  1375.                                 else if (type == 14) { //Water Jumper
  1376.                                         createWaterJumper(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3], memblock[count+4], memblock[count+5]);
  1377.                                 }
  1378.                                 else if (type == 15) { //Podoboo
  1379.                                         createPodoboo(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3], memblock[count+4]);
  1380.                                 }
  1381.                                 else if (type == 16) { //Thwomp
  1382.                                         createThwomp(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3], memblock[count+4], memblock[count+5], memblock[count+6]);
  1383.                                 }
  1384.                                 else if (type == 17) { //Skeleton
  1385.                                         createSkeleton(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1386.                                 }
  1387.                                 else if (type == 18) { //Ghoul
  1388.                                         createGhoul(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1389.                                 }
  1390.                                 else if (type == 19) { //Seal
  1391.                                         createSeal(memblock[count+1]*20, memblock[count+2]*20);
  1392.                                 }
  1393.                                 else if (type == 20) { //Jellyfish
  1394.                                         createJellyfish(memblock[count+1]*20, memblock[count+2]*20);
  1395.                                 }
  1396.                         }
  1397.                        
  1398.                         else if (type <= 30)
  1399.                         {
  1400.                                 if (type == 21) { //Wizard
  1401.                                         createWizard(memblock[count+1]*20, memblock[count+2]*20);
  1402.                                 }
  1403.                                 else if (type == 22) { //Pendulum
  1404.                                         createPendulum(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1405.                                 }
  1406.                                 else if (type == 24) { //Bee
  1407.                                         createBee(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1408.                                 }
  1409.                                 else if (type == 25) { //Air Jar
  1410.                                         //createJar(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3], memblock[count+4]);
  1411.                                         createHead(5, memblock[count + 1] * 20, memblock[count + 2] * 20, 0, memblock[count+3], memblock[count+4]);
  1412.                                 }
  1413.                                 else if (type == 26) { //Boar
  1414.                                         createBoar(memblock[count+1]*20, memblock[count+2]*20);
  1415.                                 }
  1416.                                 else if (type == 27) { //Fire Wheel
  1417.                                         createFirewheel(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1418.                                 }
  1419.                                 else if (type == 28) { //Rock Golem
  1420.                                         createGolem(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1421.                                 }
  1422.                                 else if (type == 29) { //Poison Knight
  1423.                                         createPoisonknight(memblock[count+1]*20, memblock[count+2]*20);
  1424.                                 }
  1425.                                 else if (type == 30) { //Electricity doggy
  1426.                                         createDog(memblock[count+1]*20, memblock[count+2]*20);
  1427.                                 }
  1428.                         }
  1429.                        
  1430.                         else if (type < 40)
  1431.                         {
  1432.                                 if (type == 31) {
  1433.                                         createBoomknight(memblock[count+1]*20, memblock[count+2]*20);
  1434.                                 }
  1435.                                 else if (type == 32) {
  1436.                                         createPumpkinenemy(memblock[count+1]*20, memblock[count+2]*20);
  1437.                                 }
  1438.                         }
  1439.                        
  1440.                         else if (type < 50)
  1441.                         {
  1442.                                 //Bosses
  1443.                                 if (type == 40) {
  1444.                                         createDodo(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1445.                                 }
  1446.                                 else if (type == 41) {
  1447.                                         createBatboss(memblock[count+1] * 20, memblock[count+2] * 20);
  1448.                                 }
  1449.                                 else if (type == 42) {
  1450.                                         createCrab(memblock[count+1] * 20, memblock[count+2] * 20);
  1451.                                 }
  1452.                                 else if (type == 43) {
  1453.                                         createGyra(memblock[count+1] * 20, memblock[count+2] * 20);
  1454.                                 }
  1455.                                 else if (type == 44) {
  1456.                                         createLolidra(memblock[count+1] * 20, memblock[count+2] * 20);
  1457.                                 }
  1458.                                 else if (type == 45) {
  1459.                                         createDevil(memblock[count+1] * 20, memblock[count+2] * 20);
  1460.                                 }
  1461.                                 else if (type == 46) {
  1462.                                         createGarm(memblock[count+1] * 20, memblock[count+2] * 20);
  1463.                                 }
  1464.                                 else if (type == 47) {
  1465.                                         createHydra(memblock[count+1] * 20);
  1466.                                 }
  1467.                         }
  1468.                        
  1469.                         else if (type <= 60)
  1470.                         {
  1471.                                 //Objects
  1472.                                 if (type == 50) { //Moving platforms
  1473.                                         createPlatform(0, memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3] * 20, memblock[count + 4] * 20, memblock[count + 5], memblock[count+6]);
  1474.                                 }
  1475.                                 else if (type == 51) { //Loose block
  1476.                                         createPlatform(1, memblock[count + 1] * 20, memblock[count + 2] * 20, 0, 0, 0, memblock[count+3]);
  1477.                                 }
  1478.                                 else if (type == 52) { //Locked Block
  1479.                                         createLockBlock(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1480.                                 }
  1481.                                 else if (type == 53) { //Gate
  1482.                                         createGate(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1483.                                 }
  1484.                                 else if (type == 54) { //Statue
  1485.                                         createStatue(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1486.                                 }
  1487.                                 else if (type == 55) { //Megaman block
  1488.                                         createPlatform(2, memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3], memblock[count + 4], 0, 0);
  1489.                                 }
  1490.                                 else if (type == 56) { //Electric gate
  1491.                                         createShockgate(memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3]);
  1492.                                 }
  1493.                                 else if (type == 57) { //Hydra platform
  1494.                                         createPlatform(3, memblock[count + 1] * 20, memblock[count + 2] * 20, 0, 0, 0, 0);
  1495.                                 }
  1496.                         }
  1497.                        
  1498.                         else if (type < 70)
  1499.                         {
  1500.                                
  1501.                         }
  1502.                        
  1503.                         else/* if (type <= 80)*/
  1504.                         {
  1505.                                 if (type == 70) { //Breakable Block
  1506.                                         createDestroyable(memblock[count+1] * 20, memblock[count+2] * 20, 1);
  1507.                                 }
  1508.                                 else if (type == 71) { //Secret Trigger
  1509.                                         createSecretTrigger(memblock[count+1], memblock[count+2], memblock[count+3]);
  1510.                                 }
  1511.                                 else if (type == 73) { //Chests
  1512.                                         createChest(memblock[count + 1] * 20, memblock[count + 2] * 20, memblock[count + 3], memblock[count + 4]);
  1513.                                 }
  1514.                                 else if (type == 74) { //Save Points
  1515.                                         createSavePoint(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1516.                                 }
  1517.                                 else if (type == 75) { //door
  1518.                                         createDoor(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3], memblock[count+4], memblock[count+5] * 20, memblock[count+6] * 20, memblock[count+7]);
  1519.                                 }
  1520.                                 else if (type == 76) { //Light Switch
  1521.                                         createSwitch(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1522.                                 }
  1523.                                 else if (type == 77) { //Floor Button
  1524.                                         createFloorPad(memblock[count+1]*20, memblock[count+2]*20, memblock[count+3]);
  1525.                                 }
  1526.                                 else if (type == 78) {
  1527.                                         roomDarkness = 1;                              
  1528.                                 }
  1529.                                 else if (type == 79) { //Ladder Spawner
  1530.                                         createLadder(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1531.                                 }
  1532.                                 else if (type == 80) { //Generator
  1533.                                         createGenerator(memblock[count+1] * 20, memblock[count+2] * 20, memblock[count+3]);
  1534.                                 }
  1535.                                 else if (type == 81) { //Crown
  1536.                                         createCrown(memblock[count+1] * 20, memblock[count+2] * 20);
  1537.                                 }
  1538.                         }
  1539.                         count += 16;
  1540.                 }
  1541.                
  1542.                 free(memblock);
  1543.                 fclose(file);
  1544.         }
  1545.        
  1546. }
  1547.  
  1548. void drawHud()
  1549. {
  1550.         //Repress certain screen altering variables
  1551.         int tempDark = roomDarkness;
  1552.         roomDarkness = 0;
  1553.        
  1554.         int tempQuake = quakeTimer;
  1555.         quakeTimer = 0;
  1556.        
  1557.         //Change HUD position
  1558.         int drawy = 8;
  1559.         {
  1560.                 if (heroy <= 100) {
  1561.                         drawy = 400;
  1562.                 }
  1563.         }
  1564.        
  1565.         //Move scrolling health bar
  1566.         {
  1567.                 if (drawhp > herohp) {
  1568.                         drawhp -= 1;
  1569.                 }
  1570.                 if (drawhp < herohp) {
  1571.                         drawhp += 1;
  1572.                 }
  1573.         }
  1574.        
  1575.         //Main image
  1576.         {
  1577.                 PHL_DrawSurfacePart(8, drawy, 0, 0, 368, 64, images[imgHud]);
  1578.         }
  1579.        
  1580.         //Health bar
  1581.         {
  1582.                 PHL_RGB hpbarc = PHL_NewRGB(128, 255, 0);
  1583.                 if (getHeroPoisoned() > 0) {
  1584.                         hpbarc = PHL_NewRGB(255, 128, 255);
  1585.                 }      
  1586.                
  1587.                 PHL_DrawRect(76, drawy + 8, maxhp * 2, 6, PHL_NewRGB(255, 0, 0));
  1588.                 PHL_DrawRect(76, drawy + 8, drawhp * 2, 6, hpbarc);
  1589.         }
  1590.        
  1591.         //Ammo counter
  1592.         {
  1593.                 char c[10];
  1594.                 sprintf(c, "%02d", heroAmmo);
  1595.                 PHL_DrawTextBold(c, 74, drawy + 36, WHITE);
  1596.         }
  1597.        
  1598.         //Draw weapon icon
  1599.         {
  1600.                 int wx = 32 * (heroWeapon + 1);
  1601.                 if (hasWeapon[heroWeapon] == 0) {
  1602.                         wx = 0;
  1603.                 }
  1604.                 PHL_DrawSurfacePart(24, drawy + 16, wx, 64, 32, 32, images[imgHud]);
  1605.         }
  1606.        
  1607.         //Restore screen altering variables
  1608.         {
  1609.                 quakeTimer = tempQuake;
  1610.                 roomDarkness = tempDark;
  1611.         }
  1612. }
  1613.  
  1614. void freeArrays()
  1615. {
  1616.         int i;
  1617.         for (i = 0; i < MAX_EFFECTS; i++) {
  1618.                 effectDestroy(i);
  1619.         }
  1620.        
  1621.         for (i = 0; i < MAX_OBJECTS; i++) {
  1622.                 objectDestroy(i);
  1623.         }
  1624.        
  1625.         for (i = 0; i < MAX_ENEMIES; i++) {
  1626.                 enemyDestroy(i);
  1627.         }
  1628.        
  1629.         for (i = 0; i < MAX_WEAPONS; i++) {
  1630.                 weaponDestroy(i);
  1631.         }
  1632.        
  1633.         for (i = 0; i < MAX_PLATFORMS; i++) {
  1634.                 platformDestroy(i);
  1635.         }
  1636. }
  1637.  
  1638. void changeScreen(int dx, int dy)
  1639. {              
  1640.         roomSecret = 0;
  1641.        
  1642.         freeArrays();
  1643.  
  1644.         screenX += dx;
  1645.         screenY += dy;
  1646.         loadScreen();
  1647.        
  1648.         writeSave(savename);
  1649. }
  1650.  
  1651. int getTileType(int valx, int valy) {
  1652.         int result = 0;
  1653.  
  1654.         if (valy == 11 && valx == 8) {
  1655.                 result = 3; //Ladder Top
  1656.         }else
  1657.         if (valy == 1 && valx == 1) {
  1658.                 result = 5; //Lava
  1659.         }else
  1660.         if (valy > 7) {
  1661.                 result = 1; //Solid
  1662.         }else
  1663.         //specifics
  1664.         if (valy == 0 && (valx == 3 || valx == 5)) {
  1665.                 result = 2; //Ladders
  1666.         }else  
  1667.         if (valy == 1 && valx == 5) {
  1668.                 result = 4; //Water
  1669.         }else
  1670.         if (valx == 0 && (valy == 1 || valy == 2)) {
  1671.                 result = 6; //Spikes
  1672.         }else
  1673.         if (valy == 11 && (valx == 0 || valx == 1 || valx == 2)) {
  1674.                 result = 1; //Breakable solid block
  1675.         }
  1676.        
  1677.         if (level == 4 && valy == 3 && (valx == 0 || valx == 1 || valx == 2)) {
  1678.                 result = 6; //Spikes
  1679.         }
  1680.  
  1681.         return result;
  1682. }
  1683.  
  1684. //Save file load/save
  1685. int writeSave(char* fname)
  1686. {
  1687.         int result = 0;
  1688.         //mkdir("data");
  1689.         FILE* f;
  1690.        
  1691.         char fullPath[4096];
  1692.         strcpy(fullPath, "");
  1693.         #ifdef _3DS
  1694.                 strcat(fullPath, "sdmc:/3ds/appdata/HydraCastleLabyrinth/");
  1695.         #elif _KOLIBRI
  1696.                 strcat(fullPath, KOS_HCL_SAVES_PATH);
  1697.         #endif
  1698.         strcat(fullPath, fname);
  1699.  
  1700.         if ( (f = fopen(fullPath, "wb")) ) {
  1701.                 int size = 4548;
  1702.                 unsigned char* memblock = (unsigned char*)malloc(size);
  1703.                 memset(memblock, 0, size);
  1704.                 #if defined(__amigaos4__) || defined(__MORPHOS__)
  1705.                 #define D 3
  1706.                 #else
  1707.                 #define D 0
  1708.                 #endif
  1709.                 memblock[0x0+D] = herohp;
  1710.                 memblock[0x4+D] = maxhp;
  1711.                 memblock[0x8+D] = heroAmmo;
  1712.                 memblock[0x0C+D] = maxAmmo;
  1713.                
  1714.                 if (heroWeapon == -1) {
  1715.                         memblock[0x10] = 0;
  1716.                 }else{
  1717.                         memblock[0x10] = heroWeapon;
  1718.                 }
  1719.                 memblock[0x14] = 1; //Unknown, but always resets to 1
  1720.                
  1721.                 int i;
  1722.                 for (i = 0; i < 60; i++) {
  1723.                         memblock[(0x3FC) + i] = flags[i];
  1724.                 }
  1725.                
  1726.                 for (i = 0; i < 5; i++) {
  1727.                         memblock[(0x7E4) + i] = hasWeapon[i];
  1728.                 }
  1729.                
  1730.                 int itemorder[28] = { 0x7F6, 0x7FA, 0x7F9, 0x7F8, 0x7F1, 0x7F3, 0x7F2,
  1731.                                                         0x7FB, 0x7ED, 0x7EF, 0x7EE, 0x7F0, 0x7EC, 0x7F4,
  1732.                                                         0x7F7, 0x7F5, 0x7EA, 0x7EB, 0x7FF, 0x803, 0x804,
  1733.                                                         0x7FE, 0x802, 0x805, 0x800, 0x7FD, 0x7FC, 0x801 };
  1734.                                                        
  1735.                 for (i = 0; i < 28; i++) {
  1736.                         memblock[itemorder[i]] = hasItem[i];
  1737.                 }
  1738.                
  1739.                 for (i = 0; i < 8; i++) {
  1740.                         memblock[(0x806) + i] = hasKey[i];
  1741.                 }
  1742.                
  1743.                 int writeHerox = herox;
  1744.                 int writeHeroy = heroy;
  1745.                 memcpy(&memblock[0x11B0], &writeHerox, 4);     
  1746.                 memcpy(&memblock[0x11B4], &writeHeroy, 4);
  1747.                
  1748.                 if (getHeroDirection() == 1) {
  1749.                         memblock[0x11C0+D] = 0;
  1750.                 }else{
  1751.                         memblock[0x11C0+D] = 1;
  1752.                 }
  1753.                
  1754.                 memblock[0x11B8+D] = level;
  1755.                
  1756.                 //Screen
  1757.                 memblock[0x11BC+D] = (screenX) + (screenY * 12);
  1758.                
  1759.                 //Time
  1760.                 memcpy(&memblock[0x11AC], &playTime, 4);
  1761.                
  1762.                 fwrite(memblock, 1, size, f);
  1763.                
  1764.                 free(memblock);
  1765.                
  1766.                 result = 1;
  1767.                 fclose(f);
  1768.         }
  1769.         #ifdef EMSCRIPTEN
  1770.         EM_ASM(
  1771.                 //persist changes
  1772.                 FS.syncfs(false,function (err) {
  1773.                                                 assert(!err);
  1774.                 });
  1775.         );
  1776.         #endif
  1777.  
  1778.         return result;
  1779. }
  1780.  
  1781. void loadSave(char* fname)
  1782. {
  1783.         FILE* f;
  1784.        
  1785.         char fullPath[128];
  1786.         strcpy(fullPath, "");
  1787.         #ifdef _3DS
  1788.                 strcat(fullPath, "sdmc:/3ds/appdata/HydraCastleLabyrinth/");
  1789.         #endif
  1790.         strcat(fullPath, fname);
  1791.        
  1792.         if ((f = fopen(fullPath, "rb"))) {
  1793.                 //Reminder: read order matters
  1794.                 unsigned long loadTemp = 0;
  1795.                 int tmp;
  1796.                 //Hero HP
  1797.                 tmp = fread(&loadTemp, 4, 1, f);
  1798.                 herohp = loadTemp;
  1799.                 drawhp = herohp;
  1800.                
  1801.                 //Max HP
  1802.                 tmp = fread(&loadTemp, 4, 1, f);
  1803.                 maxhp = loadTemp;
  1804.                
  1805.                 //Ammo
  1806.                 tmp = fread(&loadTemp, 4, 1, f);
  1807.                 heroAmmo = loadTemp;
  1808.                
  1809.                 //Max Ammo
  1810.                 tmp = fread(&loadTemp, 4, 1, f);
  1811.                 maxAmmo = loadTemp;
  1812.                
  1813.                 int loadedWeapon = 0;
  1814.                 tmp = fread(&loadedWeapon, 1, 1, f);
  1815.                                
  1816.                 //Read Flags
  1817.                 fseek(f, 0x3FC, SEEK_SET);
  1818.                 int i;
  1819.                 for (i = 0; i < 60; i++) {
  1820.                         tmp = fread(&flags[i], 1, 1, f);
  1821.                 }
  1822.                
  1823.                 //Read weapons
  1824.                 fseek(f, 0x7E4, SEEK_SET);
  1825.                 for (i = 0; i < 5; i++) {
  1826.                         tmp = fread(&hasWeapon[i], 1, 1, f);
  1827.                 }
  1828.                
  1829.                 heroWeapon = -1;
  1830.                 if (hasWeapon[loadedWeapon] == 1) {
  1831.                         heroWeapon = loadedWeapon;
  1832.                 }
  1833.                
  1834.                 //Read items
  1835.                 int itemorder[28] = { 16, 17, 12,  8, 10,  9, 11,
  1836.                                                            4,  6,  5, 13, 15,  0, 14,
  1837.                                                            3,  2,  1,  7, 26, 25, 21,
  1838.                                                           18, 24, 27, 22, 19, 20, 23 };
  1839.                 fseek(f, 0x7EA, SEEK_SET);
  1840.                 for (i = 0; i < 28; i++) {
  1841.                         tmp = fread(&hasItem[itemorder[i]], 1, 1, f);
  1842.                 }
  1843.                
  1844.                 //Read keys
  1845.                 for (i = 0; i < 8; i++) {
  1846.                         tmp = fread(&hasKey[i], 1, 1, f);
  1847.                 }
  1848.                
  1849.                 fseek(f, 0x11AC, SEEK_SET);
  1850.                 tmp = fread(&playTime, 4, 1, f);
  1851.                
  1852.                 //fseek(f, 4540, SEEK_SET);
  1853.                 //Hero X and Y
  1854.                 tmp = fread(&loadTemp, 4, 1, f);
  1855.                 herox = loadTemp;              
  1856.                 tmp = fread(&loadTemp, 4, 1, f);
  1857.                 heroy = loadTemp;
  1858.                
  1859.                 //Level
  1860.                 tmp = fread(&loadTemp, 4, 1, f);
  1861.                 level = loadTemp;
  1862.                
  1863.                 //Screen coords
  1864.                 tmp = fread(&loadTemp, 4, 1, f);
  1865.                 screenX = (loadTemp) % 12;
  1866.                 screenY = ((int)(loadTemp) / 12);
  1867.                
  1868.                 //Direction
  1869.                 tmp = fread(&loadTemp, 4, 1, f);               
  1870.                 if (loadTemp == 0) {
  1871.                         setHeroDirection(1);
  1872.                 }else{
  1873.                         setHeroDirection(-1);
  1874.                 }              
  1875.                 fclose(f);
  1876.                 #undef D
  1877.         }
  1878.        
  1879. }
  1880.  
  1881. int fileExists(char* fpath)
  1882. {
  1883.         int result = 0;
  1884.        
  1885.         char fullPath[128];
  1886.         strcpy(fullPath, "");
  1887.         #ifdef _3DS
  1888.                 strcat(fullPath, "sdmc:/3ds/appdata/HydraCastleLabyrinth/");
  1889.         #endif
  1890.         strcat(fullPath, fpath);
  1891.        
  1892.         FILE* f;
  1893.         if ( (f = fopen(fullPath, "rb")) ) {
  1894.                 result = 1;
  1895.                 fclose(f);
  1896.         }
  1897.        
  1898.         return result;
  1899. }
  1900.  
  1901. void playSecret()
  1902. {
  1903.         PHL_StopMusic();       
  1904.         secretTimer = 210;
  1905. }
  1906.  
  1907. void secretCountdown()
  1908. {
  1909.         if (secretTimer > 0) {
  1910.                 secretTimer -= 1;
  1911.                 if (secretTimer <= 0) {
  1912.                         PHL_StopMusic();
  1913.                         if (bossFlag == 0 && bossDefeatedFlag == 0) {
  1914.                                 PHL_PlayMusic(bgmMusic);
  1915.                         }
  1916.                 }else if (secretTimer == 180) {
  1917.                         PHL_PlayMusic(bgmSecret);
  1918.                 }
  1919.         }
  1920. }
  1921.  
  1922. int getDrawHP()
  1923. {
  1924.         return drawhp;
  1925. }
  1926.  
  1927. void setDrawHP(int val)
  1928. {
  1929.         drawhp = val;
  1930. }
  1931.  
  1932. int getLevel()
  1933. {
  1934.         return level;
  1935. }
  1936.  
  1937. void setBossRoom()
  1938. {      
  1939.         bossFlag = 1;
  1940.         PHL_StopMusic();
  1941.         secretTimer = 0;
  1942.        
  1943.         PHL_FreeMusic(bgmMusic);
  1944.         if (level != 8) {
  1945.                 bgmMusic = PHL_LoadMusic("midi/boss", 1);
  1946.         }else{
  1947.                 bgmMusic = PHL_LoadMusic("midi/lastboss", 1);
  1948.         }
  1949.         PHL_PlayMusic(bgmMusic);
  1950. }
  1951.  
  1952. void setAutoSave(char val)
  1953. {
  1954.         autoSave = val;
  1955. }
  1956.  
  1957. char getAutoSave()
  1958. {
  1959.         return autoSave;
  1960. }
  1961.  
  1962. void loadUncommonImages()
  1963. {
  1964.         //Seal Toungs
  1965.         if (level == 4) {
  1966.                 images[imgMisc2040] = PHL_LoadQDA("chr20x40.BMP");
  1967.         }
  1968.         //Darkness
  1969.         if (level == 5) {
  1970.                 images[imgDark] = PHL_LoadQDA("dark.bmp");
  1971.         }
  1972.         //Dragon Flame
  1973.         if (level == 7 || level == 8) {
  1974.                 images[imgMisc6020] = PHL_LoadQDA("chr60x20.bmp");
  1975.         }
  1976. }
  1977.