├── .github └── FUNDING.yml ├── source ├── stagedata.h ├── titlescreen.h ├── options.h ├── inventory.h ├── ini.h ├── vita │ ├── system.h │ ├── input.h │ ├── system.c │ ├── audio.h │ ├── graphics.h │ ├── input.c │ ├── decoder_wav.h │ ├── decoder_fmmidi.h │ ├── midisequencer.h │ ├── decoder_fmmidi.cpp │ ├── decoder_wav.cpp │ └── utils.h ├── 3ds │ ├── system.h │ ├── input.h │ ├── system.c │ ├── audio.h │ ├── input.c │ └── graphics.h ├── wii │ ├── system.h │ ├── input.h │ ├── audio.h │ ├── system.c │ ├── graphics.h │ ├── audio.c │ └── input.c ├── enemies │ ├── slug.h │ ├── seal.h │ ├── golem.h │ ├── skull.h │ ├── boar.h │ ├── dog.h │ ├── jellyfish.h │ ├── bee.h │ ├── bat.h │ ├── gas.h │ ├── firewheel.h │ ├── batboss.h │ ├── gyra.h │ ├── slime.h │ ├── pendulum.h │ ├── wizard.h │ ├── thwomp.h │ ├── ghoul.h │ ├── podoboo.h │ ├── dodo.h │ ├── fish.h │ ├── knight.h │ ├── waterjumper.h │ ├── poisonknight.h │ ├── boomknight.h │ ├── pumpkin.h │ ├── devil.h │ ├── crab.h │ ├── skeleton.h │ ├── garm.h │ ├── lolidra.h │ ├── hydra.h │ ├── heads.h │ ├── pendulum.c │ ├── gas.c │ ├── fish.c │ ├── wizard.c │ ├── slug.c │ ├── bat.c │ ├── podoboo.c │ ├── skull.c │ ├── golem.c │ ├── jellyfish.c │ ├── bee.c │ ├── seal.c │ ├── boar.c │ ├── slime.c │ ├── ghoul.c │ ├── knight.c │ ├── thwomp.c │ ├── boomknight.c │ ├── dog.c │ └── firewheel.c ├── enemy.h ├── psp │ ├── system.h │ ├── input.h │ ├── audio.h │ ├── system.c │ ├── graphics.h │ ├── audio.c │ ├── input.c │ └── graphics.c ├── qda.h ├── enemy.c ├── platform.h ├── weapon.h ├── collision.h ├── effect.h ├── text.h ├── PHL.h ├── hero.h ├── qda.c ├── PHL.c ├── main.c ├── object.h ├── inventory.c ├── titlescreen.c ├── stagedata.c ├── text.c ├── game.h └── platform.c ├── .gitattributes ├── .gitignore ├── Makefile ├── Makefile.psp └── Makefile.wii /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: Rinnegatamante 2 | -------------------------------------------------------------------------------- /source/stagedata.h: -------------------------------------------------------------------------------- 1 | #ifndef STAGEDATA_H 2 | #define STAGEDATA_H 3 | 4 | int stage[9][96]; 5 | 6 | #endif -------------------------------------------------------------------------------- /source/titlescreen.h: -------------------------------------------------------------------------------- 1 | #ifndef TITLESCREEN_H 2 | #define TITLESCREEN_H 3 | 4 | int titleScreen(); 5 | 6 | #endif -------------------------------------------------------------------------------- /source/options.h: -------------------------------------------------------------------------------- 1 | #ifndef OPTIONS_H 2 | #define OPTIONS_H 3 | 4 | int options(); 5 | 6 | int optionsStep(); 7 | void optionsDraw(); 8 | 9 | #endif -------------------------------------------------------------------------------- /source/inventory.h: -------------------------------------------------------------------------------- 1 | #ifndef INVENTORY_H 2 | #define INVENTORY_H 3 | 4 | void inventory(); 5 | 6 | int inventoryStep(); 7 | void inventoryDraw(); 8 | 9 | #endif -------------------------------------------------------------------------------- /source/ini.h: -------------------------------------------------------------------------------- 1 | #ifndef INI_H 2 | #define INI_H 3 | 4 | //Functions to handle the "system.ini" file 5 | void iniInit(); 6 | 7 | void saveSettings(); 8 | void loadSettings(); 9 | 10 | #endif -------------------------------------------------------------------------------- /source/vita/system.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSTEM_H 2 | #define SYSTEM_H 3 | 4 | int PHL_MainLoop(); 5 | void PHL_ConsoleInit(); 6 | void PHL_GameQuit(); 7 | 8 | void PHL_ErrorScreen(char* message); 9 | 10 | #endif -------------------------------------------------------------------------------- /source/3ds/system.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSTEM_H 2 | #define SYSTEM_H 3 | 4 | //int quitGame; 5 | 6 | int PHL_MainLoop(); 7 | void PHL_ConsoleInit(); 8 | void PHL_GameQuit(); 9 | 10 | void PHL_ErrorScreen(char* message); 11 | 12 | #endif -------------------------------------------------------------------------------- /source/wii/system.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSTEM_H 2 | #define SYSTEM_H 3 | 4 | int quitGame; 5 | 6 | int PHL_MainLoop(); 7 | void PHL_ConsoleInit(); 8 | void PHL_GameQuit(); 9 | 10 | void PHL_ErrorScreen(char* message); 11 | 12 | #endif -------------------------------------------------------------------------------- /source/enemies/slug.h: -------------------------------------------------------------------------------- 1 | #ifndef SLUG_H 2 | #define SLUG_H 3 | 4 | typedef struct { 5 | int id; 6 | int dir; 7 | double x, y, vsp; 8 | double imageIndex; 9 | } Slug; 10 | 11 | void createSlug(int x, int y, int dir); 12 | 13 | #endif -------------------------------------------------------------------------------- /source/enemy.h: -------------------------------------------------------------------------------- 1 | #ifndef ENEMY_H 2 | #define ENEMY_H 3 | 4 | typedef struct { 5 | void* data; //Specific enemy struct 6 | void (*enemyStep)(); 7 | void (*enemyDraw)(); 8 | int type; 9 | } Enemy; 10 | 11 | void enemyDestroy(int id); 12 | 13 | #endif -------------------------------------------------------------------------------- /source/enemies/seal.h: -------------------------------------------------------------------------------- 1 | #ifndef SEAL_H 2 | #define SEAL_H 3 | 4 | typedef struct { 5 | int id, hp; 6 | double x, y; 7 | double imageIndex; 8 | int dir, state, timer; 9 | int invincible; 10 | } Seal; 11 | 12 | void createSeal(int x, int y); 13 | 14 | #endif -------------------------------------------------------------------------------- /source/enemies/golem.h: -------------------------------------------------------------------------------- 1 | #ifndef GOLEM_H 2 | #define GOLEM_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | double imageIndex; 8 | int hp; 9 | int dir; 10 | int state; 11 | int blink; 12 | } Golem; 13 | 14 | void createGolem(int x, int y, int dir); 15 | 16 | #endif -------------------------------------------------------------------------------- /source/enemies/skull.h: -------------------------------------------------------------------------------- 1 | #ifndef SKULL_H 2 | #define SKULL_H 3 | 4 | typedef struct { 5 | int id, state, timer; 6 | double x, y; 7 | double yoffset; 8 | int rot; 9 | double dir; 10 | double imageIndex; 11 | } Skull; 12 | 13 | void createSkull(int x, int y); 14 | 15 | #endif -------------------------------------------------------------------------------- /source/enemies/boar.h: -------------------------------------------------------------------------------- 1 | #ifndef BOAR_H 2 | #define BOAR_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp; 7 | double x, y; 8 | double hsp; 9 | double imageIndex; 10 | int blink; 11 | int dir; 12 | int state; 13 | int timer; 14 | } Boar; 15 | 16 | void createBoar(int x, int y); 17 | 18 | #endif -------------------------------------------------------------------------------- /source/enemies/dog.h: -------------------------------------------------------------------------------- 1 | #ifndef DOG_H 2 | #define DOG_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp; 7 | int blink; 8 | double x, y; 9 | double vsp, hsp; 10 | double imageIndex; 11 | int dir; 12 | int state, timer, counter; 13 | } Dog; 14 | 15 | void createDog(int x, int y); 16 | 17 | #endif -------------------------------------------------------------------------------- /source/enemies/jellyfish.h: -------------------------------------------------------------------------------- 1 | #ifndef JELLYFISH_H 2 | #define JELLYFISH_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | int ystart; 8 | double spd; 9 | double angle; 10 | int state; 11 | double imageIndex; 12 | } Jellyfish; 13 | 14 | void createJellyfish(int x, int y); 15 | 16 | #endif -------------------------------------------------------------------------------- /source/enemies/bee.h: -------------------------------------------------------------------------------- 1 | #ifndef BEE_H 2 | #define BEE_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | int xstart, ystart; 8 | double hsp, vsp; 9 | double imageIndex; 10 | int dir, state, timer; 11 | double hoverdir; 12 | } Bee; 13 | 14 | void createBee(int x, int y, int dir); 15 | 16 | #endif -------------------------------------------------------------------------------- /source/psp/system.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSTEM_H 2 | #define SYSTEM_H 3 | 4 | #include 5 | #include 6 | #include "../PHL.h" 7 | 8 | char quitGame; 9 | 10 | int PHL_MainLoop(); 11 | void PHL_ConsoleInit(); 12 | void PHL_GameQuit(); 13 | 14 | void PHL_ErrorScreen(char* message); 15 | 16 | #endif -------------------------------------------------------------------------------- /source/qda.h: -------------------------------------------------------------------------------- 1 | #ifndef QDA_H 2 | #define QDA_H 3 | 4 | typedef struct { 5 | unsigned long offset; 6 | unsigned long size; 7 | unsigned long bytes; 8 | unsigned char* fileName[256]; 9 | } QDAHeader; 10 | 11 | QDAHeader headers[29]; //names, offsets, and sizes of each sheet 12 | int initQDA(); 13 | 14 | #endif -------------------------------------------------------------------------------- /source/enemies/bat.h: -------------------------------------------------------------------------------- 1 | #ifndef BAT_H 2 | #define BAT_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | int xstart, ystart; 8 | int type; //0 = gray | 1 = red 9 | int dir; 10 | double imageIndex; 11 | int counter, timer, state; 12 | } Bat; 13 | 14 | void createBat(int x, int y, int type); 15 | 16 | #endif -------------------------------------------------------------------------------- /source/enemies/gas.h: -------------------------------------------------------------------------------- 1 | #ifndef GAS_H 2 | #define GAS_H 3 | 4 | //#include "../enemy.h" 5 | //#include "../collision.h" 6 | 7 | typedef struct { 8 | int id; 9 | int x, y; 10 | int state, timer; 11 | double imageIndex; 12 | 13 | //Mask mask; 14 | } Gas; 15 | 16 | void createGas(int x, int y, int temp); 17 | 18 | #endif -------------------------------------------------------------------------------- /source/enemies/firewheel.h: -------------------------------------------------------------------------------- 1 | #ifndef FIREWHEEL_H 2 | #define FIREWHEEL_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | double imageIndex; 8 | int hp; 9 | int blink; 10 | int dir; 11 | int hsp, vsp; 12 | int wallx, wally; 13 | int timer; 14 | } Firewheel; 15 | 16 | void createFirewheel(int x, int y, int dir); 17 | 18 | #endif -------------------------------------------------------------------------------- /source/enemy.c: -------------------------------------------------------------------------------- 1 | #include "enemy.h" 2 | #include "game.h" 3 | #include 4 | 5 | void enemyDestroy(int id) 6 | { 7 | if (enemies[id] != NULL) { 8 | if (enemies[id]->data != NULL) { 9 | free(enemies[id]->data); 10 | } 11 | enemies[id]->data = NULL; 12 | 13 | free(enemies[id]); 14 | } 15 | enemies[id] = NULL; 16 | } 17 | -------------------------------------------------------------------------------- /source/enemies/batboss.h: -------------------------------------------------------------------------------- 1 | #ifndef BATBOSS_H 2 | #define BATBOSS_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | double hsp, vsp, grav; 8 | double imageIndex; 9 | double ypos; 10 | double rot; 11 | int hp; 12 | int state, timer, mode; 13 | int invincible; 14 | } Batboss; 15 | 16 | void createBatboss(int x, int y); 17 | 18 | #endif -------------------------------------------------------------------------------- /source/enemies/gyra.h: -------------------------------------------------------------------------------- 1 | #ifndef GYRA_H 2 | #define GYRA_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp; 7 | double x, y; 8 | double xrecord[144]; 9 | double yrecord[144]; 10 | int state, timer, counter; 11 | int targx, targy; 12 | int invincible; 13 | double dir; 14 | double imageIndex; 15 | } Gyra; 16 | 17 | void createGyra(int x, int y); 18 | 19 | #endif -------------------------------------------------------------------------------- /source/enemies/slime.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIME_H 2 | #define SLIME_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | int type; //0 = blue | 1 = red | 2 = yellow 8 | int offset; 9 | double vsp, hsp, grav; 10 | double imageIndex; 11 | int counter, timer, state; 12 | int hp; 13 | } Slime; 14 | 15 | void createSlime(int x, int y, int type, int offset); 16 | 17 | #endif -------------------------------------------------------------------------------- /source/enemies/pendulum.h: -------------------------------------------------------------------------------- 1 | #ifndef PENDULUM_H 2 | #define PENDULUM_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | double x, y; 9 | double rotCounter, angle; 10 | 11 | Mask mask; 12 | } Pendulum; 13 | 14 | void createPendulum(int x, int y, int side); 15 | 16 | void pendulumStep(Pendulum* p); 17 | void pendulumDraw(Pendulum* p); 18 | 19 | #endif -------------------------------------------------------------------------------- /source/enemies/wizard.h: -------------------------------------------------------------------------------- 1 | #ifndef WIZARD_H 2 | #define WIZARD_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | double x, y; 9 | double imageIndex; 10 | int state, timer, visible; 11 | 12 | Mask mask; 13 | } Wizard; 14 | 15 | void createWizard(int x, int y); 16 | 17 | void wizardStep(Wizard* w); 18 | void wizardDraw(Wizard* w); 19 | 20 | #endif -------------------------------------------------------------------------------- /source/enemies/thwomp.h: -------------------------------------------------------------------------------- 1 | #ifndef THWOMP_H 2 | #define THWOMP_H 3 | 4 | //#include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | double x, y; 9 | double vsp, grav; 10 | double imageIndex; 11 | int type, state, timer, dir; 12 | int hp, blink; 13 | int delay; 14 | } Thwomp; 15 | 16 | void createThwomp(int x, int y, int type, int offset, int delay, int dir); 17 | 18 | #endif -------------------------------------------------------------------------------- /source/enemies/ghoul.h: -------------------------------------------------------------------------------- 1 | #ifndef GHOUL_H 2 | #define GHOUL_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | int hp; 9 | double x, y; 10 | double vsp, grav; 11 | int type; 12 | int onground; 13 | int dir; 14 | int state, timer, invincible; 15 | double imageIndex; 16 | 17 | Mask mask; 18 | } Ghoul; 19 | 20 | void createGhoul(int x, int y, int type); 21 | 22 | #endif -------------------------------------------------------------------------------- /source/enemies/podoboo.h: -------------------------------------------------------------------------------- 1 | #ifndef PODOBOO_H 2 | #define PODOBOO_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | int ystart; 8 | int hp; 9 | int blink; 10 | int rot; 11 | double yoffset; 12 | double vsp, grav; 13 | double jumpheight; 14 | double imageIndex; 15 | int timer, state; 16 | } Podoboo; 17 | 18 | void createPodoboo(int x, int y, int offset, int height); 19 | 20 | #endif -------------------------------------------------------------------------------- /source/enemies/dodo.h: -------------------------------------------------------------------------------- 1 | #ifndef DODO_H 2 | #define DODO_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | double x, y; 9 | double vsp, hsp, grav; 10 | int dir, onground; 11 | double imageIndex; 12 | int state, timer, hp; 13 | int blink; 14 | int tojump, jumptoggle; 15 | int flag; 16 | 17 | //Mask mask; 18 | } Dodo; 19 | 20 | void createDodo(int x, int y, int flag); 21 | 22 | #endif -------------------------------------------------------------------------------- /source/wii/input.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUT_H 2 | #define INPUT_H 3 | 4 | typedef struct { 5 | int pressed, 6 | held, 7 | released; 8 | } Button; 9 | 10 | Button btnUp, btnDown, btnLeft, btnRight; 11 | Button btnFaceUp, btnFaceDown, btnFaceLeft, btnFaceRight; 12 | Button btnL, btnR; 13 | Button btnStart, btnSelect; 14 | Button btnAccept, btnDecline; 15 | 16 | int axisX, axisY; 17 | 18 | void PHL_ScanInput(); 19 | 20 | #endif -------------------------------------------------------------------------------- /source/enemies/fish.h: -------------------------------------------------------------------------------- 1 | #ifndef FISH_H 2 | #define FISH_H 3 | 4 | #include "../enemy.h" 5 | #include "../collision.h" 6 | 7 | typedef struct { 8 | int id; 9 | 10 | double x, y; 11 | int xstart; 12 | double imageIndex; 13 | double spd; 14 | int dir, turning; 15 | 16 | Mask mask; 17 | } Fish; 18 | 19 | void createFish(int x, int y, int dir); 20 | 21 | void fishStep(Fish* f); 22 | void fishDraw(Fish* f); 23 | 24 | #endif -------------------------------------------------------------------------------- /source/psp/input.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUT_H 2 | #define INPUT_H 3 | 4 | #include 5 | 6 | typedef struct { 7 | int pressed, 8 | held, 9 | released; 10 | } Button; 11 | 12 | Button btnUp, btnDown, btnLeft, btnRight; 13 | Button btnFaceUp, btnFaceDown, btnFaceLeft, btnFaceRight; 14 | Button btnL, btnR; 15 | Button btnStart, btnSelect; 16 | Button btnAccept, btnDecline; 17 | int axisX, axisY; 18 | 19 | void PHL_ScanInput(); 20 | 21 | #endif -------------------------------------------------------------------------------- /source/enemies/knight.h: -------------------------------------------------------------------------------- 1 | #ifndef KNIGHT_H 2 | #define KNIGHT_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id, type; 8 | double x, y, 9 | vsp, grav; 10 | int dir, state, timer; 11 | double imageIndex; 12 | int hp, invincible; 13 | int shieldhit; 14 | 15 | Mask mask; 16 | } Knight; 17 | 18 | void createKnight(int x, int y, int type); 19 | 20 | void knightStep(Knight* k); 21 | void knightDraw(Knight* k); 22 | 23 | #endif -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /source/3ds/input.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUT_H 2 | #define INPUT_H 3 | 4 | #include <3ds.h> 5 | 6 | typedef struct { 7 | int pressed, 8 | held, 9 | released; 10 | } Button; 11 | 12 | Button btnUp, btnDown, btnLeft, btnRight; 13 | Button btnFaceUp, btnFaceDown, btnFaceLeft, btnFaceRight; 14 | 15 | Button btnL, btnR; 16 | Button btnStart, btnSelect; 17 | 18 | Button btnAccept; 19 | Button btnDecline; 20 | 21 | int axisX, axisY; 22 | 23 | void PHL_ScanInput(); 24 | 25 | #endif -------------------------------------------------------------------------------- /source/enemies/waterjumper.h: -------------------------------------------------------------------------------- 1 | #ifndef WATERJUMPER_H 2 | #define WATERJUMPER_H 3 | 4 | #include "../enemy.h" 5 | 6 | typedef struct { 7 | int id, type; 8 | 9 | double x, y; 10 | int hp; 11 | int blink; 12 | int ystart, rot; 13 | double yoffset; 14 | double hsp, vsp, grav; 15 | 16 | double imageIndex; 17 | int state, timer; 18 | int height; 19 | } WaterJumper; 20 | 21 | void createWaterJumper(int x, int y, int type, int offset, int height); 22 | 23 | #endif -------------------------------------------------------------------------------- /source/enemies/poisonknight.h: -------------------------------------------------------------------------------- 1 | #ifndef POISONKNIGHT_H 2 | #define POISONKNIGHT_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp; 7 | double x, y; 8 | double imageIndex; 9 | int dir; 10 | int blink; 11 | int timer; 12 | int state; 13 | } Poisonknight; 14 | 15 | void createPoisonknight(int x, int y); 16 | 17 | typedef struct { 18 | int id; 19 | double x, y; 20 | int dir; 21 | double imageIndex; 22 | } Goop; 23 | 24 | void createGoop(int x, int y, int dir); 25 | 26 | #endif -------------------------------------------------------------------------------- /source/enemies/boomknight.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOMKNIGHT_H 2 | #define BOOMKNIGHT_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp; 7 | int blink; 8 | double x, y; 9 | int dir; 10 | double imageIndex; 11 | int state, timer; 12 | } Boomknight; 13 | 14 | void createBoomknight(int x, int y); 15 | 16 | typedef struct { 17 | int id; 18 | int dir; 19 | double x, y; 20 | double hsp; 21 | double imageIndex; 22 | int timer; 23 | } Boom; 24 | 25 | void createBoom(int x, int y, int dir); 26 | 27 | #endif -------------------------------------------------------------------------------- /source/vita/input.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUT_H 2 | #define INPUT_H 3 | 4 | #include 5 | 6 | typedef struct { 7 | int pressed, 8 | held, 9 | released; 10 | } Button; 11 | 12 | Button btnUp, btnDown, btnLeft, btnRight; 13 | Button btnFaceUp, btnFaceDown, btnFaceLeft, btnFaceRight; 14 | 15 | Button btnL, btnR; 16 | Button btnStart, btnSelect; 17 | 18 | Button btnSwap; 19 | 20 | Button btnAccept; 21 | Button btnDecline; 22 | 23 | int axisX, axisY; 24 | 25 | void PHL_ScanInput(); 26 | 27 | #endif -------------------------------------------------------------------------------- /source/enemies/pumpkin.h: -------------------------------------------------------------------------------- 1 | #ifndef PUMPKIN_H 2 | #define PUMPKIN_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp; 7 | int blink; 8 | double x, y; 9 | int dir; 10 | double imageIndex; 11 | int state, timer; 12 | } Pumpkinenemy; 13 | 14 | void createPumpkinenemy(int x, int y); 15 | 16 | typedef struct { 17 | int id; 18 | int dir; 19 | double x, y; 20 | double vsp; 21 | double imageIndex; 22 | int state, timer; 23 | } Pumpkinhead; 24 | 25 | void createPumpkinhead(int x, int y, int dir); 26 | 27 | #endif -------------------------------------------------------------------------------- /source/enemies/devil.h: -------------------------------------------------------------------------------- 1 | #ifndef DEVIL_H 2 | #define DEVIL_H 3 | 4 | typedef struct { 5 | int id; 6 | double x, y; 7 | double ystart, newystart; 8 | double hsp; 9 | int hp; 10 | int state, timer; 11 | int blink; 12 | int boblen, bobspd; 13 | double tailangle, bobcounter, rotcounter, rotspd; 14 | double imageIndex; 15 | } Devil; 16 | 17 | void createDevil(int x, int y); 18 | 19 | typedef struct { 20 | int id; 21 | double x, y; 22 | double dir; 23 | double imageIndex; 24 | } Orb; 25 | 26 | void createOrb(int x, int y, double dir); 27 | 28 | #endif -------------------------------------------------------------------------------- /source/enemies/crab.h: -------------------------------------------------------------------------------- 1 | #ifndef CRAB_H 2 | #define CRAB_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | int hp, invincible; 9 | double x, y; 10 | double hsp, vsp; 11 | double imageIndex; 12 | int state, timer, counter; 13 | 14 | Mask mask; 15 | } Crab; 16 | 17 | void createCrab(int x, int y); 18 | 19 | typedef struct { 20 | int id; 21 | double x, y; 22 | double angle; 23 | double imageIndex; 24 | 25 | Mask mask; 26 | } Electricity; 27 | 28 | void createElectricity(int x, int y, double angle, int minid); 29 | 30 | #endif -------------------------------------------------------------------------------- /source/enemies/skeleton.h: -------------------------------------------------------------------------------- 1 | #ifndef SKELETON_H 2 | #define SKELETON_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | double x, y; 9 | double hsp; 10 | double imageIndex; 11 | int dir; 12 | int hp; 13 | int state, timer, invincible; 14 | 15 | Mask mask; 16 | } Skeleton; 17 | 18 | void createSkeleton(int x, int y, int dir); 19 | 20 | typedef struct { 21 | int id; 22 | double x, y; 23 | double hsp, vsp, grav; 24 | double imageIndex; 25 | 26 | Mask mask; 27 | } Bone; 28 | 29 | void createBone(int x, int y, int dir); 30 | 31 | #endif -------------------------------------------------------------------------------- /source/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_H 2 | #define PLATFORM_H 3 | 4 | #include "collision.h" 5 | 6 | typedef struct { 7 | int id, type; //0 = moving platform 8 | double x, y; 9 | int xstart, ystart; 10 | int xend, yend; 11 | int state; 12 | double spd; 13 | int timer; 14 | int secret, visible; 15 | 16 | Mask mask; 17 | } Platform; 18 | 19 | void createPlatform(int type, int xstart, int ystart, int xend, int yend, int spd, int secret); 20 | 21 | void platformStep(Platform* p); 22 | void platformDraw(Platform* p); 23 | 24 | void platformDestroy(int id); 25 | 26 | #endif -------------------------------------------------------------------------------- /source/enemies/garm.h: -------------------------------------------------------------------------------- 1 | #ifndef GARM_H 2 | #define GARM_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp; 7 | double x, y; 8 | double hsp, vsp; 9 | int dir; 10 | double imageIndex; 11 | int state, timer, blink, counter; 12 | int wallcounter, substate; 13 | int targx; 14 | } Garm; 15 | 16 | void createGarm(int x, int y); 17 | 18 | typedef struct { 19 | int id; 20 | int hp; 21 | double x, y; 22 | double vsp, hsp; 23 | double imageIndex; 24 | int counter; 25 | int blink; 26 | int inwall; 27 | } Garmrock; 28 | 29 | void createGarmrock(int x, int y, double hsp, double vsp); 30 | 31 | #endif -------------------------------------------------------------------------------- /source/weapon.h: -------------------------------------------------------------------------------- 1 | #ifndef WEAPON_H 2 | #define WEAPON_H 3 | 4 | #include "collision.h" 5 | 6 | #define ARROW 0 7 | #define AXE 1 8 | #define BOOMERANG 2 9 | #define FIREBALL 3 10 | #define BOMB 4 11 | #define SWORD 5 12 | 13 | typedef struct { 14 | int id, type; 15 | 16 | double x, y; 17 | double vsp, hsp; 18 | double grav; 19 | double imageIndex; 20 | int dir; 21 | 22 | int power, timer, state, cooldown, hitflag; 23 | 24 | Mask weaponMask; 25 | } Weapon; 26 | 27 | void addWeapon(int type, int x, int y); 28 | void weaponStep(Weapon* w); 29 | void weaponDraw(Weapon* w); 30 | 31 | void weaponHit(Weapon* w); 32 | void weaponDestroy(int id); 33 | 34 | #endif -------------------------------------------------------------------------------- /source/psp/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef PSPAUDIO_H 2 | #define PSPAUDIO_H 3 | 4 | #include 5 | 6 | #define PHL_Music OSL_SOUND 7 | #define PHL_Sound OSL_SOUND 8 | 9 | void PHL_AudioInit(); 10 | void PHL_AudioClose(); 11 | 12 | OSL_SOUND* PHL_LoadMusic(char* fname, int loop); //Same as PHL_LoadSound, but expects a file name without extension 13 | OSL_SOUND* PHL_LoadSound(char* fname); 14 | 15 | void PHL_PlayMusic(OSL_SOUND* snd); 16 | void PHL_PlaySound(OSL_SOUND* snd, int channel); 17 | 18 | void PHL_StopMusic(); 19 | void PHL_StopSound(OSL_SOUND* snd, int channel); 20 | 21 | #define PHL_FreeMusic PHL_FreeSound 22 | void PHL_FreeSound(OSL_SOUND* snd); 23 | 24 | #endif -------------------------------------------------------------------------------- /source/collision.h: -------------------------------------------------------------------------------- 1 | #ifndef COLLISION_H 2 | #define COLLISION_H 3 | 4 | #include "PHL.h" 5 | 6 | typedef struct { 7 | int circle; //1 if circle, 0 is rectangle 8 | int x, y; 9 | int w, h; //width is the radius if it's a circle 10 | int unused; 11 | } Mask; 12 | 13 | void PHL_DrawMask(Mask m); 14 | 15 | int checkCollision(Mask m1, Mask m2); 16 | 17 | int checkTileCollision(int type, Mask m); 18 | PHL_Rect getTileCollision(int type, Mask m); 19 | 20 | int checkCollisionXY(Mask m, int x, int y); 21 | 22 | int checkTileCollisionXY(int type, int x, int y); 23 | PHL_Rect getTileCollisionXY(int type, int x, int y); 24 | 25 | PHL_Rect getTileCollisionWeapon(int type, Mask m); 26 | 27 | #endif -------------------------------------------------------------------------------- /source/effect.h: -------------------------------------------------------------------------------- 1 | #ifndef EFFECTS_H 2 | #define EFFECTS_H 3 | 4 | typedef struct { 5 | int id, type; 6 | double x, y, 7 | vsp, hsp, grav, 8 | imageIndex, imageSpeed; 9 | 10 | int cropx, cropy; 11 | int width, height; 12 | int image, timer; 13 | 14 | int visible; 15 | int val1; 16 | int loop, frames; 17 | int depth; 18 | } Effect; 19 | 20 | void createEffect(int type, int x, int y); 21 | void createEffectExtra(int t, int x, int y, double hsp, double vsp, int val); 22 | 23 | void effectStep(Effect* e); 24 | void effectDraw(Effect* e); 25 | void effectDestroy(int id); 26 | 27 | void createRockSmash(int x, int y); 28 | void createSplash(int x, int y); 29 | void createLavaSplash(int x, int y); 30 | 31 | #endif -------------------------------------------------------------------------------- /source/text.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_HEADER 2 | #define TEXT_HEADER 3 | 4 | #define JAPANESE 0 5 | #define ENGLISH 1 6 | #define SPANISH 2 7 | 8 | char gameLanguage; 9 | 10 | typedef struct { 11 | unsigned char x[32]; 12 | unsigned char y[32]; 13 | char length; 14 | } Message; 15 | 16 | Message* saving; 17 | Message* saveError[3]; 18 | Message* itemName[41]; 19 | Message* found; 20 | Message* itemDescription[28]; 21 | Message* dungeon[8]; 22 | 23 | void textInit(); 24 | void textFree(); 25 | 26 | void loadText(); 27 | 28 | int drawText(Message* m, int x, int y); 29 | int drawCharacter(int cx, int cy, int x, int y); 30 | void drawTextCentered(Message* m, int x, int y); 31 | 32 | void setLanguage(char lan); 33 | char getLanguage(); 34 | 35 | #endif -------------------------------------------------------------------------------- /source/enemies/lolidra.h: -------------------------------------------------------------------------------- 1 | #ifndef LOLIDRA_H 2 | #define LOLIDRA_H 3 | 4 | #include "../collision.h" 5 | 6 | typedef struct { 7 | int id; 8 | double x, y; 9 | double positionY; 10 | double imageIndex, hoverRot; 11 | int hp, state, invincible, 12 | visible, timer, counter; 13 | 14 | Mask mask; 15 | } Lolidra; 16 | 17 | void createLolidra(int x, int y); 18 | 19 | void lolidraStep(Lolidra* l); 20 | void lolidraDraw(Lolidra* l); 21 | 22 | //Minion 23 | typedef struct { 24 | int id; 25 | int state; 26 | int timer; 27 | double x, y; 28 | double positionY; 29 | double imageIndex; 30 | double dir, spd; 31 | 32 | Mask mask; 33 | } Minion; 34 | 35 | void createMinion(int x, int y); 36 | 37 | void minionStep(Minion* m); 38 | void minionDraw(Minion* m); 39 | 40 | #endif -------------------------------------------------------------------------------- /source/wii/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef WIIAUDIO_H 2 | #define WIIAUDIO_H 3 | 4 | #include 5 | 6 | typedef struct { 7 | Mix_Music* data; 8 | 9 | int loop; 10 | int used; 11 | } PHL_Music; 12 | 13 | typedef struct { 14 | Mix_Chunk* data; 15 | 16 | int loop; 17 | int used; 18 | } PHL_Sound; 19 | 20 | void PHL_AudioInit(); 21 | void PHL_AudioClose(); 22 | 23 | PHL_Music PHL_LoadMusic(char* fname, int loop); //Same as PHL_LoadSound, but expects a file name without extension 24 | PHL_Sound PHL_LoadSound(char* fname); 25 | 26 | void PHL_PlayMusic(PHL_Music snd); 27 | void PHL_PlaySound(PHL_Sound snd, int channel); 28 | 29 | void PHL_StopMusic(); 30 | void PHL_StopSound(PHL_Sound snd, int channel); 31 | 32 | void PHL_FreeMusic(PHL_Music snd); 33 | void PHL_FreeSound(PHL_Sound snd); 34 | 35 | #endif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /source/3ds/system.c: -------------------------------------------------------------------------------- 1 | #include "system.h" 2 | #include <3ds.h> 3 | #include "../PHL.h" 4 | #include 5 | #include 6 | 7 | int quitGame = 0; 8 | 9 | int PHL_MainLoop() 10 | { 11 | if (quitGame == 1) { 12 | return 0; 13 | } 14 | 15 | return aptMainLoop(); 16 | } 17 | 18 | void PHL_ConsoleInit() 19 | { 20 | consoleInit(activeScreen->screen, NULL); 21 | } 22 | 23 | void PHL_GameQuit() 24 | { 25 | quitGame = 1; 26 | } 27 | 28 | void PHL_ErrorScreen(char* message) 29 | { 30 | consoleInit(GFX_TOP, NULL); 31 | 32 | printf(message); 33 | printf("\n\nPress START to close"); 34 | 35 | u32 kDown; 36 | while (PHL_MainLoop()) { 37 | //gfxFlushBuffers(); 38 | //gfxSwapBuffers(); 39 | hidScanInput(); 40 | kDown = hidKeysHeld(); 41 | 42 | if (kDown & KEY_START) { break; } 43 | 44 | gspWaitForVBlank(); 45 | } 46 | 47 | exit(1); 48 | } -------------------------------------------------------------------------------- /source/wii/system.c: -------------------------------------------------------------------------------- 1 | #include "system.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int quitGame = 0; 7 | 8 | int PHL_MainLoop() 9 | { 10 | if (quitGame == 1) { 11 | return 0; 12 | } 13 | return 1; 14 | } 15 | 16 | void PHL_ConsoleInit() 17 | { 18 | //console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ); 19 | } 20 | 21 | void PHL_GameQuit() 22 | { 23 | quitGame = 1; 24 | } 25 | 26 | void PHL_ErrorScreen(char* message) 27 | { 28 | /*consoleInit(GFX_TOP, NULL); 29 | 30 | printf(message); 31 | printf("\n\nPress START to close"); 32 | 33 | u32 kDown; 34 | while (PHL_MainLoop()) { 35 | //gfxFlushBuffers(); 36 | //gfxSwapBuffers(); 37 | hidScanInput(); 38 | kDown = hidKeysHeld(); 39 | 40 | if (kDown & KEY_START) { break; } 41 | 42 | gspWaitForVBlank(); 43 | } 44 | */ 45 | 46 | exit(1); 47 | } -------------------------------------------------------------------------------- /source/psp/system.c: -------------------------------------------------------------------------------- 1 | #include "system.h" 2 | #include "../text.h" 3 | 4 | PSP_MODULE_INFO("Hydra Castle Labrynth", 0, 1, 1); 5 | PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU); 6 | //PSP_HEAP_SIZE_KB(12*1024); 7 | PSP_HEAP_SIZE_KB(-1024); 8 | 9 | int PHL_MainLoop() 10 | { 11 | if (quitGame == 1) { 12 | return 0; 13 | } 14 | return 1; 15 | } 16 | 17 | void PHL_ConsoleInit() 18 | { 19 | pspDebugScreenInit(); 20 | } 21 | 22 | void PHL_GameQuit() 23 | { 24 | quitGame = 1; 25 | } 26 | 27 | void PHL_ErrorScreen(char* message) 28 | { 29 | /*consoleInit(GFX_TOP, NULL); 30 | 31 | printf(message); 32 | printf("\n\nPress START to close"); 33 | 34 | u32 kDown; 35 | while (PHL_MainLoop()) { 36 | //gfxFlushBuffers(); 37 | //gfxSwapBuffers(); 38 | hidScanInput(); 39 | kDown = hidKeysHeld(); 40 | 41 | if (kDown & KEY_START) { break; } 42 | 43 | gspWaitForVBlank(); 44 | } 45 | */ 46 | 47 | exit(1); 48 | } -------------------------------------------------------------------------------- /source/PHL.h: -------------------------------------------------------------------------------- 1 | /* 2 | PHL stands for Portable Homebrew Library 3 | */ 4 | #ifndef PHL_H 5 | #define PHL_H 6 | 7 | #ifdef _3DS 8 | #include "3ds/system.h" 9 | #include "3ds/graphics.h" 10 | #include "3ds/input.h" 11 | #include "3ds/audio.h" 12 | #endif 13 | 14 | #ifdef _WII 15 | #include "wii/system.h" 16 | #include "wii/graphics.h" 17 | #include "wii/input.h" 18 | #include "wii/audio.h" 19 | #endif 20 | 21 | #ifdef _PSP 22 | #include "psp/system.h" 23 | #include "psp/graphics.h" 24 | #include "psp/input.h" 25 | #include "psp/audio.h" 26 | #endif 27 | 28 | #ifdef _PSP2 29 | #include "vita/system.h" 30 | #include "vita/graphics.h" 31 | #include "vita/input.h" 32 | #include "vita/audio.h" 33 | #endif 34 | 35 | typedef struct { 36 | int x, y, w, h; 37 | } PHL_Rect; 38 | 39 | void PHL_Init(); 40 | void PHL_Deinit(); 41 | 42 | int WHITE, 43 | RED, 44 | YELLOW; 45 | 46 | PHL_Surface PHL_LoadQDA(char* fname); 47 | void PHL_DrawTextBold(char* txt, int dx, int dy, int col); 48 | void PHL_DrawTextBoldCentered(char* txt, int dx, int dy, int col); 49 | 50 | #endif -------------------------------------------------------------------------------- /source/hero.h: -------------------------------------------------------------------------------- 1 | #ifndef HERO_H 2 | #define HERO_H 3 | 4 | #include "PHL.h" 5 | #include "collision.h" 6 | 7 | double herox, heroy; 8 | double herohp, maxhp; 9 | int heroAmmo, maxAmmo; 10 | int heroWeapon; 11 | 12 | Mask heroMask; 13 | Mask shieldMask; 14 | 15 | void heroSetup(); 16 | void heroCleanup(); 17 | int heroStep(); 18 | void heroDraw(); 19 | 20 | int heroHit(int damage, int centerx); 21 | 22 | void heroPoison(); 23 | void heroStone(); 24 | 25 | Mask getHeroMask(); 26 | 27 | int getHeroState(); 28 | void setHeroState(int s); 29 | 30 | int getHeroInvincible(); 31 | 32 | int getHeroDirection(); 33 | void setHeroDirection(int d); 34 | 35 | double getHeroImageIndex(); 36 | void setHeroImageIndex(double index); 37 | 38 | double getHeroVsp(); 39 | double getHeroHsp(); 40 | 41 | void setHeroHsp(double newHsp); 42 | void setHeroVsp(double newVsp); 43 | 44 | int getHeroOnground(); 45 | void setHeroOnground(int val); 46 | 47 | void setHeroTimer(int t); 48 | 49 | int getHeroPoisoned(); 50 | 51 | void heroStun(); 52 | 53 | void setHeroCanjump(int set); 54 | 55 | #endif -------------------------------------------------------------------------------- /source/vita/system.c: -------------------------------------------------------------------------------- 1 | #include "system.h" 2 | #include 3 | #include "../PHL.h" 4 | #include 5 | #include 6 | 7 | vita2d_pgf* debug_font; 8 | uint32_t white; 9 | int quitGame = 0; 10 | 11 | int PHL_MainLoop(){ 12 | if (quitGame == 1) return 0; 13 | return 1; 14 | } 15 | 16 | void PHL_ConsoleInit(){ 17 | debug_font = vita2d_load_default_pgf(); 18 | white = RGBA8(0xFF, 0xFF, 0xFF, 0xFF); 19 | } 20 | 21 | void PHL_GameQuit(){ 22 | quitGame = 1; 23 | } 24 | 25 | void PHL_ErrorScreen(char* message){ 26 | SceCtrlData pad; 27 | int oldpad = 0; 28 | 29 | while (PHL_MainLoop()) { 30 | 31 | sceCtrlPeekBufferPositive(0, &pad, 1); 32 | if (pad.buttons & SCE_CTRL_START) break; 33 | 34 | vita2d_start_drawing(); 35 | vita2d_pgf_draw_text(debug_font, 2, 50, white, 1.0, message); 36 | vita2d_pgf_draw_text(debug_font, 2, 80, white, 1.0, "Press START to close"); 37 | vita2d_end_drawing(); 38 | vita2d_wait_rendering_done(); 39 | vita2d_swap_buffers(); 40 | 41 | oldpad = pad.buttons; 42 | } 43 | 44 | sceKernelExitDeleteThread(0); 45 | } -------------------------------------------------------------------------------- /source/vita/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIO_H 2 | #define AUDIO_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // Music block struct 10 | typedef struct DecodedMusic 11 | { 12 | uint8_t* audiobuf; 13 | uint8_t* audiobuf2; 14 | uint8_t* cur_audiobuf; 15 | FILE* handle; 16 | volatile int isPlaying; 17 | int loop; 18 | volatile int pauseTrigger; 19 | volatile int closeTrigger; 20 | volatile int audioThread; 21 | char filepath[256]; 22 | int tempBlock; 23 | int used; 24 | } DecodedMusic; 25 | 26 | typedef DecodedMusic PHL_Sound; 27 | typedef DecodedMusic PHL_Music; 28 | 29 | void PHL_AudioInit(); 30 | void PHL_AudioClose(); 31 | 32 | PHL_Music PHL_LoadMusic(char* fname, int loop); //Same as PHL_LoadSound, but expects a file name without extension 33 | PHL_Sound PHL_LoadSound(char* fname); 34 | 35 | void PHL_PlayMusic(PHL_Music snd); 36 | void PHL_PlaySound(PHL_Sound snd, int channel); 37 | 38 | void PHL_StopMusic(); 39 | void PHL_StopSound(PHL_Sound snd, int channel); 40 | 41 | void PHL_FreeMusic(PHL_Music snd); 42 | void PHL_FreeSound(PHL_Sound snd); 43 | 44 | #endif -------------------------------------------------------------------------------- /source/enemies/hydra.h: -------------------------------------------------------------------------------- 1 | #ifndef HYDRA_H 2 | #define HYDRA_H 3 | 4 | typedef struct { 5 | int id; 6 | int hp, blink; 7 | double x, y; 8 | double hsp, vsp; 9 | double imageIndex; 10 | int state, timer; 11 | int patternCounter; 12 | char onground; 13 | char noheads; 14 | int headid[4]; 15 | } Hydra; 16 | 17 | void createHydra(int x); 18 | 19 | typedef struct { 20 | int id; 21 | int hp, blink; 22 | int dir; 23 | int position; //0 = lower 1 = higher 24 | double imageIndex; 25 | double neckRot; 26 | int state, timer, counter; 27 | int bodyid; 28 | double bodyposX[7]; 29 | double bodyposY[7]; 30 | } Hydrahead; 31 | 32 | int createHydrahead(int dir, int position, int bodyid); 33 | 34 | typedef struct { 35 | int id; 36 | double x, y; 37 | double hsp, vsp; 38 | char inwall; 39 | char bounce; 40 | double imageIndex; 41 | } Hydragoop; 42 | 43 | void createHydragoop(int x, int y, int hsp, int vsp); 44 | 45 | typedef struct { 46 | int id; 47 | double x, y; 48 | double vsp; 49 | char bounce; 50 | double imageIndex; 51 | } Hydrarock; 52 | 53 | void createHydrarock(); 54 | 55 | typedef struct { 56 | int id; 57 | int timer; 58 | double x, y; 59 | double angle; 60 | double imageIndex; 61 | } Hydrashock; 62 | 63 | void createHydrashock(int x, int y); 64 | 65 | #endif -------------------------------------------------------------------------------- /source/3ds/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIO_H 2 | #define AUDIO_H 3 | 4 | #include <3ds.h> 5 | 6 | typedef struct { 7 | u16 sampleRate; 8 | u32 dataSize; 9 | u16 bitsPerSample; 10 | u16 ndspFormat; 11 | u16 numChannels; 12 | u8 loop; 13 | u8* data; 14 | //int used; 15 | } PHL_Music; 16 | 17 | typedef struct{ 18 | u32 sampleRate; 19 | u32 dataSize; 20 | u16 bitsPerSample; 21 | u16 ndspFormat; 22 | u16 numChannels; 23 | u8* data; 24 | } PHL_Sound; 25 | 26 | ndspWaveBuf waveBuf[6]; //One for each channel? 27 | 28 | void PHL_AudioInit(); 29 | void PHL_AudioClose(); 30 | 31 | PHL_Music PHL_LoadMusic(char* fname, int loop); //Same as PHL_LoadSound, but expects a file name without extension 32 | PHL_Sound PHL_LoadSound(char* fname); 33 | 34 | void PHL_PlayMusic(PHL_Music snd); 35 | void PHL_PlaySound(PHL_Sound snd, int channel); 36 | 37 | void PHL_StopMusic(); 38 | void PHL_StopSound(PHL_Sound snd, int channel); 39 | 40 | /* 41 | PHL_Music PHL_LoadMusic(char* fname, int channel); //Same as PHL_LoadSound, but expects a file name without extension 42 | PHL_Sound PHL_LoadSound(char* fname, int loop, int stream, int channel); 43 | 44 | void PHL_PlayMusic(PHL_Music snd); 45 | void PHL_PlaySound(PHL_Sound snd); 46 | */ 47 | 48 | void PHL_FreeMusic(PHL_Music snd); 49 | void PHL_FreeSound(PHL_Sound snd); 50 | 51 | #endif -------------------------------------------------------------------------------- /source/3ds/input.c: -------------------------------------------------------------------------------- 1 | #include "input.h" 2 | 3 | void updateKey(Button* btn, int state); 4 | 5 | void PHL_ScanInput() 6 | { 7 | hidScanInput(); 8 | u32 kDown = hidKeysHeld(); 9 | 10 | updateKey(&btnUp, kDown & KEY_UP); 11 | updateKey(&btnDown, kDown & KEY_DOWN); 12 | updateKey(&btnLeft, kDown & KEY_LEFT); 13 | updateKey(&btnRight, kDown & KEY_RIGHT); 14 | 15 | updateKey(&btnStart, kDown & KEY_START); 16 | updateKey(&btnSelect, kDown & KEY_SELECT); 17 | 18 | updateKey(&btnFaceRight, kDown & KEY_A); 19 | updateKey(&btnFaceDown, kDown & KEY_B); 20 | updateKey(&btnFaceLeft, kDown & KEY_Y); 21 | 22 | updateKey(&btnL, kDown & KEY_L); 23 | updateKey(&btnR, kDown & KEY_R); 24 | 25 | updateKey(&btnAccept, kDown & KEY_A); 26 | updateKey(&btnDecline, kDown & KEY_B); 27 | /* 28 | //Start button 29 | if (kDown & KEY_START) { 30 | btnStart.pressed = 1; 31 | }else{ 32 | btnStart.pressed = 0; 33 | } 34 | */ 35 | } 36 | 37 | void updateKey(Button* btn, int state) 38 | { 39 | if (state) { 40 | if (btn->held == 1) { 41 | btn->pressed = 0; 42 | }else{ 43 | btn->pressed = 1; 44 | } 45 | btn->held = 1; 46 | btn->released = 0; 47 | }else{ 48 | if (btn->held == 1) { 49 | btn->released = 1; 50 | }else{ 51 | btn->released = 0; 52 | } 53 | btn->held = 0; 54 | btn->pressed = 0; 55 | } 56 | } -------------------------------------------------------------------------------- /source/vita/graphics.h: -------------------------------------------------------------------------------- 1 | //VITA graphics.h 2 | #ifndef GRAPHICS_H 3 | #define GRAPHICS_H 4 | 5 | #include 6 | #include 7 | 8 | #define PHL_Surface vita2d_texture* 9 | 10 | #define PHL_RGB uint32_t 11 | 12 | typedef struct { 13 | int tileX[16][12]; 14 | int tileY[16][12]; 15 | } PHL_Background; 16 | 17 | void PHL_GraphicsInit(); 18 | void PHL_GraphicsExit(); 19 | 20 | void PHL_StartDrawing(); 21 | void PHL_EndDrawing(); 22 | 23 | void PHL_ForceScreenUpdate(); 24 | 25 | void PHL_SetDrawbuffer(vita2d_texture* surf); 26 | void PHL_ResetDrawbuffer(); 27 | 28 | uint32_t PHL_NewRGB(uint8_t r, uint8_t g, uint8_t b); 29 | void PHL_SetColorKey(vita2d_texture* surf, uint8_t r, uint8_t g, uint8_t b); 30 | 31 | vita2d_texture* PHL_NewSurface(uint16_t w, uint16_t h); 32 | void PHL_FreeSurface(vita2d_texture* surf); 33 | 34 | vita2d_texture* PHL_LoadBMP(int index); 35 | 36 | void PHL_DrawRect(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t col); 37 | 38 | void PHL_DrawSurface(int16_t x, int16_t y, vita2d_texture* surf); 39 | void PHL_DrawSurfacePart(int16_t x, int16_t y, int16_t cropx, int16_t cropy, int16_t cropw, int16_t croph, vita2d_texture*); 40 | 41 | void PHL_DrawBackground(PHL_Background back, PHL_Background fore); 42 | void PHL_UpdateBackground(PHL_Background back, PHL_Background fore); 43 | 44 | void PHL_SwapBorder(); 45 | 46 | #endif -------------------------------------------------------------------------------- /source/wii/graphics.h: -------------------------------------------------------------------------------- 1 | //Wii graphics.h 2 | #ifndef GRAPHICS_H 3 | #define GRAPHICS_H 4 | 5 | //#include 6 | #include 7 | 8 | typedef struct { 9 | int tileX[16][12]; 10 | int tileY[16][12]; 11 | } PHL_Background; 12 | 13 | typedef struct { 14 | unsigned int r; 15 | unsigned int g; 16 | unsigned int b; 17 | } PHL_RGB; 18 | 19 | typedef struct { 20 | SDL_Surface* fb; 21 | int width; 22 | int height; 23 | } DrawBuffer; 24 | 25 | typedef struct { 26 | SDL_Surface* surf; 27 | } PHL_Surface; 28 | 29 | PHL_Surface backBuffer; 30 | SDL_Surface *surfScreen; 31 | DrawBuffer db; 32 | 33 | void PHL_GraphicsInit(); 34 | void PHL_GraphicsExit(); 35 | 36 | void PHL_StartDrawing(); 37 | void PHL_EndDrawing(); 38 | 39 | void PHL_ForceScreenUpdate(); 40 | 41 | void PHL_SetDrawbuffer(PHL_Surface surf); 42 | void PHL_ResetDrawbuffer(); 43 | 44 | PHL_RGB PHL_NewRGB(int r, int g, int b); 45 | void PHL_SetColorKey(PHL_Surface surf, int r, int g, int b); 46 | 47 | PHL_Surface PHL_NewSurface(int w, int h); 48 | void PHL_FreeSurface(PHL_Surface surface); 49 | 50 | //PHL_Surface PHL_LoadBMP(char* fname); 51 | PHL_Surface PHL_LoadBMP(int index); 52 | 53 | void PHL_DrawRect(int x, int y, int w, int h, PHL_RGB col); 54 | 55 | void PHL_DrawSurface(double x, double y, PHL_Surface surface); 56 | void PHL_DrawSurfacePart(double x, double y, int cropx, int cropy, int cropw, int croph, PHL_Surface surface); 57 | 58 | void PHL_DrawBackground(PHL_Background back, PHL_Background fore); 59 | void PHL_UpdateBackground(PHL_Background back, PHL_Background fore); 60 | 61 | #endif -------------------------------------------------------------------------------- /source/3ds/graphics.h: -------------------------------------------------------------------------------- 1 | //3DS graphics.h 2 | #ifndef GRAPHICS_H 3 | #define GRAPHICS_H 4 | 5 | #include <3ds.h> 6 | 7 | typedef struct { 8 | u8 r; 9 | u8 g; 10 | u8 b; 11 | } PHL_RGB; 12 | 13 | typedef struct { 14 | u8* pxdata; 15 | u16 width; 16 | u16 height; 17 | PHL_RGB colorKey; 18 | } PHL_Surface; 19 | 20 | typedef struct { 21 | gfxScreen_t screen; 22 | gfx3dSide_t side; 23 | u16 width; 24 | u16 height; 25 | } Screen; 26 | 27 | typedef struct { 28 | int tileX[16][12]; 29 | int tileY[16][12]; 30 | } PHL_Background; 31 | 32 | PHL_Surface db; 33 | Screen* activeScreen; 34 | 35 | PHL_Surface backBuffer; 36 | 37 | void PHL_GraphicsInit(); 38 | void PHL_GraphicsExit(); 39 | 40 | void PHL_StartDrawing(); 41 | void PHL_EndDrawing(); 42 | 43 | void PHL_ForceScreenUpdate(); 44 | 45 | void PHL_SetDrawbuffer(PHL_Surface surf); 46 | void PHL_ResetDrawbuffer(); 47 | 48 | PHL_RGB PHL_NewRGB(u8 r, u8 g, u8 b); 49 | void PHL_SetColorKey(PHL_Surface surf, u8 r, u8 g, u8 b); 50 | 51 | PHL_Surface PHL_NewSurface(u16 w, u16 h); 52 | void PHL_FreeSurface(PHL_Surface surf); 53 | 54 | PHL_Surface PHL_LoadBMP_Debug(int index); 55 | PHL_Surface PHL_LoadBMP(int index); 56 | 57 | void PHL_DrawRect(s16 x, s16 y, u16 w, u16 h, PHL_RGB col); 58 | 59 | void PHL_DrawSurface(s16 x, s16 y, PHL_Surface surf); 60 | void PHL_DrawSurfacePart(s16 x, s16 y, s16 cropx, s16 cropy, s16 cropw, s16 croph, PHL_Surface surf); 61 | 62 | void PHL_DrawBackground(PHL_Background back, PHL_Background fore); 63 | void PHL_UpdateBackground(PHL_Background back, PHL_Background fore); 64 | 65 | void swapScreen(gfxScreen_t screen, gfx3dSide_t side); 66 | 67 | #endif -------------------------------------------------------------------------------- /source/vita/input.c: -------------------------------------------------------------------------------- 1 | #include "input.h" 2 | 3 | void updateKey(Button* btn, int state); 4 | 5 | int enterButton = 0; 6 | 7 | void PHL_ScanInput() 8 | { 9 | SceCtrlData pad; 10 | sceCtrlPeekBufferPositive(0, &pad, 1); 11 | uint32_t kDown = pad.buttons; 12 | 13 | updateKey(&btnUp, (kDown & SCE_CTRL_UP) || (pad.ly < 70)); 14 | updateKey(&btnDown, kDown & SCE_CTRL_DOWN || (pad.ly > 170)); 15 | updateKey(&btnLeft, kDown & SCE_CTRL_LEFT || (pad.lx < 70)); 16 | updateKey(&btnRight, kDown & SCE_CTRL_RIGHT || (pad.lx > 170)); 17 | 18 | updateKey(&btnStart, kDown & SCE_CTRL_START); 19 | updateKey(&btnSelect, kDown & SCE_CTRL_SELECT); 20 | 21 | updateKey(&btnFaceRight, kDown & SCE_CTRL_CIRCLE); 22 | updateKey(&btnFaceDown, kDown & SCE_CTRL_CROSS); 23 | updateKey(&btnFaceLeft, kDown & SCE_CTRL_SQUARE); 24 | 25 | updateKey(&btnL, kDown & SCE_CTRL_LTRIGGER); 26 | updateKey(&btnR, kDown & SCE_CTRL_RTRIGGER); 27 | 28 | if (enterButton == 0){ 29 | updateKey(&btnAccept, kDown & SCE_CTRL_CIRCLE); 30 | updateKey(&btnDecline, kDown & SCE_CTRL_CROSS); 31 | }else{ 32 | updateKey(&btnAccept, kDown & SCE_CTRL_CROSS); 33 | updateKey(&btnDecline, kDown & SCE_CTRL_CIRCLE); 34 | } 35 | 36 | updateKey(&btnSwap, kDown & SCE_CTRL_TRIANGLE); 37 | 38 | } 39 | 40 | void updateKey(Button* btn, int state) 41 | { 42 | if (state) { 43 | if (btn->held == 1) { 44 | btn->pressed = 0; 45 | }else{ 46 | btn->pressed = 1; 47 | } 48 | btn->held = 1; 49 | btn->released = 0; 50 | }else{ 51 | if (btn->held == 1) { 52 | btn->released = 1; 53 | }else{ 54 | btn->released = 0; 55 | } 56 | btn->held = 0; 57 | btn->pressed = 0; 58 | } 59 | } -------------------------------------------------------------------------------- /source/psp/graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHICS_H 2 | #define GRAPHICS_H 3 | 4 | #include 5 | #include 6 | 7 | #define PHL_Surface OSL_IMAGE 8 | 9 | #define PHL_RGB OSL_COLOR 10 | #define PHL_NewRGB RGB 11 | 12 | typedef struct { 13 | int tileX[16][12]; 14 | int tileY[16][12]; 15 | } PHL_Background; 16 | 17 | /* 18 | typedef struct { 19 | unsigned int r, g, b; 20 | } PHL_RGB; 21 | */ 22 | /* 23 | typedef struct { 24 | OSL_IMAGE* pxdata; 25 | int width; 26 | int height; 27 | PHL_RGB colorKey; 28 | } PHL_Surface; 29 | */ 30 | OSL_IMAGE* screen; 31 | 32 | void PHL_GraphicsInit(); 33 | void PHL_GraphicsExit(); 34 | 35 | void PHL_StartDrawing(); 36 | void PHL_EndDrawing(); 37 | 38 | void PHL_ForceScreenUpdate(); 39 | 40 | void PHL_SetDrawbuffer(OSL_IMAGE* surf); 41 | void PHL_ResetDrawbuffer(); 42 | 43 | //PHL_RGB PHL_NewRGB(int r, int g, int b); 44 | void PHL_SetColorKey(OSL_IMAGE* surf, int r, int g, int b); 45 | 46 | OSL_IMAGE* PHL_NewSurface(int w, int h); 47 | void PHL_FreeSurface(OSL_IMAGE* surf); 48 | 49 | //PHL_Surface PHL_LoadBMP(char* fname); 50 | OSL_IMAGE* PHL_LoadBMP(int index); 51 | 52 | void PHL_DrawRect(int x, int y, int w, int h, OSL_COLOR col); 53 | 54 | void PHL_DrawSurface(double x, double y, OSL_IMAGE* surface); 55 | void PHL_DrawSurfacePart(double x, double y, int cropx, int cropy, int cropw, int croph, OSL_IMAGE* surface); 56 | 57 | void PHL_DrawBackground(PHL_Background back, PHL_Background fore); 58 | void PHL_UpdateBackground(PHL_Background back, PHL_Background fore); 59 | 60 | void setBlur(int blur); 61 | void setScreenSize(int size); 62 | 63 | int getBlur(); 64 | int getScreenSize(); 65 | 66 | #endif -------------------------------------------------------------------------------- /source/psp/audio.c: -------------------------------------------------------------------------------- 1 | #include "audio.h" 2 | #include "../game.h" 3 | 4 | void PHL_AudioInit() 5 | { 6 | oslInitAudio(); 7 | } 8 | 9 | void PHL_AudioClose() 10 | { 11 | oslDeinitAudio(); 12 | } 13 | 14 | //Each system can use a custom music file format 15 | OSL_SOUND* PHL_LoadMusic(char* fname, int loop) 16 | { 17 | char stream = 0; 18 | 19 | OSL_SOUND* result = NULL; 20 | 21 | char fullPath[40]; 22 | strcpy(fullPath, fname); 23 | strcat(fullPath, ".bgm"); 24 | 25 | FILE* file; 26 | 27 | if ( (file = fopen(fullPath, "r")) ) { 28 | fclose(file); 29 | result = oslLoadSoundFile(fullPath, stream); 30 | oslSetSoundLoop(result, loop); 31 | } 32 | 33 | return result; 34 | } 35 | 36 | OSL_SOUND* PHL_LoadSound(char* fname) 37 | { 38 | char stream = 0; 39 | 40 | OSL_SOUND* result = NULL; 41 | 42 | char fullPath[40]; 43 | strcpy(fullPath, fname); 44 | 45 | FILE* file; 46 | 47 | if ( (file = fopen(fullPath, "r")) ) { 48 | fclose(file); 49 | result = oslLoadSoundFile(fullPath, stream); 50 | oslSetSoundLoop(result, 0); 51 | } 52 | 53 | return result; 54 | } 55 | 56 | 57 | void PHL_PlayMusic(OSL_SOUND* snd) 58 | { 59 | //Music always plays on the first channel 60 | PHL_PlaySound(snd, 0); 61 | } 62 | 63 | void PHL_PlaySound(OSL_SOUND* snd, int channel) 64 | { 65 | if (snd) { 66 | oslPlaySound(snd, channel); 67 | } 68 | } 69 | 70 | void PHL_StopMusic() 71 | { 72 | PHL_StopSound(bgmMusic, 0); 73 | } 74 | 75 | void PHL_StopSound(OSL_SOUND* snd, int channel) 76 | { 77 | if (snd) { 78 | oslStopSound(snd); 79 | } 80 | } 81 | 82 | void PHL_FreeSound(OSL_SOUND* snd) 83 | { 84 | if (snd) { 85 | oslDeleteSound(snd); 86 | } 87 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET := HCL 2 | TITLE := HYDCASLAB 3 | VPK_TITLE := Hydra Castle Labyrinth 4 | SOURCES := source source/enemies source/vita 5 | 6 | LIBS = -lvita2d -lSceLibKernel_stub -lScePvf_stub -lSceAppMgr_stub -lSceCtrl_stub \ 7 | -lSceSysmodule_stub -lm -lSceAppUtil_stub -lScePgf_stub -ljpeg -lfreetype -lc -lScePower_stub \ 8 | -lSceCommonDialog_stub -lpng16 -lz -lspeexdsp -lSceAudio_stub -lSceGxm_stub -lSceDisplay_stub \ 9 | 10 | CFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c)) 11 | CPPFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.cpp)) 12 | BINFILES := $(foreach dir,$(DATA), $(wildcard $(dir)/*.bin)) 13 | OBJS := $(addsuffix .o,$(BINFILES)) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o) 14 | 15 | PREFIX = arm-vita-eabi 16 | CC = $(PREFIX)-gcc 17 | CXX = $(PREFIX)-g++ 18 | CFLAGS = -fno-lto -g -Wl,-q -O2 -D_PSP2 -DHAVE_LIBSPEEXDSP \ 19 | -DWANT_FMMIDI=1 -DUSE_AUDIO_RESAMPLER -DWANT_FASTWAV 20 | CXXFLAGS = $(CFLAGS) -fno-exceptions -std=gnu++11 -fpermissive 21 | ASFLAGS = $(CFLAGS) 22 | 23 | all: $(TARGET).vpk 24 | 25 | $(TARGET).vpk: $(TARGET).velf 26 | vita-make-fself -s $< build\eboot.bin 27 | vita-mksfoex -s TITLE_ID=$(TITLE) "$(VPK_TITLE)" param.sfo 28 | cp -f param.sfo build/sce_sys/param.sfo 29 | 30 | #------------ Comment this if you don't have 7zip ------------------ 31 | 7z a -tzip $(TARGET).vpk -r .\build\sce_sys\* .\build\eboot.bin 32 | #------------------------------------------------------------------- 33 | 34 | %.velf: %.elf 35 | cp $< $<.unstripped.elf 36 | $(PREFIX)-strip -g $< 37 | vita-elf-create $< $@ 38 | vita-make-fself -s $@ eboot.bin 39 | 40 | $(TARGET).elf: $(OBJS) 41 | $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@ 42 | 43 | clean: 44 | @rm -rf $(TARGET).velf $(TARGET).elf $(OBJS) eboot.bin -------------------------------------------------------------------------------- /source/enemies/heads.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADS_H 2 | #define HEADS_H 3 | 4 | #include "../collision.h" 5 | 6 | //Goblin/medusa/dragon head statues 7 | typedef struct { 8 | int id, type; //0 = Rhyno head | 1 = Goblin | 2 = Dragon | 3 = Demon | 4 = Fireball | 5 = Air Jar 9 | int state, timer; 10 | double x, y; 11 | int dir; 12 | int hp, invincible; 13 | int cooloff; 14 | int counter; 15 | 16 | //Mask mask; 17 | } Head; 18 | 19 | void createHead(int type, int x, int y, int dir, int offset, int cooloff); 20 | 21 | //Bullet from Rhyno statues 22 | typedef struct { 23 | int id; 24 | double x, y; 25 | int hsp; 26 | double imageIndex; 27 | 28 | //Mask mask; 29 | } Bullet; 30 | 31 | void createBullet(int x, int y, int dir, int minid); //Minid is the spawner's id 32 | 33 | //Fireball 34 | typedef struct { 35 | int id; 36 | double x, y; 37 | int angle; 38 | int spd; 39 | double imageIndex; 40 | 41 | Mask mask; 42 | } Fireball; 43 | 44 | void createFireball(int x, int y, int angle, int minid); 45 | 46 | //Medusa lazer 47 | typedef struct { 48 | int id; 49 | double x, y; 50 | int dir; 51 | double imageIndex; 52 | 53 | Mask mask; 54 | } Laser; 55 | 56 | void createLaser(int x, int y, int dir); 57 | 58 | //Dragon flame 59 | typedef struct { 60 | int id; 61 | int x, y; 62 | int dir; 63 | int timer; 64 | double imageIndex; 65 | } Flame; 66 | 67 | void createFlame(int x, int y, int dir); 68 | 69 | //Demon Boulder 70 | typedef struct { 71 | int id; 72 | double x, y; 73 | double vsp; 74 | int dir; 75 | double imageIndex; 76 | } Rock; 77 | 78 | void createRock(int x, int y, int dir); 79 | 80 | //Air 81 | typedef struct { 82 | int id; 83 | double x, y; 84 | double imageIndex; 85 | } Air; 86 | 87 | void createAir(int x, int y); 88 | 89 | #endif -------------------------------------------------------------------------------- /source/qda.c: -------------------------------------------------------------------------------- 1 | #include "qda.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef _PSP2 7 | extern uint8_t use_uma0; 8 | #endif 9 | 10 | //Load headers for each image 11 | //Returns: 0 = file not found | 1 = success | 2 = Invalid file 12 | int initQDA() 13 | { 14 | int result = 0; 15 | FILE* f; 16 | 17 | char fullPath[80]; 18 | strcpy(fullPath, ""); 19 | #ifdef _3DS 20 | strcat(fullPath, "romfs:/"); 21 | #endif 22 | #ifdef _PSP2 23 | sprintf(fullPath, "%s:data/HCL/bmp.qda", use_uma0 ? "uma0" : "ux0"); 24 | #else 25 | strcat(fullPath, "bmp.qda"); 26 | #endif 27 | if ( (f = fopen(fullPath, "rb")) ) { 28 | result = 1; 29 | 30 | //Read header data into memory 31 | int allHeadersSize = 0x1F5C; 32 | unsigned char* QDAFile = (unsigned char*)malloc(allHeadersSize); 33 | fread(QDAFile, allHeadersSize, 1, f); 34 | 35 | //Check if QDA file is valid 36 | { 37 | if (QDAFile[4] == 0x51 && QDAFile[5] == 0x44 && QDAFile[6] == 0x41 && QDAFile[7] == 0x30) { 38 | //Load headers separately 39 | { 40 | int numofsheets = 29; 41 | int headerSize = 0x10C; 42 | 43 | int i; 44 | for (i = 0; i < numofsheets; i++) { 45 | //memcpy(&headers[i], &QDAFile[0x100 + (i * headerSize)], sizeof(QDAHeader)); 46 | int offset = 256 + (i * headerSize); 47 | memcpy(&headers[i].offset, &QDAFile[offset], 4); 48 | memcpy(&headers[i].size, &QDAFile[offset + 4], 4); 49 | memcpy(&headers[i].bytes, &QDAFile[offset + 8], 4); 50 | memcpy(&headers[i].fileName, &QDAFile[offset + 12], 0x100); 51 | } 52 | } 53 | }else{ 54 | result = 2; 55 | } 56 | } 57 | 58 | //Cleanup 59 | free(QDAFile); 60 | } 61 | 62 | fclose(f); 63 | 64 | return result; 65 | } -------------------------------------------------------------------------------- /Makefile.psp: -------------------------------------------------------------------------------- 1 | TARGET := HydraCloneLabyrinth 2 | OBJS = source/main.o source/PHL.o source/collision.o source/psp/graphics.o source/psp/input.o source/psp/system.o source/psp/audio.o source/titlescreen.o source/inventory.o source/options.o source/ini.o source/text.o source/game.o source/hero.o source/object.o source/enemy.o source/effect.o source/qda.o source/weapon.o source/platform.o source/enemies/slime.o source/enemies/bat.o source/enemies/slug.o source/enemies/knight.o source/enemies/heads.o source/enemies/gas.o source/enemies/skull.o source/enemies/fish.o source/enemies/waterjumper.o source/enemies/podoboo.o source/enemies/thwomp.o source/enemies/dodo.o source/enemies/batboss.o source/enemies/skeleton.o source/enemies/ghoul.o source/enemies/crab.o source/enemies/seal.o source/enemies/jellyfish.o source/enemies/gyra.o source/enemies/wizard.o source/enemies/pendulum.o source/enemies/lolidra.o source/enemies/bee.o source/enemies/devil.o source/enemies/boar.o source/enemies/firewheel.o source/enemies/golem.o source/enemies/garm.o source/enemies/poisonknight.o source/enemies/dog.o source/enemies/boomknight.o source/enemies/pumpkin.o source/stagedata.o source/enemies/hydra.o 3 | 4 | INCDIR = 5 | CFLAGS = -O2 -g -G0 -Wall -D_PSP 6 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 7 | ASFLAGS = $(CFLAGS) 8 | LIBDIR = 9 | 10 | MYLIBS= 11 | STDLIBS = -losl -lpng -lz \ 12 | -lpspsdk -lpspctrl -lpspumd -lpsprtc -lpsppower -lpspgu -lpspaudiolib -lpspaudio -lm -lpsphprm 13 | 14 | LIBS +=$(STDLIBS)$(MYLIBS) 15 | 16 | LDFLAGS = 17 | EXTRA_TARGETS = EBOOT.PBP 18 | PSP_EBOOT_TITLE = Hydra Castle Labyrinth 19 | PSP_EBOOT_ICON = ICON0.PNG 20 | PSP_EBOOT_PIC1 = PIC1.PNG 21 | #PSP_FW_VERSION = 660 22 | BUILD_PRX = 0 23 | 24 | PSPSDK=$(shell psp-config --pspsdk-path) 25 | include $(PSPSDK)/lib/build.mak -------------------------------------------------------------------------------- /source/vita/decoder_wav.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of EasyRPG Player. 3 | * 4 | * EasyRPG Player is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * EasyRPG Player is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with EasyRPG Player. If not, see . 16 | */ 17 | 18 | #ifndef EASYRPG_AUDIO_DECODER_WAV_H 19 | #define EASYRPG_AUDIO_DECODER_WAV_H 20 | 21 | // Headers 22 | #include "audio_decoder.h" 23 | #include 24 | #include 25 | 26 | /** 27 | * Standalone basic audio decoder for WAV 28 | */ 29 | class WavDecoder : public AudioDecoder { 30 | public: 31 | WavDecoder(); 32 | 33 | ~WavDecoder(); 34 | 35 | bool Open(FILE* file) override; 36 | 37 | bool Seek(size_t offset, Origin origin) override; 38 | 39 | bool IsFinished() const override; 40 | 41 | void GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const override; 42 | 43 | bool SetFormat(int frequency, AudioDecoder::Format format, int channels) override; 44 | 45 | private: 46 | int FillBuffer(uint8_t* buffer, int length) override; 47 | Format output_format; 48 | FILE * file_; 49 | bool finished; 50 | uint32_t samplerate; 51 | uint16_t nchannels; 52 | uint32_t audiobuf_offset; 53 | uint32_t chunk_size; 54 | uint32_t cur_pos; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /source/PHL.c: -------------------------------------------------------------------------------- 1 | #include "PHL.h" 2 | #include 3 | #include 4 | #include "qda.h" 5 | #include "game.h" 6 | 7 | void PHL_Init() 8 | { 9 | PHL_GraphicsInit(); 10 | PHL_AudioInit(); 11 | 12 | #ifdef _3DS 13 | Result rc = romfsInit(); 14 | /*if (rc) { 15 | printf("romfsInit: %08lX\n", rc); 16 | //while(1){} 17 | } 18 | else 19 | { 20 | printf("\nromfs Init Successful!\n"); 21 | }*/ 22 | #endif 23 | 24 | WHITE = 0; 25 | RED = 1; 26 | YELLOW = 2; 27 | } 28 | 29 | void PHL_Deinit() 30 | { 31 | #ifndef _PSP2 32 | PHL_AudioClose(); 33 | #endif 34 | PHL_GraphicsExit(); 35 | 36 | #ifdef _3DS 37 | romfsExit(); 38 | #endif 39 | } 40 | 41 | extern void LOG(char* format, ...); 42 | 43 | //Extracts bmps from the bmp.qda archive file 44 | PHL_Surface PHL_LoadQDA(char* fname) 45 | { 46 | PHL_Surface surf = NULL; 47 | 48 | int numofsheets = 29; 49 | int i; 50 | 51 | for (i = 0; i < numofsheets; i++) 52 | { 53 | if (strcmp(fname, (char*)headers[i].fileName) == 0) { //Match found 54 | //printf("\nMatch Found: %s", fname); 55 | surf = PHL_LoadBMP(i); 56 | i = numofsheets; //End search 57 | } 58 | } 59 | 60 | return surf; 61 | } 62 | 63 | void PHL_DrawTextBold(char* txt, int dx, int dy, int col) 64 | { 65 | int i, cx, cy; 66 | 67 | for (i = 0; i < strlen(txt); i++) 68 | { 69 | cx = (txt[i] - 32) * 16; 70 | cy = 32 * col; 71 | 72 | while (cx >= 512) { 73 | cx -= 512; 74 | cy += 16; 75 | } 76 | 77 | PHL_DrawSurfacePart(dx + (16 * i), dy, cx, cy, 16, 16, images[imgBoldFont]); 78 | } 79 | } 80 | 81 | void PHL_DrawTextBoldCentered(char* txt, int dx, int dy, int col) 82 | { 83 | if (dy < 640 && dy > -16) { 84 | int stringW = strlen(txt) * 16; 85 | 86 | PHL_DrawTextBold(txt, dx - (stringW / 2), dy, col); 87 | } 88 | } -------------------------------------------------------------------------------- /source/enemies/pendulum.c: -------------------------------------------------------------------------------- 1 | #include "pendulum.h" 2 | #include "../enemy.h" 3 | #include "../game.h" 4 | #include "../hero.h" 5 | #include 6 | #include 7 | 8 | void createPendulum(int x, int y, int side) 9 | { 10 | int i; 11 | for (i = 0; i < MAX_ENEMIES; i++) { 12 | if (enemies[i] == NULL) { 13 | Enemy* e = malloc(sizeof *e); 14 | Pendulum* p = malloc(sizeof *p); 15 | p->id = i; 16 | 17 | p->x = x; 18 | p->y = y; 19 | 20 | p->angle = 0; 21 | p->rotCounter = 180; 22 | if (side == 1) { 23 | p->rotCounter += 180; 24 | } 25 | 26 | p->mask.circle = 1; 27 | p->mask.unused = 0; 28 | p->mask.w = 24; 29 | p->mask.x = 0; 30 | p->mask.y = 0; 31 | 32 | e->data = p; 33 | e->enemyStep = pendulumStep; 34 | e->enemyDraw = pendulumDraw; 35 | e->type = 22; 36 | 37 | enemies[i] = e; 38 | i = MAX_ENEMIES; 39 | } 40 | } 41 | } 42 | 43 | void pendulumStep(Pendulum* p) 44 | { 45 | p->rotCounter += 2; 46 | if (p->rotCounter >= 360) { 47 | p->rotCounter -= 360; 48 | } 49 | 50 | p->angle += (3.15 * cos(p->rotCounter * 3.14159 / 180)); 51 | 52 | //Update Mask 53 | p->mask.x = p->x + (96 * cos((p->angle + 90) * 3.14159 / 180)); 54 | p->mask.y = p->y + (96 * sin((p->angle + 90) * 3.14159 / 180)); 55 | 56 | //Hit Player 57 | if (checkCollision(p->mask, getHeroMask())) { 58 | heroHit(15, p->mask.x); 59 | } 60 | } 61 | 62 | void pendulumDraw(Pendulum* p) 63 | { 64 | int drawX = p->x, 65 | drawY = p->y; 66 | 67 | int len[] = {0, 16, 32, 48, 66, 96}; 68 | int cropX[] = {64, 64, 64, 64, 0, 576}; 69 | int cropY[] = {128, 128, 128, 128, 128, 64}; 70 | 71 | int i; 72 | for (i = 0; i < 6; i++) { 73 | drawX = p->x + (len[i] * cos((p->angle + 90) * 3.14159 / 180)); 74 | drawY = p->y + (len[i] * sin((p->angle + 90) * 3.14159 / 180)); 75 | 76 | PHL_DrawSurfacePart(drawX- 32, drawY - 32, cropX[i], cropY[i], 64, 64, images[imgMisc32]); 77 | } 78 | } -------------------------------------------------------------------------------- /source/psp/input.c: -------------------------------------------------------------------------------- 1 | #include "input.h" 2 | #include "../text.h" 3 | 4 | int deadZone = 64; 5 | 6 | void updateKey(Button* btn, int state); 7 | 8 | void PHL_ScanInput() 9 | { 10 | oslReadKeys(); 11 | 12 | int pUp = 0, pDown = 0, pLeft = 0, pRight = 0; 13 | 14 | if (osl_keys->held.up || osl_keys->analogY < -deadZone) { pUp = 1; } 15 | if (osl_keys->held.down || osl_keys->analogY > deadZone) { pDown = 1; } 16 | if (osl_keys->held.left || osl_keys->analogX < -deadZone) { pLeft = 1; } 17 | if (osl_keys->held.right || osl_keys->analogX > deadZone) { pRight = 1; } 18 | 19 | updateKey(&btnUp, pUp); 20 | updateKey(&btnDown, pDown); 21 | updateKey(&btnLeft, pLeft); 22 | updateKey(&btnRight, pRight); 23 | 24 | updateKey(&btnL, osl_keys->held.L); 25 | updateKey(&btnR, osl_keys->held.R); 26 | 27 | updateKey(&btnStart, osl_keys->held.start); 28 | updateKey(&btnSelect, osl_keys->held.select); 29 | 30 | updateKey(&btnFaceRight, osl_keys->held.circle); 31 | updateKey(&btnFaceDown, osl_keys->held.cross); 32 | updateKey(&btnFaceLeft, osl_keys->held.square); 33 | updateKey(&btnFaceUp, osl_keys->held.triangle); 34 | 35 | btnAccept = btnFaceDown; 36 | btnDecline = btnFaceRight; 37 | //Swap buttons for japanese 38 | if (getLanguage() == JAPANESE) { 39 | btnAccept = btnFaceRight; 40 | btnDecline = btnFaceDown; 41 | } 42 | 43 | /* 44 | if (btnFaceUp.pressed == 1) { 45 | FILE* f; 46 | 47 | if ( (f = fopen("debug.txt", "a")) ) { 48 | fprintf(f, "\n%i bytes available", oslGetRamStatus().maxAvailable); 49 | } 50 | 51 | fclose(f); 52 | } 53 | */ 54 | } 55 | 56 | void updateKey(Button* btn, int state) 57 | { 58 | if (state) { 59 | if (btn->held == 1) { 60 | btn->pressed = 0; 61 | }else{ 62 | btn->pressed = 1; 63 | } 64 | btn->held = 1; 65 | btn->released = 0; 66 | }else{ 67 | if (btn->held == 1) { 68 | btn->released = 1; 69 | }else{ 70 | btn->released = 0; 71 | } 72 | btn->held = 0; 73 | btn->pressed = 0; 74 | } 75 | } -------------------------------------------------------------------------------- /source/wii/audio.c: -------------------------------------------------------------------------------- 1 | #include "audio.h" 2 | 3 | void PHL_AudioInit() 4 | { 5 | //oslInitAudio(); 6 | if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 1, 4096)) 7 | { 8 | fprintf(stderr, "SDL_Mixer Error: %s\n", Mix_GetError()); 9 | exit(EXIT_FAILURE); 10 | } 11 | } 12 | 13 | void PHL_AudioClose() 14 | { 15 | Mix_CloseAudio(); 16 | } 17 | 18 | //Each system can use a custom music file extension 19 | PHL_Music PHL_LoadMusic(char* fname, int loop) 20 | { 21 | PHL_Music result; 22 | result.loop = loop; 23 | 24 | char fullPath[40]; 25 | strcpy(fullPath, fname); 26 | strcat(fullPath, ".ogg"); 27 | 28 | FILE* file; 29 | if ((file = fopen(fullPath, "r"))) { 30 | fclose(file); 31 | 32 | result.data = Mix_LoadMUS(fullPath); 33 | result.used = 1; 34 | }else{ 35 | result.used = 0; 36 | } 37 | 38 | return result; 39 | } 40 | 41 | //PHL_Sound PHL_LoadSound(char* fname, int loop, int stream, int channel) 42 | PHL_Sound PHL_LoadSound(char* fname) 43 | { 44 | PHL_Sound result; 45 | 46 | FILE* file; 47 | if ((file = fopen(fname, "r"))) { 48 | fclose(file); 49 | 50 | result.data = Mix_LoadWAV(fname); 51 | result.used = 1; 52 | }else{ 53 | result.used = 0; 54 | } 55 | 56 | return result; 57 | } 58 | 59 | void PHL_PlayMusic(PHL_Music snd) 60 | { 61 | if (snd.used == 1) { 62 | int loop = 1; 63 | if (snd.loop == 1) { 64 | loop = -1; 65 | } 66 | Mix_PlayMusic(snd.data, loop); 67 | } 68 | } 69 | 70 | //void PHL_PlaySound(PHL_Sound snd) 71 | void PHL_PlaySound(PHL_Sound snd, int channel) 72 | { 73 | if (snd.used == 1) { 74 | Mix_PlayChannel(channel, snd.data, 0); 75 | } 76 | } 77 | 78 | void PHL_StopMusic() 79 | { 80 | Mix_HaltMusic(); 81 | } 82 | 83 | void PHL_StopSound(PHL_Sound snd, int channel) 84 | { 85 | 86 | } 87 | 88 | void PHL_FreeMusic(PHL_Music snd) 89 | { 90 | Mix_FreeMusic(snd.data); 91 | snd.used = 0; 92 | } 93 | 94 | void PHL_FreeSound(PHL_Sound snd) 95 | { 96 | Mix_FreeChunk(snd.data); 97 | snd.used = 0; 98 | } -------------------------------------------------------------------------------- /source/main.c: -------------------------------------------------------------------------------- 1 | #include "PHL.h" 2 | #include "game.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #ifdef _PSP2 8 | extern int enterButton; 9 | uint8_t use_uma0 = 0; // 0 = ux0, 1 = uma0 10 | #endif 11 | 12 | void createSaveLocations() 13 | { 14 | //Force create save data folders 15 | #ifdef _3DS 16 | //3DS builds 17 | mkdir("sdmc:/3ds", 0777); 18 | mkdir("sdmc:/3ds/appdata", 0777); 19 | mkdir("sdmc:/3ds/appdata/HydraCastleLabyrinth", 0777); 20 | mkdir("sdmc:/3ds/appdata/HydraCastleLabyrinth/data", 0777); 21 | mkdir("sdmc:/3ds/appdata/HydraCastleLabyrinth/map", 0777); 22 | #else 23 | #ifdef _PSP2 24 | //vita 25 | if (use_uma0){ 26 | sceIoMkdir("uma0:data/HCL", 0777); 27 | sceIoMkdir("uma0:data/HCL/data", 0777); 28 | sceIoMkdir("uma0:data/HCL/map", 0777); 29 | }else{ 30 | sceIoMkdir("ux0:data/HCL", 0777); 31 | sceIoMkdir("ux0:data/HCL/data", 0777); 32 | sceIoMkdir("ux0:data/HCL/map", 0777); 33 | } 34 | #else 35 | //psp, wii 36 | mkdir("/data", 0777); 37 | mkdir("/map", 0777); 38 | #endif 39 | #endif 40 | } 41 | 42 | 43 | int main(int argc, char **argv) 44 | { 45 | //Setup 46 | #ifdef _3DS 47 | sdmcInit(); 48 | osSetSpeedupEnable(false); 49 | #endif 50 | 51 | #ifdef _PSP2 52 | SceAppUtilInitParam appUtilParam; 53 | SceAppUtilBootParam appUtilBootParam; 54 | memset(&appUtilParam, 0, sizeof(SceAppUtilInitParam)); 55 | memset(&appUtilBootParam, 0, sizeof(SceAppUtilBootParam)); 56 | sceAppUtilInit(&appUtilParam, &appUtilBootParam); 57 | sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, (int *)&enterButton); 58 | sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG); 59 | 60 | // Checking if data files are available on ux0 partition 61 | FILE* f = fopen("ux0:data/HCL/bmp.qda", "rb"); 62 | if (f == NULL) use_uma0 = 1; 63 | else fclose(f); 64 | #endif 65 | 66 | srand(time(NULL)); 67 | createSaveLocations(); 68 | 69 | game(); 70 | 71 | //System specific cleanup 72 | #ifdef _PSP 73 | sceKernelExitGame(); 74 | #endif 75 | 76 | #ifdef _3DS 77 | sdmcExit(); 78 | #endif 79 | 80 | #ifdef _PSP2 81 | sceAppUtilShutdown(); 82 | #endif 83 | 84 | return 0; 85 | } -------------------------------------------------------------------------------- /source/vita/decoder_fmmidi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of EasyRPG Player. 3 | * 4 | * EasyRPG Player is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * EasyRPG Player is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with EasyRPG Player. If not, see . 16 | */ 17 | 18 | #ifndef EASYRPG_AUDIO_DECODER_FMMIDI_H 19 | #define EASYRPG_AUDIO_DECODER_FMMIDI_H 20 | 21 | // Headers 22 | #include 23 | #include 24 | #include "audio_decoder.h" 25 | #include "midisequencer.h" 26 | #include "midisynth.h" 27 | 28 | /** 29 | * Audio decoder for MIDI powered by FM MIDI 30 | */ 31 | class FmMidiDecoder : public AudioDecoder, midisequencer::output { 32 | public: 33 | FmMidiDecoder(); 34 | 35 | ~FmMidiDecoder(); 36 | 37 | // Audio Decoder interface 38 | bool Open(FILE* file) override; 39 | 40 | bool Seek(size_t offset, Origin origin) override; 41 | 42 | bool IsFinished() const override; 43 | 44 | void GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const override; 45 | 46 | bool SetFormat(int frequency, AudioDecoder::Format format, int channels) override; 47 | 48 | bool SetPitch(int pitch) override; 49 | 50 | int GetTicks() const override; 51 | private: 52 | int FillBuffer(uint8_t* buffer, int length) override; 53 | 54 | FILE* file; 55 | float mtime = 0.0f; 56 | float pitch = 1.0f; 57 | int frequency = 44100; 58 | bool begin = true; 59 | 60 | // midisequencer::output interface 61 | int synthesize(int_least16_t* output, std::size_t samples, float rate); 62 | void midi_message(int, uint_least32_t message) override; 63 | void sysex_message(int, const void* data, std::size_t size) override; 64 | void meta_event(int, const void*, std::size_t) override; 65 | void reset() override; 66 | 67 | std::unique_ptr seq; 68 | std::unique_ptr synth; 69 | std::unique_ptr note_factory; 70 | midisynth::DRUMPARAMETER p; 71 | void load_programs(); 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /source/enemies/gas.c: -------------------------------------------------------------------------------- 1 | #include "gas.h" 2 | #include "../PHL.h" 3 | #include "../game.h" 4 | #include "../hero.h" 5 | #include 6 | 7 | void gasStep(Gas* g); 8 | void gasDraw(Gas* g); 9 | 10 | void createGas(int x, int y, int temp) 11 | { 12 | if (temp == 0 || hasKey[7] == 0) { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* e = malloc(sizeof *e); 17 | Gas* g = malloc(sizeof *g); 18 | g->id = i; 19 | 20 | g->x = x; 21 | g->y = y; 22 | 23 | g->state = 0; 24 | g->timer = 0; 25 | g->imageIndex = 0; 26 | 27 | /* 28 | g->mask.unused = g->mask.circle = 0; 29 | g->mask.w = g->mask.h = 24; 30 | g->mask.x = x + 20 - (g->mask.w / 2); 31 | g->mask.y = y + 40 - g->mask.h; 32 | */ 33 | 34 | e->data = g; 35 | e->enemyStep = gasStep; 36 | e->enemyDraw = gasDraw; 37 | e->type = -1; 38 | 39 | enemies[i] = e; 40 | i = MAX_ENEMIES; 41 | } 42 | } 43 | } 44 | } 45 | 46 | void gasStep(Gas* g) 47 | { 48 | if (g->state != 0) { 49 | g->imageIndex += 0.2; 50 | } 51 | 52 | if (g->state == 0) { //Wait 53 | Mask tempMask; 54 | tempMask.circle = tempMask.unused = 0; 55 | tempMask.x = g->x - 100; 56 | tempMask.y = g->y - 20; 57 | tempMask.w = 240; 58 | tempMask.h = 60; 59 | 60 | if (checkCollisionXY(tempMask, herox, heroy + 20)) { 61 | g->state = 1; 62 | g->imageIndex = 3; 63 | g->timer = 32; 64 | PHL_PlaySound(sounds[sndGas01], CHN_ENEMIES); 65 | } 66 | } 67 | else if (g->state == 1 || g->state == 3) { //Small puff 68 | if (g->imageIndex >= 5) { 69 | g->imageIndex -= 2; 70 | } 71 | 72 | g->timer -= 1; 73 | if (g->timer <= 0) { 74 | if (g->state == 3) { 75 | g->state = 0; 76 | }else{ 77 | g->state = 2; 78 | g->imageIndex = 0; 79 | g->timer = 175; 80 | } 81 | } 82 | } 83 | else if (g->state == 2) { //Big puff 84 | if (g->imageIndex >= 3) { 85 | g->imageIndex -= 3; 86 | } 87 | 88 | g->timer -= 1; 89 | if (g->timer <= 0) { 90 | g->state = 3; 91 | g->timer = 120; 92 | g->imageIndex = 3; 93 | } 94 | 95 | if (hasItem[7] != 1) { //Does not have gas mask 96 | Mask mask; 97 | mask.unused = mask.circle = 0; 98 | mask.w = mask.h = 24; 99 | mask.x = g->x + 20 - (mask.w / 2); 100 | mask.y = g->y + 40 - mask.h; 101 | 102 | if (checkCollision(getHeroMask(), mask)) { 103 | if (heroHit(15, g->x + 20)) { 104 | heroPoison(); 105 | } 106 | } 107 | } 108 | } 109 | } 110 | 111 | void gasDraw(Gas* g) 112 | { 113 | if (g->state != 0) { 114 | PHL_DrawSurfacePart(g->x, g->y, (int)g->imageIndex * 40, 400, 40, 40, images[imgEnemies]); 115 | } 116 | } -------------------------------------------------------------------------------- /source/enemies/fish.c: -------------------------------------------------------------------------------- 1 | #include "fish.h" 2 | #include "../game.h" 3 | #include "../enemy.h" 4 | #include "../PHL.h" 5 | #include "../collision.h" 6 | #include "../hero.h" 7 | #include 8 | 9 | void createFish(int x, int y, int dir) 10 | { 11 | int i; 12 | for (i = 0; i < MAX_ENEMIES; i++) { 13 | if (enemies[i] == NULL) { 14 | Enemy* e = malloc(sizeof *e); 15 | Fish* f = malloc(sizeof *f); 16 | f->id = i; 17 | 18 | f->x = f->xstart = x; 19 | f->y = y; 20 | 21 | f->imageIndex = 0; 22 | 23 | f->spd = 1; 24 | 25 | f->turning = 0; 26 | f->dir = 1; 27 | if (dir == 1) { 28 | f->dir = -1; 29 | f->spd = -1; 30 | } 31 | 32 | f->mask.circle = f->mask.unused = 0; 33 | f->mask.x = x + 3; 34 | f->mask.y = y + 6; 35 | f->mask.w = 34; 36 | f->mask.h = 32; 37 | 38 | e->data = f; 39 | e->enemyStep = fishStep; 40 | e->enemyDraw = fishDraw; 41 | e->type = 13; 42 | 43 | enemies[i] = e; 44 | i = MAX_ENEMIES; 45 | } 46 | } 47 | } 48 | 49 | void fishStep(Fish* f) 50 | { 51 | double fric = 0.02; 52 | 53 | f->x += f->spd; 54 | f->mask.x = f->x + 3; 55 | 56 | if (f->turning == 0) { 57 | f->imageIndex += 0.1; 58 | if (f->imageIndex >= 2) { 59 | f->imageIndex -= 2; 60 | } 61 | }else{ 62 | f->imageIndex += 0.25; 63 | if (f->imageIndex >= 3) { 64 | f->turning = 0; 65 | } 66 | } 67 | 68 | if (f->dir == 1) { 69 | if (f->x > f->xstart + 25) { 70 | f->spd -= fric; 71 | 72 | if (f->spd < 0) { 73 | f->dir = -1; 74 | f->turning = 1; 75 | f->imageIndex = 0; 76 | } 77 | }else{ 78 | f->spd += fric; 79 | if (f->spd > 1) { 80 | f->spd = 1; 81 | } 82 | } 83 | }else if (f->dir == -1) { 84 | if (f->x < f->xstart - 25) { 85 | f->spd += fric; 86 | 87 | if (f->spd > 0) { 88 | f->dir = 1; 89 | f->turning = 1; 90 | f->imageIndex = 0; 91 | } 92 | }else{ 93 | f->spd -= fric; 94 | if (f->spd < -1) { 95 | f->spd = -1; 96 | } 97 | } 98 | } 99 | 100 | if (checkCollision(f->mask, getHeroMask())) { 101 | heroHit(15, f->x + 20); 102 | } 103 | 104 | //Weapon collision 105 | int i; 106 | for (i = 0; i < MAX_WEAPONS; i++) { 107 | if (weapons[i] != NULL) { 108 | if (checkCollision(f->mask, weapons[i]->weaponMask)) { 109 | weaponHit(weapons[i]); 110 | createEffect(2, f->x - 12, f->y - 12); 111 | spawnCollectable(f->x + 20, f->y); 112 | enemyDestroy(f->id); 113 | 114 | i = MAX_WEAPONS; 115 | } 116 | } 117 | } 118 | } 119 | 120 | void fishDraw(Fish* f) 121 | { 122 | int thisImage = 0; 123 | if (f->turning == 1) { 124 | if (f->dir == -1) { 125 | int animation[3] = {4, 6, 5}; 126 | thisImage = animation[(int)f->imageIndex]; 127 | }else{ 128 | int animation[3] = {5, 6, 4}; 129 | thisImage = animation[(int)f->imageIndex]; 130 | } 131 | }else{ 132 | thisImage = f->imageIndex; 133 | if (f->spd < 0) { 134 | thisImage += 2; 135 | } 136 | } 137 | 138 | PHL_DrawSurfacePart(f->x, f->y, 360 + (thisImage * 40), 360, 40, 40, images[imgEnemies]); 139 | } -------------------------------------------------------------------------------- /source/enemies/wizard.c: -------------------------------------------------------------------------------- 1 | #include "wizard.h" 2 | #include "../enemy.h" 3 | #include "../game.h" 4 | #include "../hero.h" 5 | #include 6 | 7 | void createWizard(int x, int y) 8 | { 9 | int i; 10 | for (i = 0; i < MAX_ENEMIES; i++) { 11 | if (enemies[i] == NULL) { 12 | Enemy* e = malloc(sizeof *e); 13 | Wizard* w = malloc(sizeof *w); 14 | w->id = i; 15 | 16 | w->x = x; 17 | w->y = y; 18 | 19 | w->imageIndex = 0; 20 | 21 | w->state = 0; 22 | w->timer = 50; 23 | w->visible = 1; 24 | 25 | w->mask.circle = w->mask.unused = 0; 26 | w->mask.w = 24; 27 | w->mask.h = 38; 28 | w->mask.x = w->x + 8; 29 | w->mask.y = w->y + 2; 30 | 31 | e->data = w; 32 | e->enemyStep = wizardStep; 33 | e->enemyDraw = wizardDraw; 34 | e->type = 21; 35 | 36 | enemies[i] = e; 37 | i = MAX_ENEMIES; 38 | } 39 | } 40 | } 41 | 42 | void wizardStep(Wizard* w) 43 | { 44 | w->imageIndex += 0.3; 45 | if (w->imageIndex >= 3) { 46 | w->imageIndex -= 3; 47 | } 48 | 49 | //Stand still 50 | if (w->state == 0) { 51 | w->timer -= 1; 52 | 53 | if (w->timer <= 0) { 54 | PHL_PlaySound(sounds[sndPi10], CHN_ENEMIES); 55 | w->state = 1; 56 | w->timer = 15; 57 | } 58 | } 59 | //Flash 60 | else if (w->state == 1 || w->state == 3) { 61 | if (w->visible == 0) { 62 | w->visible = 1; 63 | }else{ 64 | w->visible = 0; 65 | } 66 | 67 | w->timer -= 1; 68 | if (w->timer <= 0) { 69 | if (w->state == 1) { 70 | w->state = 2; 71 | w->timer = 60; 72 | } 73 | else if (w->state == 3) { 74 | w->visible = 1; 75 | w->state = 0; 76 | w->timer = 50; 77 | } 78 | } 79 | } 80 | //Invisible 81 | else if (w->state == 2) { 82 | w->visible = 0; 83 | 84 | w->timer -= 1; 85 | if (w->timer <= 0) { 86 | PHL_PlaySound(sounds[sndPi03], CHN_ENEMIES); 87 | w->state = 3; 88 | w->timer = 15; 89 | 90 | //Horizontal Jump 91 | int gridX = w->x / 40, 92 | gridY = w->y / 40, 93 | lastGridX = gridX; 94 | 95 | do { 96 | gridX = (rand() % 16) + 1; 97 | } while (collisionTiles[gridX][gridY] != 0 || 98 | collisionTiles[gridX][gridY+1] != 1 || 99 | gridX == lastGridX); 100 | 101 | w->x = gridX * 40; 102 | w->mask.x = w->x + 8; 103 | } 104 | } 105 | 106 | if (w->state == 0 || w->state == 3) { 107 | //Hit Player 108 | if (checkCollision(w->mask, getHeroMask())) { 109 | heroHit(15, w->x + 20); 110 | } 111 | 112 | //Weapon Collision 113 | int i; 114 | for (i = 0; i < MAX_WEAPONS; i++) { 115 | if (weapons[i] != NULL) { 116 | if (checkCollision(w->mask, weapons[i]->weaponMask)) { 117 | weaponHit(weapons[i]); 118 | createEffect(2, w->x - 12, w->y - 6); 119 | spawnCollectable(w->x + 20, w->y); 120 | enemyDestroy(w->id); 121 | i = MAX_WEAPONS; 122 | } 123 | } 124 | } 125 | } 126 | } 127 | 128 | void wizardDraw(Wizard* w) 129 | { 130 | if (w->visible == 1) { 131 | PHL_DrawSurfacePart(w->x, w->y, 520 + (((int)w->imageIndex) * 40), 480, 40, 40, images[imgEnemies]); 132 | } 133 | } -------------------------------------------------------------------------------- /source/vita/midisequencer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2003-2006 yuno 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 3. Neither the name of copyright holders nor the names of its contributors 13 | may be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef midisequencer_h 29 | #define midisequencer_h 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | namespace midisequencer{ 37 | /* 38 | typedef unsigned long uint_least32_t; 39 | */ 40 | struct midi_message{ 41 | float time; 42 | uint_least32_t message; 43 | int port; 44 | int track; 45 | }; 46 | 47 | class uncopyable{ 48 | public: 49 | uncopyable(){} 50 | private: 51 | uncopyable(const uncopyable&); 52 | void operator=(const uncopyable&); 53 | }; 54 | 55 | class output:uncopyable{ 56 | public: 57 | virtual void midi_message(int port, uint_least32_t message) = 0; 58 | virtual void sysex_message(int port, const void* data, std::size_t size) = 0; 59 | virtual void meta_event(int type, const void* data, std::size_t size) = 0; 60 | virtual void reset() = 0; 61 | protected: 62 | ~output(){} 63 | }; 64 | 65 | class sequencer:uncopyable{ 66 | public: 67 | sequencer(); 68 | void clear(); 69 | void rewind(); 70 | bool load(void* fp, int(*fgetc)(void*)); 71 | bool load(std::FILE* fp); 72 | int get_num_ports()const; 73 | float get_total_time()const; 74 | std::string get_title()const; 75 | std::string get_copyright()const; 76 | std::string get_song()const; 77 | void play(float time, output* out); 78 | private: 79 | std::vector messages; 80 | std::vector::iterator position; 81 | std::vector long_messages; 82 | void load_smf(void* fp, int(*fgetc)(void*)); 83 | }; 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /source/enemies/slug.c: -------------------------------------------------------------------------------- 1 | #include "slug.h" 2 | #include "../enemy.h" 3 | #include "../game.h" 4 | #include "../PHL.h" 5 | #include "../hero.h" 6 | #include 7 | 8 | void slugStep(Slug* s); 9 | void slugDraw(Slug* s); 10 | 11 | void createSlug(int x, int y, int dir) 12 | { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* e = malloc(sizeof *e); 17 | Slug* s = malloc(sizeof *s); 18 | s->id = i; 19 | 20 | s->x = x; 21 | s->y = y; 22 | 23 | s->imageIndex = 0; 24 | s->vsp = 0; 25 | 26 | s->dir = 1; 27 | if (dir == 1) { 28 | s->dir = -1; 29 | } 30 | 31 | e->data = s; 32 | e->enemyStep = slugStep; 33 | e->enemyDraw = slugDraw; 34 | e->type = 2; 35 | 36 | enemies[i] = e; 37 | i = MAX_ENEMIES; 38 | } 39 | } 40 | } 41 | 42 | void slugStep(Slug* s) 43 | { 44 | //Create Mask 45 | Mask mask; 46 | { 47 | mask.circle = 0; 48 | mask.unused = 0; 49 | mask.w = 32; 50 | mask.h = 24; 51 | mask.x = s->x + ((40 - mask.w) / 2); 52 | mask.y = s->y + (40 - mask.h); 53 | } 54 | 55 | //Animate 56 | { 57 | s->imageIndex += 0.1; 58 | if (s->imageIndex >= 4) { 59 | s->imageIndex -= 4; 60 | } 61 | } 62 | 63 | //Check if on ground 64 | int onground = 1; 65 | { 66 | mask.y += 1; 67 | if (checkTileCollision(1, mask) == 0 && checkTileCollision(3, mask) == 0) { 68 | onground = 0; 69 | } 70 | mask.y -= 1; 71 | } 72 | 73 | if (onground == 0) { 74 | double grav = 0.2; 75 | 76 | //Fall 77 | { 78 | s->y += s->vsp; 79 | s->vsp += grav; 80 | } 81 | 82 | //Land on ground 83 | { 84 | mask.y = mask.y + (40 - mask.h); 85 | PHL_Rect collide = getTileCollision(1, mask); 86 | if (collide.x == -1) { 87 | collide = getTileCollision(3, mask); 88 | } 89 | if (collide.x != -1) { 90 | s->y = collide.y - 40; 91 | s->vsp = 0; 92 | } 93 | } 94 | }else{ 95 | //Check if on ledge 96 | { 97 | mask.x += mask.w * s->dir; 98 | mask.y += 1; 99 | 100 | PHL_Rect collide = getTileCollision(1, mask); 101 | if (collide.x == -1) { 102 | collide = getTileCollision(3, mask); 103 | } 104 | if (collide.x == -1) { 105 | s->dir *= -1; 106 | } 107 | } 108 | } 109 | 110 | //Horizontal movement 111 | double hsp = 0.5; 112 | { 113 | s->x += s->dir * hsp; 114 | } 115 | 116 | //Check if hit a wall 117 | { 118 | mask.x = s->x + ((40 - mask.w) / 2); 119 | mask.y = s->y + (40 - mask.h); 120 | 121 | PHL_Rect collide = getTileCollision(1, mask); 122 | if (collide.x != -1) { 123 | s->dir *= -1; 124 | } 125 | } 126 | 127 | //Hit Player 128 | { 129 | if (checkCollision(mask, getHeroMask()) == 1) { 130 | heroHit(15, mask.x + (mask.w / 2)); 131 | } 132 | } 133 | 134 | //Weapon collision 135 | { 136 | int i; 137 | for (i = 0; i < MAX_WEAPONS; i++) { 138 | if (weapons[i] != NULL) { 139 | if (checkCollision(mask, weapons[i]->weaponMask) == 1) { 140 | weaponHit(weapons[i]); 141 | 142 | createEffect(2, s->x - 12, s->y - 6); 143 | spawnCollectable(s->x + 20, s->y); 144 | enemyDestroy(s->id); 145 | 146 | i = MAX_WEAPONS; 147 | } 148 | } 149 | } 150 | } 151 | 152 | } 153 | 154 | void slugDraw(Slug* s) 155 | { 156 | int anim[4] = { 1, 0, 2, 0 }; 157 | 158 | int cropx = anim[(int)s->imageIndex] * 40; 159 | if (s->dir == -1) { 160 | cropx += 120; 161 | } 162 | 163 | PHL_DrawSurfacePart(s->x, s->y + 10, cropx, 40, 40, 40, images[imgEnemies]); 164 | } -------------------------------------------------------------------------------- /source/object.h: -------------------------------------------------------------------------------- 1 | #ifndef OBJECT_H 2 | #define OBJECT_H 3 | 4 | #include "collision.h" 5 | 6 | typedef struct { 7 | void* data; //Specific object struct 8 | void (*objectStep)(); 9 | void (*objectDraw)(); 10 | int type; 11 | } Object; 12 | 13 | void objectDestroy(int id); 14 | 15 | //Health/Ammo collectables 16 | typedef struct { 17 | int id, type; //0 for ammo, 1 for heart 18 | double x, y, 19 | vsp, grav; 20 | 21 | int blink, canLand, bounce; 22 | } Ammo; 23 | 24 | void spawnCollectable(int x, int y); 25 | void createAmmo(int x, int y, int type); 26 | 27 | //Destroyable blocks 28 | typedef struct { 29 | int id; 30 | int x, y; 31 | int hp/*, invulnerable*/; 32 | int secret; 33 | Mask mask; 34 | } Destroyable; 35 | 36 | void createDestroyable(int x, int y, int secret); 37 | 38 | //Secret Trigger 39 | typedef struct { 40 | int id, flag; 41 | int type, enemyType; 42 | } SecretTrigger; 43 | 44 | void createSecretTrigger(int type, int enemyType, int flag); 45 | 46 | //Chest 47 | typedef struct { 48 | int id; 49 | int x, y; 50 | int item, secret; 51 | int visible; 52 | int timer; 53 | 54 | Mask mask; 55 | } Chest; 56 | 57 | void createChest(int x, int y, int item, int secret); 58 | 59 | //Save point 60 | typedef struct { 61 | int id; 62 | int x, y; 63 | double imageIndex; 64 | 65 | Mask mask; 66 | } SavePoint; 67 | 68 | void createSavePoint(int x, int y, int hidden); 69 | 70 | //Door 71 | typedef struct { 72 | int id; 73 | int x, y; 74 | int open, secret, visible; 75 | 76 | int warplevel, warpcoords; 77 | int warpx, warpy; 78 | 79 | Mask mask; 80 | } Door; 81 | 82 | void createDoor(int x, int y, int level, int coords, int warpx, int warpy, int secret); 83 | 84 | //Lock Block 85 | typedef struct { 86 | int id, flag; 87 | int x, y; 88 | int tile; 89 | int invincible; 90 | } LockBlock; 91 | 92 | void createLockBlock(int x, int y, int flag); 93 | 94 | //Light Switch 95 | typedef struct { 96 | int id, flag; 97 | int x, y; 98 | int activated; 99 | double imageIndex; 100 | } Switch; 101 | 102 | void createSwitch(int x, int y, int flag); 103 | 104 | //Blue/Red Gates 105 | typedef struct { 106 | int id; 107 | int x, y; 108 | int col; 109 | int timer, open; 110 | //int invincible; 111 | double imageIndex; 112 | } Gate; 113 | 114 | void createGate(int x, int y, int col); 115 | 116 | //Statue 117 | typedef struct { 118 | int id; 119 | int x, y; 120 | int type; 121 | int invincible; 122 | int hp; 123 | } Statue; 124 | 125 | void createStatue(int x, int y, int type); 126 | 127 | //Button 128 | typedef struct { 129 | int id; 130 | int x, y; 131 | int flag; 132 | int pressed; 133 | } FloorPad; 134 | 135 | void createFloorPad(int x, int y, int flag); 136 | 137 | //Ladder 138 | typedef struct { 139 | int id; 140 | int x, y; 141 | int flag; 142 | } Ladder; 143 | 144 | void createLadder(int x, int y, int flag); 145 | 146 | //Generator 147 | typedef struct { 148 | int id; 149 | int hp; 150 | int blink; 151 | int x, y; 152 | double imageIndex; 153 | int flag; 154 | } Generator; 155 | 156 | void createGenerator(int x, int y, int flag); 157 | 158 | //Electric gate 159 | typedef struct { 160 | int id; 161 | int x, y; 162 | double imageIndex; 163 | int flag; 164 | } Shockgate; 165 | 166 | void createShockgate(int x, int y, int flag); 167 | 168 | //Ending crown 169 | typedef struct { 170 | int id; 171 | int x, ystart; 172 | double y; 173 | double bobRot; 174 | double imageIndex; 175 | int timer; 176 | char visible; 177 | } Crown; 178 | 179 | void createCrown(int x, int y); 180 | 181 | #endif -------------------------------------------------------------------------------- /source/enemies/bat.c: -------------------------------------------------------------------------------- 1 | #include "bat.h" 2 | #include "../game.h" 3 | #include "../PHL.h" 4 | #include "../hero.h" 5 | #include 6 | #include 7 | 8 | void batStep(Bat* b); 9 | void batDraw(Bat* b); 10 | 11 | void createBat(int x, int y, int type) 12 | { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* result = /*(Enemy*)*/malloc(sizeof *result); 17 | Bat* b = /*(Bat*)*/malloc(sizeof *b); 18 | b->id = i; 19 | 20 | b->x = b->xstart = x; 21 | b->y = b->ystart = y; 22 | b->type = type; 23 | 24 | b->imageIndex = 5; 25 | b->counter = 0; 26 | b->timer = 0; 27 | b->state = 0; 28 | b->dir = 1; 29 | 30 | result->data = b; 31 | result->enemyStep = batStep; 32 | result->enemyDraw = batDraw; 33 | result->type = 1; 34 | 35 | enemies[i] = result; 36 | i = MAX_ENEMIES; 37 | } 38 | } 39 | } 40 | 41 | void batStep(Bat* b) 42 | { 43 | //Wait 44 | if (b->state == 0) 45 | { 46 | //Animate 47 | { 48 | b->imageIndex = 5; 49 | } 50 | 51 | //wait for hero to get near 52 | { 53 | if (b->timer <= 0) { 54 | Mask area; 55 | area.circle = 0; 56 | area.unused = 0; 57 | area.x = b->xstart - 60; 58 | area.y = b->ystart; 59 | area.w = 160; area.h = 100; 60 | 61 | if (checkCollisionXY(area, herox, heroy + 20)) { 62 | PHL_PlaySound(sounds[sndPi07], CHN_ENEMIES); 63 | b->state = 1; 64 | b->timer = 270; 65 | if (b->type == 1) { 66 | b->counter = 1; 67 | if (herox < b->x + 20) { 68 | b->dir = -1; 69 | }else{ 70 | b->dir = 1; 71 | } 72 | } 73 | } 74 | }else{ 75 | b->timer -= 1; 76 | } 77 | } 78 | } 79 | //Fly 80 | else if (b->state == 1) 81 | { 82 | //Animate 83 | { 84 | b->imageIndex += 0.25; 85 | if (b->imageIndex >= 5) { 86 | b->imageIndex -= 5; 87 | } 88 | } 89 | 90 | //Rotation angle 91 | { 92 | b->timer += 4; 93 | if (b->timer >= 360) { 94 | b->timer -= 360; 95 | } 96 | } 97 | 98 | //Movement 99 | { 100 | b->y = b->ystart + 30 + (30 * sin(b->timer * 3.14159 / 180)); 101 | //Red bat 102 | if (b->type == 1) { 103 | b->x += 2 * b->dir; 104 | } 105 | } 106 | 107 | //Return to perch 108 | { 109 | if (b->timer == 270) { 110 | if (b->type == 1 && b->counter > 0) { 111 | b->dir *= -1; 112 | b->timer = 270; 113 | b->counter -= 1; 114 | }else{ 115 | b->state = 0; 116 | b->timer = 70; 117 | } 118 | } 119 | } 120 | } 121 | 122 | //Setup Mask 123 | Mask mask; 124 | { 125 | mask.circle = mask.unused = 0; 126 | mask.w = 32; 127 | mask.h = 28; 128 | mask.x = b->x + ((40 - mask.w) / 2); 129 | mask.y = b->y; 130 | } 131 | 132 | //Hit Player 133 | { 134 | if (checkCollision(mask, heroMask)) { 135 | heroHit(10, mask.x + (mask.w / 2)); 136 | } 137 | } 138 | 139 | //Weapon collision 140 | { 141 | int i; 142 | for (i = 0; i < MAX_WEAPONS; i++) { 143 | if (weapons[i] != NULL) { 144 | if (checkCollision(mask, weapons[i]->weaponMask)) { 145 | weaponHit(weapons[i]); 146 | //Death 147 | createEffect(2, b->x - 12, b->y - 6); 148 | spawnCollectable(b->x + 20, b->y); 149 | enemyDestroy(b->id); 150 | 151 | i = MAX_WEAPONS; 152 | } 153 | } 154 | } 155 | } 156 | 157 | } 158 | 159 | void batDraw(Bat* b) 160 | { 161 | int cropX = 0, 162 | cropY = 120; 163 | 164 | if (b->type == 1) { 165 | cropX = 400; 166 | cropY = 280; 167 | } 168 | 169 | cropX += (int)b->imageIndex * 40; 170 | 171 | PHL_DrawSurfacePart(b->x, b->y - 4, cropX, cropY, 40, 40, images[imgEnemies]); 172 | } -------------------------------------------------------------------------------- /source/enemies/podoboo.c: -------------------------------------------------------------------------------- 1 | #include "podoboo.h" 2 | #include "../PHL.h" 3 | #include "../hero.h" 4 | #include "../game.h" 5 | #include "../effect.h" 6 | #include 7 | #include 8 | 9 | void podobooStep(Podoboo* p); 10 | void podobooDraw(Podoboo* p); 11 | 12 | void createPodoboo(int x, int y, int offset, int height) 13 | { 14 | int i; 15 | for (i = 0; i < MAX_ENEMIES; i++) { 16 | if (enemies[i] == NULL) { 17 | Enemy* e = malloc(sizeof *e); 18 | Podoboo* p = malloc(sizeof *p); 19 | 20 | p->id = i; 21 | 22 | p->x = x; 23 | p->y = p->ystart = y; 24 | 25 | p->hp = 2; 26 | p->blink = 0; 27 | 28 | p->yoffset = p->rot = 0; 29 | 30 | p->vsp = 0; 31 | p->grav = 0.13; 32 | 33 | p->jumpheight = -5; 34 | /* 35 | if (height == 1) { 36 | p->jumpheight = -5.4; 37 | } 38 | */ 39 | if (height == 1) { 40 | p->jumpheight = -7; 41 | } 42 | 43 | p->imageIndex = 0; 44 | 45 | p->timer = 30 * offset; 46 | p->state = 0; 47 | 48 | e->data = p; 49 | e->enemyStep = podobooStep; 50 | e->enemyDraw = podobooDraw; 51 | e->type = 15; 52 | 53 | enemies[i] = e; 54 | i = MAX_ENEMIES; 55 | } 56 | } 57 | } 58 | 59 | void podobooStep(Podoboo* p) 60 | { 61 | //Blinking 62 | { 63 | if (p->blink > 0) { 64 | p->blink -= 1; 65 | } 66 | } 67 | 68 | p->timer -= 1; 69 | 70 | //Patterns 71 | { 72 | //Float in lava 73 | if (p->state == 0) 74 | { 75 | //Animate 76 | p->imageIndex += 0.1; 77 | if (p->imageIndex >= 2) { 78 | p->imageIndex -= 2; 79 | } 80 | 81 | //Bob movement 82 | p->rot += 5; 83 | if (p->rot >= 360) { 84 | p->rot -= 360; 85 | } 86 | p->y = p->ystart + (5 * sin(p->rot * 3.14159 / 180)); 87 | 88 | //Jump 89 | if (p->timer <= 0) { 90 | p->state = 1; 91 | createLavaSplash(p->x + 20, p->y); 92 | 93 | p->y = p->ystart; 94 | p->vsp = p->jumpheight; 95 | } 96 | } 97 | //In air 98 | else if (p->state == 1) 99 | { 100 | //Animate 101 | p->imageIndex += 0.25; 102 | if (p->imageIndex >= 3) { 103 | p->imageIndex -= 3; 104 | } 105 | 106 | //Movement 107 | p->y += p->vsp; 108 | p->vsp += p->grav; 109 | 110 | //Land in lava again 111 | if (p->vsp > 0 && p->y >= p->ystart) { 112 | createLavaSplash(p->x + 20, p->y); 113 | p->y = p->ystart; 114 | p->state = 0; 115 | p->vsp = 0; 116 | p->timer = 60; 117 | } 118 | } 119 | 120 | } 121 | 122 | //Create Mask 123 | Mask mask; 124 | { 125 | mask.unused = mask.circle = 0; 126 | mask.w = mask.h = 30; 127 | mask.x = p->x + 5; 128 | mask.y = p->y + 5; 129 | } 130 | 131 | //Collide with hero 132 | { 133 | if (checkCollision(mask, getHeroMask())) { 134 | heroHit(15, mask.x + (mask.w / 2)); 135 | } 136 | } 137 | 138 | //Weapon collision 139 | { 140 | int i; 141 | for (i = 0; i < MAX_WEAPONS; i++) { 142 | if (weapons[i] != NULL) { 143 | if (weapons[i]->cooldown == 0) { 144 | if (checkCollision(mask, weapons[i]->weaponMask)) { 145 | weaponHit(weapons[i]); 146 | p->hp -= 1; 147 | p->blink = 15; 148 | 149 | //Death 150 | if (p->hp <= 0) { 151 | createEffect(2, p->x - 12, p->y - 12); 152 | spawnCollectable(p->x + 20, p->y); 153 | enemyDestroy(p->id); 154 | } 155 | 156 | i = MAX_WEAPONS; 157 | } 158 | } 159 | } 160 | } 161 | } 162 | 163 | } 164 | 165 | void podobooDraw(Podoboo* p) 166 | { 167 | if (p->blink % 2 == 0) { 168 | int thisImage = p->imageIndex; 169 | 170 | if (p->state == 1) { 171 | thisImage += 2; 172 | } 173 | 174 | PHL_DrawSurfacePart(p->x, p->y, 280 + (40 * thisImage), 520, 40, 40, images[imgEnemies]); 175 | } 176 | } -------------------------------------------------------------------------------- /source/vita/decoder_fmmidi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of EasyRPG Player. 3 | * 4 | * EasyRPG Player is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * EasyRPG Player is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with EasyRPG Player. If not, see . 16 | */ 17 | 18 | #ifdef WANT_FMMIDI 19 | 20 | // Headers 21 | #include 22 | #include "audio_decoder.h" 23 | #include "decoder_fmmidi.h" 24 | 25 | FmMidiDecoder::FmMidiDecoder() { 26 | note_factory.reset(new midisynth::fm_note_factory()); 27 | synth.reset(new midisynth::synthesizer(note_factory.get())); 28 | seq.reset(new midisequencer::sequencer()); 29 | 30 | music_type = "midi"; 31 | 32 | load_programs(); 33 | } 34 | 35 | FmMidiDecoder::~FmMidiDecoder() { 36 | fclose(file); 37 | } 38 | 39 | bool FmMidiDecoder::Open(FILE* file) { 40 | this->file = file; 41 | 42 | seq->clear(); 43 | if (!seq->load(file)) { 44 | error_message = "FM Midi: Error reading file"; 45 | return false; 46 | } 47 | seq->rewind(); 48 | 49 | return true; 50 | } 51 | 52 | bool FmMidiDecoder::Seek(size_t offset, Origin origin) { 53 | if (offset == 0 && origin == Origin::Begin) { 54 | mtime = 0.0f; 55 | seq->rewind(); 56 | begin = true; 57 | 58 | return true; 59 | } 60 | 61 | return false; 62 | } 63 | 64 | bool FmMidiDecoder::IsFinished() const { 65 | return mtime >= seq->get_total_time(); 66 | } 67 | 68 | void FmMidiDecoder::GetFormat(int& freq, AudioDecoder::Format& format, int& channels) const { 69 | freq = frequency; 70 | format = Format::S16; 71 | channels = 2; 72 | } 73 | 74 | bool FmMidiDecoder::SetFormat(int freq, AudioDecoder::Format format, int channels) { 75 | frequency = freq; 76 | 77 | if (channels != 2 || format != Format::S16) { 78 | return false; 79 | } 80 | 81 | return true; 82 | } 83 | 84 | bool FmMidiDecoder::SetPitch(int pitch) { 85 | this->pitch = 100.0f / pitch; 86 | 87 | return true; 88 | } 89 | 90 | int FmMidiDecoder::GetTicks() const { 91 | return 0; 92 | } 93 | 94 | int FmMidiDecoder::FillBuffer(uint8_t* buffer, int length) { 95 | size_t samples = (size_t)length / sizeof(int_least16_t) / 2; 96 | 97 | float delta = (float)samples / (frequency * pitch); 98 | 99 | // FM Midi somehow returns immediately at the beginning when mtime is too small 100 | // This increments mtime until FM Midi is happy 101 | int notes = 0; 102 | do { 103 | seq->play(mtime, this); 104 | notes = synthesize(reinterpret_cast(buffer), samples, frequency); 105 | mtime += delta; 106 | } while (begin && notes == 0 && !IsFinished()); 107 | 108 | begin = false; 109 | 110 | return length; 111 | } 112 | 113 | int FmMidiDecoder::synthesize(int_least16_t * output, std::size_t samples, float rate) { 114 | return synth->synthesize(output, samples, rate); 115 | } 116 | 117 | void FmMidiDecoder::midi_message(int, uint_least32_t message) { 118 | synth->midi_event(message); 119 | } 120 | 121 | void FmMidiDecoder::sysex_message(int, const void * data, std::size_t size) { 122 | synth->sysex_message(data, size); 123 | } 124 | 125 | void FmMidiDecoder::meta_event(int, const void *, std::size_t) { 126 | // no-op 127 | } 128 | 129 | void FmMidiDecoder::reset() { 130 | synth->reset(); 131 | } 132 | 133 | void FmMidiDecoder::load_programs() { 134 | // beautiful 135 | #include "midiprogram.h" 136 | } 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /source/enemies/skull.c: -------------------------------------------------------------------------------- 1 | #include "skull.h" 2 | #include "../enemy.h" 3 | #include "../PHL.h" 4 | #include "../game.h" 5 | #include "../hero.h" 6 | #include 7 | #include 8 | 9 | void skullStep(Skull* s); 10 | void skullDraw(Skull* s); 11 | 12 | void createSkull(int x, int y) 13 | { 14 | int i; 15 | for (i = 0; i < MAX_ENEMIES; i++) { 16 | if (enemies[i] == NULL) { 17 | Enemy* e = malloc(sizeof *e); 18 | Skull* s = malloc(sizeof *s); 19 | s->id = i; 20 | 21 | //X/Y in center of sprite 22 | s->x = x + 20; 23 | s->y = y + 20; 24 | s->yoffset = 0; 25 | 26 | s->rot = 0; 27 | s->state = 0; 28 | s->timer = 0; 29 | s->imageIndex = 0; 30 | s->dir = 0; 31 | 32 | e->data = s; 33 | e->enemyStep = skullStep; 34 | e->enemyDraw = skullDraw; 35 | e->type = 12; 36 | 37 | enemies[i] = e; 38 | i = MAX_ENEMIES; 39 | } 40 | } 41 | } 42 | 43 | void skullStep(Skull* s) 44 | { 45 | double imageSpeed = 0; 46 | 47 | //Wait 48 | if (s->state == 0) 49 | { 50 | imageSpeed = 0.2; 51 | 52 | if (s->timer > 0) { 53 | s->timer -= 1; 54 | }else{ 55 | Mask tempmask; 56 | 57 | tempmask.unused = tempmask.circle = 0; 58 | tempmask.x = s->x - 100; 59 | tempmask.y = s->y - 100; 60 | tempmask.w = tempmask.h = 200; 61 | 62 | if (checkCollisionXY(tempmask, herox, heroy + 20)) { 63 | 64 | //Calculate distance 65 | //int dis = sqrt(pow(s->x - herox, 2) + pow(s->y - (heroy + 20), 2)); 66 | //if (dis <= 100) { 67 | s->state = 1; 68 | //s->dir = (rand() % 8) * 45; 69 | s->dir = (rand() % 360) + 1; 70 | PHL_PlaySound(sounds[sndPi08], CHN_ENEMIES); 71 | s->timer = 130; 72 | } 73 | } 74 | } 75 | 76 | //Chase 77 | else if (s->state == 1) 78 | { 79 | imageSpeed = 0.3; 80 | 81 | int spd = 2; 82 | s->x += (spd * cos(s->dir * 3.14159 / 180)); 83 | s->y += (spd * sin(s->dir * 3.14159 / 180)); 84 | 85 | double herodir = ((atan2((heroy + 20) - s->y, herox - s->x) * 180) / 3.14159); 86 | if (herodir >= 360) { 87 | herodir -= 360; 88 | } 89 | if (herodir < 0) { 90 | herodir += 360; 91 | } 92 | 93 | double tempdir = s->dir - herodir; 94 | if (tempdir < 0) { 95 | tempdir += 360; 96 | } 97 | 98 | if (tempdir < 180) { 99 | s->dir -= 2; 100 | }else{ 101 | s->dir += 2; 102 | } 103 | if (s->dir >= 360) { 104 | s->dir -= 360; 105 | } 106 | if (s->dir < 0) { 107 | s->dir += 360; 108 | } 109 | 110 | s->timer -= 1; 111 | if (s->timer <= 0) { 112 | s->state = 0; 113 | s->timer = 10; 114 | } 115 | } 116 | 117 | //Animate 118 | { 119 | s->imageIndex += imageSpeed; 120 | if (s->imageIndex >= 4) { 121 | s->imageIndex -= 4; 122 | } 123 | } 124 | 125 | //Hover offset 126 | { 127 | s->rot += 5; 128 | if (s->rot >= 360) { 129 | s->rot -= 360; 130 | } 131 | s->yoffset = (5 * sin(s->rot * 3.14159 / 180)); 132 | } 133 | 134 | //Setup Mask 135 | Mask mask; 136 | { 137 | mask.unused = 0; 138 | mask.circle = 1; 139 | mask.x = s->x; 140 | mask.y = s->y; 141 | mask.w = mask.h = 10; 142 | } 143 | 144 | //Hero collision 145 | { 146 | if (checkCollision(mask, getHeroMask())) { 147 | heroHit(15, mask.x); 148 | } 149 | } 150 | 151 | //Weapon collision 152 | { 153 | int i; 154 | for (i = 0; i < MAX_WEAPONS; i++) { 155 | if (weapons[i] != NULL) { 156 | if (checkCollision(mask, weapons[i]->weaponMask)) { 157 | weaponHit(weapons[i]); 158 | 159 | createEffect(2, s->x - 32, s->y - 32); 160 | spawnCollectable(s->x, s->y - 20); 161 | enemyDestroy(s->id); 162 | 163 | i = MAX_WEAPONS; 164 | } 165 | } 166 | } 167 | } 168 | 169 | } 170 | 171 | void skullDraw(Skull* s) 172 | { 173 | PHL_DrawSurfacePart(s->x - 20, s->y + s->yoffset - 20, 480 + ((int)s->imageIndex * 40), 40, 40, 40, images[imgEnemies]); 174 | } -------------------------------------------------------------------------------- /source/inventory.c: -------------------------------------------------------------------------------- 1 | #include "inventory.h" 2 | #include "PHL.h" 3 | #include "game.h" 4 | #include "text.h" 5 | 6 | int cursorX = 0; 7 | int cursorY = 0; 8 | 9 | void inventory() 10 | { 11 | char tempDark = roomDarkness; 12 | roomDarkness = 0; 13 | 14 | char loop = 1; 15 | PHL_PlaySound(sounds[sndPi04], CHN_SOUND); 16 | while (PHL_MainLoop() && loop == 1) 17 | { 18 | PHL_StartDrawing(); 19 | PHL_ScanInput(); 20 | 21 | if (inventoryStep() == 1) { 22 | loop = 0; 23 | } 24 | 25 | inventoryDraw(); 26 | 27 | PHL_EndDrawing(); 28 | } 29 | 30 | roomDarkness = tempDark; 31 | } 32 | 33 | int inventoryStep() 34 | { 35 | secretCountdown(); 36 | 37 | //Input 38 | char playsnd = 0; 39 | 40 | if (btnRight.pressed - btnLeft.pressed != 0) { 41 | cursorX += btnRight.pressed - btnLeft.pressed; 42 | playsnd = 1; 43 | } 44 | if (btnDown.pressed - btnUp.pressed != 0) { 45 | cursorY += btnDown.pressed - btnUp.pressed; 46 | playsnd = 1; 47 | } 48 | 49 | if (playsnd == 1) { 50 | PHL_PlaySound(sounds[sndPi01], CHN_SOUND); 51 | } 52 | 53 | //Limit cursor 54 | if (cursorX < 0) { cursorX = 6; } 55 | if (cursorX > 6) { cursorX = 0; } 56 | if (cursorY < 0) { cursorY = 3; } 57 | if (cursorY > 3) { cursorY = 0; } 58 | 59 | if (btnStart.pressed == 1 || btnDecline.pressed == 1) 60 | { 61 | return 1; 62 | } 63 | 64 | return 0; 65 | } 66 | 67 | void inventoryDraw() 68 | { 69 | //Black background 70 | PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0)); 71 | 72 | //Labels 73 | PHL_DrawTextBold("SUB WEAPON", 16, 16, YELLOW); 74 | PHL_DrawTextBold("ITEM", 16, 96, YELLOW); 75 | PHL_DrawTextBold("KEY", 16, 320, YELLOW); 76 | 77 | //Blue rectangles 78 | int i, a, cx, cy; 79 | //Weapons 80 | for (i = 0; i < 5; i++) { 81 | PHL_DrawRect(18 + (48 * i), 34, 44, 44, PHL_NewRGB(255, 255, 255)); 82 | PHL_DrawRect(20 + (48 * i), 36, 40, 40, PHL_NewRGB(119, 166, 219)); 83 | if (hasWeapon[i] == 1) { 84 | cx = (i + 1) * 40; 85 | }else{ 86 | cx = 0; 87 | } 88 | PHL_DrawSurfacePart(20 + (48 * i), 36, cx, 0, 40, 40, images[imgItems]); 89 | } 90 | //Items 91 | int count = 0; 92 | int imageOrder[28] = { 13, 17, 16, 15, 8, 10, 9, 93 | 18, 4, 6, 5, 7, 3, 11, 94 | 14, 12, 1, 2, 22, 26, 27, 95 | 21, 25, 28, 23, 20, 19, 24 }; 96 | 97 | for (i = 0; i < 4; i++) { 98 | for (a = 0; a < 7; a++) { 99 | PHL_DrawRect(18 + (48 * a), 114 + (48 * i), 44, 44, PHL_NewRGB(255, 255, 255)); 100 | PHL_DrawRect(20 + (48 * a), 116 + (48 * i), 40, 40, PHL_NewRGB(119, 166, 219)); 101 | 102 | if (hasItem[count] == 0) { 103 | cx = 0; 104 | cy = 0; 105 | }else{ 106 | cy = 0; 107 | cx = (imageOrder[count] + 6) * 40; 108 | while (cx >= 640) { 109 | cy += 40; 110 | cx -= 640; 111 | } 112 | } 113 | 114 | PHL_DrawSurfacePart(20 + (48 * a), 116 + (48 * i), cx, cy, 40, 40, images[imgItems]); 115 | count++; 116 | } 117 | } 118 | //Keys 119 | for (i = 0; i < 8; i++) { 120 | PHL_DrawRect(18 + (48 * i), 338, 44, 44, PHL_NewRGB(255, 255, 255)); 121 | PHL_DrawRect(20 + (48 * i), 340, 40, 40, PHL_NewRGB(119, 166, 219)); 122 | if (hasKey[i] == 1) { 123 | cx = 120 + (i * 40); 124 | cy = 80; 125 | }else{ 126 | cx = 0; 127 | cy = 0; 128 | } 129 | PHL_DrawSurfacePart(20 + (48 * i), 340, cx, cy, 40, 40, images[imgItems]); 130 | } 131 | 132 | //Text box 133 | PHL_DrawRect(16, 400, 606, 46, PHL_NewRGB(255, 255, 255)); 134 | PHL_DrawRect(18, 402, 602, 42, PHL_NewRGB(0, 0, 255)); 135 | 136 | //Text 137 | if (hasItem[cursorX + (cursorY * 7)] == 1) { 138 | int drawX = 32, drawY = 402; 139 | 140 | //Draw item name 141 | drawX = drawText(itemName[cursorX + (cursorY * 7) + 5], drawX, drawY); 142 | //Draw item description 143 | drawX = drawCharacter(6, 0, drawX, drawY); 144 | drawText(itemDescription[cursorX + (cursorY * 7)], drawX, drawY); 145 | } 146 | 147 | //Cursor 148 | PHL_DrawSurfacePart(16 + (cursorX * 48), 112 + (cursorY * 48), 0, 96, 48, 48, images[imgHud]); 149 | } -------------------------------------------------------------------------------- /source/titlescreen.c: -------------------------------------------------------------------------------- 1 | #include "titlescreen.h" 2 | #include "game.h" 3 | #include 4 | #include "text.h" 5 | 6 | int tempsave = 0; 7 | int cursor = 0; 8 | 9 | void titleScreenSetup(); 10 | 11 | int titleScreenStep(); 12 | void titleScreenDraw(); 13 | 14 | void pretitleScreen(){ 15 | char loop = 1; 16 | while (PHL_MainLoop()) 17 | { 18 | //Get input 19 | PHL_ScanInput(); 20 | 21 | //Check for button pressing 22 | if (btnAccept.pressed == 1 || btnStart.pressed == 1) { 23 | PHL_PlaySound(sounds[sndOk], 1); 24 | break; 25 | } 26 | 27 | //Draw pre-titlescreen 28 | PHL_StartDrawing(); 29 | PHL_DrawTextBoldCentered("HYDRA CASTLE LABYRINTH VITA V.1.1", 320, 30, YELLOW); 30 | PHL_DrawTextBoldCentered("BY RINNEGATAMANTE", 320, 50, YELLOW); 31 | PHL_DrawTextBoldCentered("THANKS TO ALL DISTINGUISHED PATRONERS", 320, 100, YELLOW); 32 | PHL_DrawTextBoldCentered("FOR THEIR AWESOME SUPPORT:", 320, 120, YELLOW); 33 | PHL_DrawTextBoldCentered("XANDRIDFIRE", 320, 150, WHITE); 34 | PHL_DrawTextBoldCentered("STYDE PREGNY", 320, 170, WHITE); 35 | PHL_DrawTextBoldCentered("BILLY MCLAUGHIN II", 320, 190, WHITE); 36 | PHL_DrawTextBoldCentered("CREDITS", 320, 240, YELLOW); 37 | PHL_DrawTextBoldCentered("E.HASHIMOTO FOR THE ORIGINAL GAME", 320, 270, WHITE); 38 | PHL_DrawTextBoldCentered("EASYRPG TEAM FOR THE AUDIO DECODER", 320, 290, WHITE); 39 | PHL_DrawTextBoldCentered("SWITCHBLADEFURY FOR A SCREEN BORDER", 320, 310, WHITE); 40 | PHL_DrawTextBoldCentered("BRANDONHEAT8 FOR TWO SCREEN BORDERS", 320, 330, WHITE); 41 | PHL_DrawTextBoldCentered("PRESS START TO CONTINUE", 320, 400, YELLOW); 42 | PHL_EndDrawing(); 43 | 44 | } 45 | } 46 | 47 | int titleScreen() 48 | { 49 | 50 | #ifdef _PSP2 51 | pretitleScreen(); 52 | #endif 53 | 54 | titleScreenSetup(); 55 | 56 | char loop = 1; 57 | int result = -1; 58 | 59 | while (PHL_MainLoop() && loop == 1) 60 | { 61 | //Get input 62 | PHL_ScanInput(); 63 | 64 | //Titlescreen step 65 | result = titleScreenStep(); 66 | 67 | //Draw titlescreen 68 | PHL_StartDrawing(); 69 | 70 | titleScreenDraw(); 71 | 72 | if (result != -1) { 73 | loop = 0; 74 | //Force screen to black 75 | PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0)); 76 | } 77 | 78 | PHL_EndDrawing(); 79 | } 80 | 81 | return result; 82 | } 83 | 84 | void titleScreenSetup() 85 | { 86 | cursor = 0; 87 | 88 | //Move cursor if save file exists 89 | if ( fileExists("map/018.map") ) { 90 | cursor = 1; 91 | } 92 | 93 | //Check if temp save file exists 94 | tempsave = 0; 95 | if ( fileExists("data/save.tmp") ) { 96 | tempsave = 1; 97 | cursor = 1; 98 | } 99 | } 100 | 101 | int titleScreenStep() 102 | { 103 | //Move cursor 104 | if (btnDown.pressed == 1 || btnSelect.pressed == 1) { 105 | cursor += 1; 106 | if (cursor > 2) { 107 | cursor = 0; 108 | } 109 | PHL_PlaySound(sounds[sndPi01], 1); 110 | } 111 | 112 | if (btnUp.pressed == 1) { 113 | cursor -= 1; 114 | if (cursor < 0) { 115 | cursor = 2; 116 | } 117 | PHL_PlaySound(sounds[sndPi01], 1); 118 | } 119 | 120 | //Selection 121 | if (btnAccept.pressed == 1 || btnStart.pressed == 1) { 122 | PHL_PlaySound(sounds[sndOk], 1); 123 | return cursor; 124 | } 125 | 126 | return -1; 127 | } 128 | 129 | void titleScreenDraw() 130 | { 131 | //Blackdrop 132 | PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0)); 133 | 134 | //if (tempsave == 0) { 135 | //Title image 136 | PHL_DrawSurfacePart(168, 72, 0, 0, 304, 168, images[imgTitle01]); 137 | /*}else{ 138 | //Save error message 139 | drawTextCentered(saveError[0], 320, 80); 140 | drawTextCentered(saveError[1], 320, 80 + 50); 141 | drawTextCentered(saveError[2], 320, 80 + 96); 142 | }*/ 143 | 144 | //Cursor 145 | PHL_DrawSurfacePart(228, 264 + (cursor * 32), 4, 176, 184, 32, images[imgTitle01]); 146 | 147 | //Text 148 | PHL_DrawTextBold("NEW GAME", 256, 272, YELLOW); 149 | PHL_DrawTextBold("LOAD GAME", 248, 304, YELLOW); 150 | PHL_DrawTextBold("EXIT", 288, 336, YELLOW); 151 | PHL_DrawTextBold("(C) 2011 E.HASHIMOTO", 160, 400, WHITE); 152 | } -------------------------------------------------------------------------------- /source/enemies/golem.c: -------------------------------------------------------------------------------- 1 | #include "golem.h" 2 | #include "../PHL.h" 3 | #include "../hero.h" 4 | #include "../game.h" 5 | #include 6 | 7 | void golemStep(Golem* g); 8 | void golemDraw(Golem* g); 9 | 10 | void createGolem(int x, int y, int dir) 11 | { 12 | int i; 13 | for (i = 0; i < MAX_ENEMIES; i++) { 14 | if (enemies[i] == NULL) { 15 | Enemy* e = malloc(sizeof *e); 16 | Golem* g = malloc(sizeof *g); 17 | g->id = i; 18 | 19 | g->x = x; 20 | g->y = y; 21 | 22 | g->hp = 4; 23 | 24 | g->dir = 1; 25 | if (dir == 1) { 26 | g->dir = -1; 27 | } 28 | 29 | g->imageIndex = 0; 30 | g->state = 0; 31 | g->blink = 0; 32 | 33 | e->data = g; 34 | e->enemyStep = golemStep; 35 | e->enemyDraw = golemDraw; 36 | e->type = 28; 37 | 38 | enemies[i] = e; 39 | i = MAX_ENEMIES; 40 | } 41 | } 42 | } 43 | 44 | void golemStep(Golem* g) 45 | { 46 | double imageSpeed = 0.2; 47 | 48 | //Timers 49 | { 50 | if (g->blink > 0) { 51 | g->blink -= 1; 52 | } 53 | } 54 | 55 | //Setup Mask 56 | Mask mask; 57 | { 58 | mask.unused = mask.circle = 0; 59 | mask.w = 36; 60 | mask.h = 36; 61 | mask.x = g->x + ((40 - mask.w) / 2); 62 | mask.y = g->y + (40 - mask.h); 63 | } 64 | 65 | //Rolling 66 | if (g->state == 0) 67 | { 68 | //Animate 69 | { 70 | g->imageIndex += imageSpeed * g->dir; 71 | 72 | if (g->imageIndex >= 8) { 73 | g->imageIndex -= 8; 74 | } 75 | 76 | if (g->imageIndex < 0) { 77 | g->imageIndex += 8; 78 | } 79 | } 80 | 81 | //Movement 82 | double hsp = 1; 83 | { 84 | g->x += hsp * g->dir; 85 | mask.x = g->x + ((40 - mask.w) / 2); 86 | } 87 | 88 | char nextState = 0; 89 | 90 | //Check on ledge 91 | { 92 | mask.x += 30 * g->dir; 93 | mask.y += 10; 94 | 95 | if (checkTileCollision(1, mask) == 0 && checkTileCollision(3, mask) == 0) { 96 | nextState = 1; 97 | } 98 | 99 | mask.x = g->x + ((40 - mask.w) / 2); 100 | mask.y = g->y + (40 - mask.h); 101 | } 102 | 103 | //Collide with wall 104 | { 105 | mask.x += hsp * g->dir; 106 | 107 | if (checkTileCollision(1, mask) == 1) { 108 | nextState = 1; 109 | } 110 | 111 | mask.x = g->x + ((40 - mask.w) / 2); 112 | } 113 | 114 | if (nextState == 1) { 115 | PHL_PlaySound(sounds[sndPi10], CHN_ENEMIES); 116 | g->state = 1; 117 | g->imageIndex = 0; 118 | } 119 | } 120 | 121 | //Forming 122 | else if (g->state == 1) 123 | { 124 | //Animate 125 | { 126 | g->imageIndex += imageSpeed; 127 | 128 | if (g->imageIndex >= 12) { 129 | g->imageIndex = 0; 130 | g->state = 0; 131 | g->dir *= -1; 132 | } 133 | } 134 | 135 | } 136 | 137 | //Hero Collision 138 | { 139 | if (checkCollision(mask, getHeroMask())) { 140 | heroHit(15, mask.x + (mask.w / 2)); 141 | } 142 | } 143 | 144 | //Weapon collision 145 | { 146 | int i; 147 | for (i = 0; i < MAX_WEAPONS; i++) { 148 | if (weapons[i] != NULL) { 149 | if (weapons[i]->cooldown == 0) { 150 | if (checkCollision(mask, weapons[i]->weaponMask)) { 151 | weaponHit(weapons[i]); 152 | 153 | //Tink 154 | if (g->state == 0) { 155 | PHL_PlaySound(sounds[sndHit03], CHN_WEAPONS); 156 | }else{ 157 | g->hp -= 1; 158 | g->blink = 15; 159 | } 160 | 161 | i = MAX_WEAPONS; 162 | } 163 | } 164 | } 165 | } 166 | } 167 | 168 | //Death 169 | { 170 | if (g->hp <= 0) { 171 | createRockSmash(mask.x + (mask.w / 2), mask.y + (mask.h / 2)); 172 | spawnCollectable(g->x + 20, g->y); 173 | enemyDestroy(g->id); 174 | } 175 | } 176 | } 177 | 178 | void golemDraw(Golem* g) 179 | { 180 | if (g->blink % 2 == 0) { 181 | int cropX = 320, 182 | cropY = 160; 183 | 184 | int drawY = g->y; 185 | 186 | if (g->state == 0) { 187 | cropX += (int)g->imageIndex * 40; 188 | drawY += 2; 189 | }else{ 190 | cropY = 280; 191 | cropX = 240; 192 | 193 | int animation[12] = {0, 1, 2, 3, 3, 3, 3, 3, 3, 2, 1, 0}; 194 | cropX += animation[(int)g->imageIndex] * 40; 195 | } 196 | 197 | PHL_DrawSurfacePart(g->x, drawY, cropX, cropY, 40, 40, images[imgEnemies]); 198 | } 199 | } -------------------------------------------------------------------------------- /source/enemies/jellyfish.c: -------------------------------------------------------------------------------- 1 | #include "jellyfish.h" 2 | #include "../enemy.h" 3 | #include "../game.h" 4 | #include "../hero.h" 5 | #include 6 | #include 7 | 8 | void jellyfishStep(Jellyfish* j); 9 | void jellyfishDraw(Jellyfish* j); 10 | 11 | void createJellyfish(int x, int y) 12 | { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* e = malloc(sizeof *e); 17 | Jellyfish* j = malloc(sizeof *j); 18 | j->id = i; 19 | 20 | j->x = x; 21 | j->y = j->ystart = y; 22 | j->ystart += 20; 23 | 24 | j->spd = 0; 25 | j->angle = 0; 26 | 27 | j->state = 0; 28 | j->imageIndex = 0; 29 | 30 | e->data = j; 31 | e->enemyStep = jellyfishStep; 32 | e->enemyDraw = jellyfishDraw; 33 | e->type = 20; 34 | 35 | enemies[i] = e; 36 | i = MAX_ENEMIES; 37 | } 38 | } 39 | } 40 | 41 | void jellyfishStep(Jellyfish* j) 42 | { 43 | Mask mask; 44 | mask.unused = mask.circle = 0; 45 | mask.w = mask.h = 30; 46 | mask.x = j->x + 20 - (mask.w / 2); 47 | mask.y = j->y + 20 - (mask.h / 2); 48 | 49 | //Idle float 50 | if (j->state == 0) 51 | { 52 | //Animate 53 | j->imageIndex += 0.06; 54 | if (j->imageIndex >= 4) { 55 | j->imageIndex -= 4; 56 | } 57 | 58 | //Movement 59 | j->angle += 2.5; 60 | if (j->angle >= 360) { j->angle -= 360; } 61 | j->y = j->ystart + (20 * sin(j->angle * 3.14159 / 180)); 62 | 63 | //Update mask 64 | mask.y = j->y + 20 - (mask.h / 2); 65 | 66 | //if player is close enough 67 | Mask area; 68 | area.unused = area.circle = 0; 69 | area.w = area.h = 160; 70 | area.x = j->x - 60; 71 | area.y = j->y - 60; 72 | 73 | if (checkCollision(area, getHeroMask()) == 1) { 74 | j->state = 1; 75 | j->spd = 0; 76 | } 77 | } 78 | //Attack 79 | if (j->state == 1) 80 | { 81 | //Setup 82 | if (j->spd == 0) { 83 | PHL_PlaySound(sounds[sndPi02], CHN_ENEMIES); 84 | j->spd = 3; 85 | 86 | //Move Right 87 | if (herox > j->x + 20) { 88 | //Move Up 89 | if (heroy < j->y) { 90 | j->angle = 135; 91 | } 92 | //Move Down 93 | else { 94 | j->angle = 45; 95 | } 96 | } 97 | //Move Left 98 | else{ 99 | //Move Up 100 | if (heroy < j->y) { 101 | j->angle = 225; 102 | } 103 | //Move Down 104 | else { 105 | j->angle = 315; 106 | } 107 | } 108 | } 109 | 110 | //Movement 111 | j->x += (j->spd) * sin(j->angle * 3.14159 / 180); 112 | j->y += (j->spd) * cos(j->angle * 3.14159 / 180); 113 | 114 | //Slow down 115 | j->spd -= 0.075; 116 | if (j->spd <= 0) { 117 | j->spd = 0; 118 | j->state = 2; 119 | } 120 | } 121 | //Stablize 122 | if (j->state == 2) 123 | { 124 | //Setup 125 | if (j->spd == 0) { 126 | j->spd = 1; 127 | j->ystart = j->y - 20; 128 | j->angle = 80; 129 | } 130 | 131 | //Movement 132 | j->angle += 2.5; 133 | if (j->angle >= 360) { j->angle -= 360; } 134 | j->y = j->ystart + (20 * sin(j->angle * 3.14159 / 180)); 135 | 136 | 137 | if (j->angle >= 180) { 138 | j->state = 0; 139 | j->ystart = j->y - 20; 140 | j->angle = 100; 141 | } 142 | } 143 | 144 | //Update Mask 145 | mask.x = j->x + 20 - (mask.w / 2); 146 | mask.y = j->y + 20 - (mask.h / 2); 147 | 148 | //Collide with hero 149 | if (checkCollision(mask, getHeroMask())) { 150 | heroHit(15, j->x + 20); 151 | } 152 | 153 | //Sword collision 154 | int i; 155 | for (i = 0; i < MAX_WEAPONS; i++) { 156 | if (weapons[i] != NULL) { 157 | if (checkCollision(mask, weapons[i]->weaponMask)) { 158 | spawnCollectable(j->x + 20, j->y); 159 | weaponHit(weapons[i]); 160 | 161 | createEffect(2, j->x - 12, j->y - 12); 162 | enemyDestroy(j->id); 163 | 164 | i = MAX_WEAPONS; 165 | } 166 | } 167 | } 168 | } 169 | 170 | void jellyfishDraw(Jellyfish* j) 171 | { 172 | int frame = 0; 173 | 174 | //if (j->state == 0) { 175 | int animation[4] = { 0, 1, 0, 2}; 176 | frame = animation[(int)j->imageIndex]; 177 | //} 178 | 179 | if (j->state == 1) { 180 | if (j->angle == 135) { 181 | frame = 3; 182 | } 183 | else if (j->angle == 225) { 184 | frame = 4; 185 | } 186 | else if (j->angle == 315) { 187 | frame = 5; 188 | } 189 | else { 190 | frame = 6; 191 | } 192 | } 193 | 194 | PHL_DrawSurfacePart(j->x, j->y, frame * 40, 520, 40, 40, images[imgEnemies]); 195 | } -------------------------------------------------------------------------------- /source/enemies/bee.c: -------------------------------------------------------------------------------- 1 | #include "bee.h" 2 | #include "../enemy.h" 3 | #include "../game.h" 4 | #include "../hero.h" 5 | #include 6 | #include 7 | 8 | void beeStep(Bee* b); 9 | void beeDraw(Bee* b); 10 | 11 | void createBee(int x, int y, int dir) 12 | { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* e = /*(Enemy*)*/malloc(sizeof *e); 17 | Bee* b = /*(Bee*)*/malloc(sizeof *b); 18 | b->id = i; 19 | 20 | b->x = x; 21 | b->y = y; 22 | b->xstart = b->x; 23 | b->ystart = b->y; 24 | 25 | b->hsp = 0; 26 | b->vsp = 0; 27 | 28 | b->timer = 0; 29 | b->imageIndex = 0; 30 | b->dir = 1; 31 | b->state = 0; 32 | 33 | b->hoverdir = 180; 34 | 35 | if (dir == 1) { 36 | b->hoverdir = 0; 37 | b->dir = -1; 38 | } 39 | 40 | e->data = b; 41 | e->enemyStep = beeStep; 42 | e->enemyDraw = beeDraw; 43 | e->type = 24; 44 | 45 | enemies[i] = e; 46 | i = MAX_ENEMIES; 47 | } 48 | } 49 | } 50 | 51 | void beeStep(Bee* b) 52 | { 53 | //Animate 54 | { 55 | b->imageIndex += 0.33; 56 | if (b->imageIndex >= 3) { 57 | b->imageIndex -= 3; 58 | } 59 | } 60 | 61 | //Mindless hovering 62 | if (b->state == 0) 63 | { 64 | b->hoverdir += 2.6; 65 | if (b->hoverdir >= 360) { 66 | b->hoverdir -= 360; 67 | } 68 | 69 | b->dir = 1; 70 | if (b->hoverdir <= 180) { 71 | b->dir = -1; 72 | } 73 | 74 | b->x = b->xstart + (20 * cos(b->hoverdir * 3.14159 /180)); 75 | 76 | //If player is within range 77 | Mask area; 78 | area.unused = area.circle = 0; 79 | area.x = b->x - 80; 80 | area.y = b->y; 81 | area.w = 200; 82 | area.h = 100; 83 | 84 | if (checkCollision(area, getHeroMask())) { 85 | b->state = 1; 86 | 87 | b->dir = 1; 88 | if (b->x + 20 > herox) { 89 | b->dir = -1; 90 | } 91 | 92 | b->hsp = -5.5 * b->dir; 93 | 94 | PHL_PlaySound(sounds[sndBee01], CHN_ENEMIES); 95 | } 96 | } 97 | //Fly backwards 98 | else if (b->state == 1) 99 | { 100 | b->hsp += 0.25 * b->dir; 101 | 102 | if ((b->dir == 1 && b->hsp >= 0) || (b->dir == -1 && b->hsp <= 0)) { 103 | b->hsp = 0; 104 | b->state = 2; 105 | b->vsp = 3.75; 106 | } 107 | } 108 | //Fly downwards 109 | else if (b->state == 2) 110 | { 111 | b->vsp -= 0.1; 112 | if (b->vsp <= 0) { 113 | b->state = 3; 114 | b->vsp = 0; 115 | 116 | b->dir = 1; 117 | if (b->x + 20 > herox) { 118 | b->dir = -1; 119 | } 120 | b->hsp = 3 * b->dir; 121 | } 122 | } 123 | //Fly diaganal 124 | else if (b->state == 3) 125 | { 126 | b->vsp -= 0.1; 127 | 128 | if (b->vsp < -3) { 129 | b->vsp = -3; 130 | } 131 | 132 | if (b->y <= b->ystart) { 133 | b->state = 4; 134 | 135 | b->vsp = 0; 136 | b->y = b->ystart; 137 | 138 | if (b->x < b->xstart) { 139 | b->dir = 1; 140 | }else{ 141 | b->dir = -1; 142 | } 143 | b->hsp = b->dir; 144 | } 145 | } 146 | //Fly back to start 147 | else if (b->state == 4) 148 | { 149 | if ((b->dir == 1 && b->x >= b->xstart) || (b->dir == -1 && b->x <= b->xstart)) { 150 | b->state = 0; 151 | b->hsp = 0; 152 | 153 | b->hoverdir = 0; 154 | } 155 | } 156 | 157 | //Movement 158 | { 159 | b->x += b->hsp; 160 | b->y += b->vsp; 161 | } 162 | 163 | //Setup Mask 164 | Mask mask; 165 | { 166 | mask.circle = mask.unused = 0; 167 | mask.w = 24; 168 | mask.h = 32; 169 | mask.y = b->y + 6; 170 | mask.x = b->x + 14; 171 | if (b->dir == -1) { 172 | mask.x = b->x + 2; 173 | } 174 | } 175 | 176 | //Hit Player 177 | { 178 | if (checkCollision(mask, getHeroMask())) { 179 | heroHit(15, mask.x + (mask.w / 2)); 180 | } 181 | } 182 | 183 | //Weapon Collision 184 | { 185 | int i; 186 | for (i = 0; i < MAX_WEAPONS; i++) { 187 | if (weapons[i] != NULL) { 188 | if (checkCollision(mask, weapons[i]->weaponMask)) { 189 | weaponHit(weapons[i]); 190 | 191 | createEffect(2, b->x - 12, b->y - 6); 192 | spawnCollectable(b->x + 20, b->y); 193 | enemyDestroy(b->id); 194 | 195 | i = MAX_WEAPONS; 196 | } 197 | } 198 | } 199 | } 200 | 201 | } 202 | 203 | void beeDraw(Bee* b) 204 | { 205 | int cropx = 280; 206 | 207 | if (b->dir == -1) { 208 | cropx += 120; 209 | } 210 | 211 | cropx += (int)b->imageIndex * 40; 212 | 213 | PHL_DrawSurfacePart(b->x, b->y, cropx, 480, 40, 40, images[imgEnemies]); 214 | } -------------------------------------------------------------------------------- /source/enemies/seal.c: -------------------------------------------------------------------------------- 1 | #include "seal.h" 2 | #include "../game.h" 3 | #include "../enemy.h" 4 | #include "../collision.h" 5 | #include "../hero.h" 6 | #include 7 | 8 | void sealStep(Seal* s); 9 | void sealDraw(Seal* s); 10 | 11 | void createSeal(int x, int y) 12 | { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* e = malloc(sizeof *e); 17 | Seal* s = malloc(sizeof *s); 18 | s->id = i; 19 | s->hp = 2; 20 | 21 | s->x = x; 22 | s->y = y; 23 | 24 | s->imageIndex = 0; 25 | 26 | s->dir = 1; 27 | if (x + 20 > herox) { 28 | s->dir = -1; 29 | } 30 | 31 | s->state = 0; 32 | s->timer = 0; 33 | 34 | s->invincible = 0; 35 | 36 | e->data = s; 37 | e->enemyStep = sealStep; 38 | e->enemyDraw = sealDraw; 39 | e->type = 19; 40 | 41 | enemies[i] = e; 42 | i = MAX_ENEMIES; 43 | } 44 | } 45 | } 46 | 47 | void sealStep(Seal* s) 48 | { 49 | if (s->invincible > 0) { 50 | s->invincible -= 1; 51 | } 52 | 53 | Mask mask; 54 | mask.unused = mask.circle = 0; 55 | mask.w = mask.h = 28; 56 | mask.x = s->x + ((40 - mask.w) / 2); 57 | mask.y = s->y + (40 - mask.h); 58 | 59 | //Walk 60 | if (s->state == 0) 61 | { 62 | //Animate 63 | s->imageIndex += 0.1; 64 | if (s->imageIndex >= 2) { 65 | s->imageIndex -= 2; 66 | } 67 | 68 | //Check if hit a wall 69 | if (checkTileCollision(1, mask) == 1) { 70 | s->dir *= -1; 71 | }else{ 72 | //Check if on edge 73 | mask.x += mask.w * s->dir; 74 | mask.y += mask.h; 75 | 76 | PHL_Rect collide = getTileCollision(1, mask); 77 | if (collide.x == -1) { 78 | collide = getTileCollision(3, mask); 79 | } 80 | if (collide.x == -1) { 81 | s->dir *= -1; 82 | } 83 | 84 | mask.x = s->x + ((40 - mask.w) / 2); 85 | mask.y = s->y + (40 - mask.h); 86 | } 87 | 88 | //Movement 89 | s->x += 0.5 * s->dir; 90 | 91 | if (s->timer <= 0) { 92 | //Check if player is close enough 93 | Mask area; 94 | area.unused = area.circle = 0; 95 | area.x = s->x - 40; 96 | area.y = s->y; 97 | area.w = 120; 98 | area.h = 120; 99 | 100 | if (checkCollision(area, getHeroMask()) == 1) { 101 | s->state = 1; 102 | s->timer = -1; 103 | } 104 | }else{ 105 | s->timer -= 1; 106 | } 107 | } 108 | 109 | //Rear back 110 | else if (s->state == 1) 111 | { 112 | //Setup 113 | if (s->timer == -1) { 114 | s->imageIndex = 4; 115 | s->timer = 20; 116 | } 117 | 118 | s->timer -= 1; 119 | 120 | if (s->timer <= 0) { 121 | s->state = 2; 122 | s->timer = -1; 123 | s->imageIndex = 0; 124 | } 125 | } 126 | 127 | //Tounge attack 128 | else if (s->state == 2) 129 | { 130 | //Setup 131 | if (s->timer == -1) { 132 | s->timer = 0; 133 | PHL_PlaySound(sounds[sndGet01], CHN_ENEMIES); 134 | } 135 | 136 | //Animate 137 | int animation[41] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 138 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 139 | 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 140 | 2, 2, 1, 1, 0, 0, 5, 5, 5, 5, 5 }; 141 | 142 | s->imageIndex = animation[(int)s->timer]; 143 | 144 | //Update mask height to fit tounge 145 | int len[6] = { 18, 38, 58, 64, 66, 0}; 146 | mask.h += len[(int)s->imageIndex]; 147 | 148 | s->timer += 1; 149 | 150 | if (s->timer >= 41) { 151 | s->state = 0; 152 | s->timer = 120; 153 | s->imageIndex = 0; 154 | } 155 | } 156 | 157 | //Hit Player 158 | if (checkCollision(mask, getHeroMask())) { 159 | heroHit(10, s->x + 20); 160 | } 161 | 162 | int i; 163 | for (i = 0; i < MAX_WEAPONS; i++) { 164 | if (weapons[i] != NULL) { 165 | if (weapons[i]->cooldown == 0) { 166 | if (checkCollision(mask, weapons[i]->weaponMask)) { 167 | s->hp -= 1; 168 | s->invincible = 15; 169 | weaponHit(weapons[i]); 170 | if (s->hp <= 0) { 171 | enemyDestroy(s->id); 172 | createEffect(2, s->x - 12, s->y - 6); 173 | spawnCollectable(s->x + 20, s->y); 174 | } 175 | i = MAX_WEAPONS; 176 | } 177 | } 178 | } 179 | } 180 | } 181 | 182 | void sealDraw(Seal* s) 183 | { 184 | if (s->invincible % 2 == 0) { 185 | int cx = 400 + ((int)s->imageIndex * 40); 186 | 187 | if (s->state == 0) { 188 | if (s->dir == -1) { 189 | cx += 80; 190 | } 191 | } 192 | 193 | if (s->state == 2) { 194 | cx = 600; 195 | } 196 | 197 | PHL_DrawSurfacePart(s->x, s->y, cx, 200, 40, 40, images[imgEnemies]); 198 | 199 | //Draw tounge 200 | if (s->state == 2) { 201 | PHL_DrawSurfacePart(s->x, s->y + 28, 200 + ((int)s->imageIndex * 40), 0, 40, 80, images[imgMisc2040]); 202 | } 203 | } 204 | } -------------------------------------------------------------------------------- /source/stagedata.c: -------------------------------------------------------------------------------- 1 | #include "stagedata.h" 2 | 3 | int stage[9][96] = { 4 | //Overworld 5 | { -1, -1, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, 6 | -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, 7 | -1, -1, 36, 37, 38, 39, 40, 41, 42, 43, -1, -1, 8 | -1, -1, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, 9 | -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, -1, -1, 10 | -1, -1, 60, 61, 62, 63, 64, 65, 66, 67, -1, -1, 11 | -1, -1, 68, 69, 70, 71, 72, 73, 74, 75, -1, -1, 12 | -1, -1, 76, 77, 78, 79, 80, 81, 82, 83, -1, -1 }, 13 | 14 | //Level 1 15 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17 | -1, -1, -1, 84, 85, 86, -1, -1, -1, -1, -1, -1, 18 | -1, -1, -1, -1, 87, 88, 89, 90, -1, -1, -1, -1, 19 | -1, -1, -1, -1, -1, -1, 91, 92, 93, 94, -1, -1, 20 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 23 | 24 | //Level 2 25 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27 | -1, -1, -1, 95, -1, -1, -1, 96, -1, -1, -1, -1, 28 | -1, -1, -1, 97, 98, 99, 100, 101, -1, -1, -1, -1, 29 | -1, -1, -1, 102, 103, 104, 105, 106, -1, -1, -1, -1, 30 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 32 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 33 | 34 | //Level 3 35 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37 | -1, -1, 108, -1, 109, 110, 111, -1, 112, -1, -1, -1, 38 | -1, -1, 113, 114, 115, 107, 116, 117, 118, -1, -1, -1, 39 | -1, -1, -1, -1, 119, 120, 121, -1, -1, -1, -1, -1, 40 | -1, -1, -1, -1, -1, 122, -1, -1, -1, -1, -1, -1, 41 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 42 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 43 | 44 | //Level 4 45 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 47 | -1, -1, -1, -1, 129, 130, 131, 132, -1, 135, 136, -1, 48 | -1, -1, 123, 124, 125, 126, 127, 128, 133, 134, -1, -1, 49 | -1, -1, 137, 138, -1, -1, -1, -1, -1, -1, -1, -1, 50 | -1, -1, -1, 139, -1, -1, -1, -1, -1, -1, -1, -1, 51 | -1, -1, -1, 140, -1, -1, -1, -1, -1, -1, -1, -1, 52 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 53 | 54 | //Level 5 55 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56 | -1, -1, -1, 159, -1, 162, -1, -1, -1, -1, -1, -1, 57 | -1, -1, 158, 160, 161, 163, 164, -1, -1, -1, -1, -1, 58 | -1, -1, -1, 165, 166, 167, -1, -1, -1, -1, -1, -1, 59 | -1, -1, 168, 169, 170, 171, 172, -1, -1, -1, -1, -1, 60 | -1, -1, -1, 173, -1, 174, -1, -1, -1, -1, -1, -1, 61 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 63 | 64 | //Level 6 65 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67 | -1, -1, -1, -1, -1, -1, -1, 156, 157, -1, -1, -1, 68 | -1, -1, -1, -1, 149, 150, 154, 155, -1, -1, -1, -1, 69 | -1, -1, 151, -1, 152, 153, -1, -1, -1, -1, -1, -1, 70 | -1, -1, 141, 142, 143, 144, 145, 146, -1, -1, -1, -1, 71 | -1, -1, -1, -1, -1, 147, 148, -1, -1, -1, -1, -1, 72 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 73 | 74 | //Level 7 75 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 76 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 77 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 78 | -1, -1, -1, 188, 189, 190, 191, -1, -1, -1, -1, -1, 79 | -1, -1, -1, 182, 183, 184, 185, -1, -1, -1, -1, -1, 80 | -1, 186, 175, 176, 177, 178, 179, 180, 181, -1, -1, -1, 81 | -1, 187, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 83 | 84 | //Level 8 85 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 86 | -1, -1, -1, -1, -1, 192, -1, -1, -1, -1, -1, -1, 87 | -1, -1, -1, 195, 194, 193, 198, 199, -1, -1, -1, -1, 88 | -1, -1, -1, 196, 197, 202, 201, 200, -1, -1, -1, -1, 89 | -1, -1, -1, 205, 204, 203, 208, 209, -1, -1, -1, -1, 90 | -1, -1, -1, 206, 207, 212, 211, 210, -1, -1, -1, -1, 91 | -1, -1, -1, -1, -1, 213, -1, -1, -1, -1, -1, -1, 92 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, } 93 | }; -------------------------------------------------------------------------------- /source/text.c: -------------------------------------------------------------------------------- 1 | #include "text.h" 2 | #include 3 | #include 4 | #include 5 | #include "PHL.h" 6 | #include "game.h" 7 | 8 | #ifdef _PSP2 9 | extern uint8_t use_uma0; 10 | #endif 11 | 12 | void loadMessage(Message* m, FILE* f); 13 | void trimMessage(Message* m); 14 | 15 | void textInit() 16 | { 17 | gameLanguage = JAPANESE; 18 | 19 | saving = (Message*)malloc(sizeof(Message)); 20 | 21 | int i; 22 | for (i = 0; i < 3; i++) { 23 | saveError[i] = (Message*)malloc(sizeof(Message)); 24 | } 25 | 26 | for (i = 0; i < 8; i++) { 27 | dungeon[i] = (Message*)malloc(sizeof(Message)); 28 | } 29 | 30 | for (i = 0; i < 41; i++) { 31 | itemName[i] = (Message*)malloc(sizeof(Message)); 32 | } 33 | 34 | found = (Message*)malloc(sizeof(Message)); 35 | 36 | for (i = 0; i < 28; i++) { 37 | itemDescription[i] = (Message*)malloc(sizeof(Message)); 38 | } 39 | 40 | //printf("\nText init"); 41 | } 42 | 43 | void textFree() 44 | { 45 | free(saving); 46 | 47 | int i; 48 | for (i = 0; i < 3; i++) { 49 | free(saveError[i]); 50 | } 51 | 52 | for (i = 0; i < 8; i++) { 53 | free(dungeon[i]); 54 | } 55 | 56 | for (i = 0; i < 41; i++) { 57 | free(itemName[i]); 58 | } 59 | 60 | free(found); 61 | 62 | for (i = 0; i < 28; i++) { 63 | free(itemDescription[i]); 64 | } 65 | } 66 | 67 | void loadText() 68 | { 69 | FILE* f; 70 | 71 | char fullPath[30]; 72 | #ifdef _3DS 73 | strcpy(fullPath, "romfs:/"); 74 | #else 75 | #ifdef _PSP2 76 | sprintf(fullPath, "%s:data/HCL/%s", use_uma0 ? "uma0" : "ux0", (gameLanguage == ENGLISH) ? "en.dat" : ((gameLanguage==SPANISH)?"es.dat":"jp.dat")); 77 | #else 78 | strcpy(fullPath, "romfs/"); 79 | #endif 80 | 81 | #endif 82 | 83 | #ifndef _PSP2 84 | if (gameLanguage == ENGLISH) { 85 | strcat(fullPath, "en.dat"); 86 | } else if (gameLanguage == SPANISH) { 87 | strcat(fullPath, "es.dat"); 88 | } else{ 89 | strcat(fullPath, "jp.dat"); 90 | } 91 | #endif 92 | 93 | //printf("\n"); 94 | //printf(fullPath); 95 | 96 | if ( (f = fopen(fullPath, "rb")) ) 97 | { 98 | //printf("\ntext.dat found"); 99 | 100 | //Load saving message 101 | loadMessage(saving, f); 102 | 103 | printf("\n%d", saving->length); 104 | 105 | //Load save error message 106 | int i; 107 | for (i = 0; i < 3; i++) { 108 | loadMessage(saveError[i], f); 109 | } 110 | 111 | //Load dungeon intros 112 | for (i = 0; i < 8; i++) { 113 | loadMessage(dungeon[i], f); 114 | } 115 | 116 | //Load item names 117 | for (i = 0; i < 41; i++) { 118 | loadMessage(itemName[i], f); 119 | } 120 | 121 | //Found! 122 | loadMessage(found, f); 123 | 124 | //Load item descriptions 125 | for (i = 0; i < 28; i++) { 126 | loadMessage(itemDescription[i], f); 127 | } 128 | 129 | }else{ 130 | //printf("\ntext.dat was not found"); 131 | } 132 | 133 | fclose(f); 134 | } 135 | 136 | //Returns the next character X position 137 | int drawText(Message* m, int x, int y) 138 | { 139 | int textw = 20; 140 | int texth = 32; 141 | 142 | int dx = x; 143 | 144 | int i; 145 | for (i = 0; i < m->length; i++) { 146 | PHL_DrawSurfacePart(dx, y, m->x[i] * textw, m->y[i] * texth, textw, texth, images[imgFontKana]); 147 | dx += textw - 2; 148 | } 149 | 150 | return dx; 151 | } 152 | 153 | int drawCharacter(int cx, int cy, int x, int y) 154 | { 155 | int textw = 20; 156 | int texth = 32; 157 | 158 | PHL_DrawSurfacePart(x, y, cx * textw, cy * texth, textw, texth, images[imgFontKana]); 159 | 160 | return x + textw - 2; 161 | } 162 | 163 | void drawTextCentered(Message* m, int x, int y) 164 | { 165 | int textw = 20; 166 | int texth = 32; 167 | 168 | x -= (m->length / 2) * (textw - 2); 169 | 170 | int i; 171 | for (i = 0; i < m->length; i++) { 172 | PHL_DrawSurfacePart(x + (i * (textw - 2)), y, m->x[i] * textw, m->y[i] * texth, textw, texth, images[imgFontKana]); 173 | } 174 | } 175 | 176 | void setLanguage(char lan) 177 | { 178 | gameLanguage = lan; 179 | loadText(); 180 | } 181 | 182 | char getLanguage() 183 | { 184 | return gameLanguage; 185 | } 186 | 187 | void loadMessage(Message* m, FILE* f) 188 | { 189 | unsigned char* buffer = (unsigned char*)malloc(sizeof(unsigned char) * 64); 190 | 191 | fread(buffer, 1, 64, f); 192 | 193 | int i; 194 | for (i = 0; i < 64; i+=2) { 195 | m->x[i/2] = buffer[i]; 196 | m->y[i/2] = buffer[i+1]; 197 | } 198 | trimMessage(m); 199 | 200 | free(buffer); 201 | } 202 | 203 | void trimMessage(Message* m) 204 | { 205 | m->length = 32; 206 | 207 | int i; 208 | for (i = 31; i >= 0; i--) 209 | { 210 | if (m->x[i] == 0 && m->y[i] == 0) { 211 | m->length -= 1; 212 | }else{ 213 | i = -1; 214 | } 215 | } 216 | } -------------------------------------------------------------------------------- /source/vita/decoder_wav.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of EasyRPG Player. 3 | * 4 | * EasyRPG Player is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * EasyRPG Player is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with EasyRPG Player. If not, see . 16 | */ 17 | 18 | #ifdef WANT_FASTWAV 19 | 20 | // Headers 21 | #include 22 | #include "decoder_wav.h" 23 | #include "utils.h" 24 | 25 | WavDecoder::WavDecoder() 26 | { 27 | music_type = "wav"; 28 | } 29 | 30 | WavDecoder::~WavDecoder() { 31 | if (file_ != NULL) { 32 | fclose(file_); 33 | } 34 | } 35 | 36 | bool WavDecoder::Open(FILE* file) { 37 | file_=file; 38 | fseek(file_, 16, SEEK_SET); 39 | fread(&chunk_size, 1, 4, file_); 40 | Utils::SwapByteOrder(chunk_size); 41 | fseek(file_, 2, SEEK_CUR); 42 | fread(&nchannels, 1, 2, file_); 43 | Utils::SwapByteOrder(nchannels); 44 | fread(&samplerate, 1, 4, file_); 45 | Utils::SwapByteOrder(samplerate); 46 | fseek(file_, 6, SEEK_CUR); 47 | uint16_t bitspersample; 48 | fread(&bitspersample, 1, 2, file_); 49 | Utils::SwapByteOrder(bitspersample); 50 | switch (bitspersample) { 51 | case 8: 52 | output_format=Format::U8; 53 | break; 54 | case 16: 55 | output_format=Format::S16; 56 | break; 57 | case 32: 58 | output_format=Format::S32; 59 | break; 60 | default: 61 | return false; 62 | } 63 | 64 | // Skip to next chunk using "fmt" chunk as offset 65 | fseek(file_, 12 + 8 + chunk_size, SEEK_SET); 66 | 67 | char chunk_name[4] = {0}; 68 | fread(chunk_name, 4, 1, file_); 69 | 70 | // Skipping to audiobuffer start 71 | while (strncmp(chunk_name, "data", 4)) { 72 | fread(&chunk_size, 1, 4, file_); 73 | Utils::SwapByteOrder(chunk_size); 74 | fseek(file_, chunk_size, SEEK_CUR); 75 | fread(chunk_name, 4, 1, file_); 76 | 77 | if (feof(file_) || ferror(file_)) { 78 | fclose(file_); 79 | return false; 80 | } 81 | } 82 | 83 | // Get data chunk size 84 | fread(&chunk_size, 4, 1, file_); 85 | Utils::SwapByteOrder(chunk_size); 86 | 87 | if (feof(file_) || ferror(file_)) { 88 | fclose(file_); 89 | return false; 90 | } 91 | 92 | // Start of data chunk 93 | audiobuf_offset = ftell(file_); 94 | cur_pos = audiobuf_offset; 95 | finished = false; 96 | return file_!=NULL; 97 | } 98 | 99 | bool WavDecoder::Seek(size_t offset, Origin origin) { 100 | finished = false; 101 | if (file_ == NULL) 102 | return false; 103 | if (origin != Origin::End) { 104 | offset += audiobuf_offset; 105 | } 106 | 107 | bool success = fseek(file_,offset,(int)origin) == 0; 108 | cur_pos = ftell(file_); 109 | return success; 110 | } 111 | 112 | bool WavDecoder::IsFinished() const { 113 | return finished; 114 | } 115 | 116 | 117 | void WavDecoder::GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const { 118 | if (file_ == NULL) return; 119 | frequency = samplerate; 120 | channels = nchannels; 121 | format = output_format; 122 | } 123 | 124 | bool WavDecoder::SetFormat(int, AudioDecoder::Format, int) { 125 | return false; 126 | } 127 | 128 | int WavDecoder::FillBuffer(uint8_t* buffer, int length) { 129 | if (file_ == NULL) 130 | return -1; 131 | 132 | int real_length; 133 | 134 | // Handle case that another chunk is behind "data" or file ended 135 | if (cur_pos + length >= audiobuf_offset + chunk_size) { 136 | real_length = audiobuf_offset + chunk_size - cur_pos; 137 | cur_pos = audiobuf_offset + chunk_size; 138 | } else { 139 | real_length = length; 140 | cur_pos += length; 141 | } 142 | 143 | if (real_length == 0) { 144 | finished = true; 145 | return 0; 146 | } 147 | 148 | int decoded = fread(buffer, 1, real_length, file_); 149 | 150 | if (Utils::IsBigEndian()) { 151 | if (output_format == AudioDecoder::Format::S16) { 152 | uint16_t* buffer_16 = reinterpret_cast(buffer); 153 | for (int i = 0; i < decoded / 2; ++i) { 154 | Utils::SwapByteOrder(buffer_16[i]); 155 | } 156 | } else if (output_format == AudioDecoder::Format::S32) { 157 | uint32_t* buffer_32 = reinterpret_cast(buffer); 158 | for (int i = 0; i < decoded / 4; ++i) { 159 | Utils::SwapByteOrder(buffer_32[i]); 160 | } 161 | } 162 | } 163 | 164 | if (decoded < length) 165 | finished = true; 166 | 167 | return decoded; 168 | } 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /source/wii/input.c: -------------------------------------------------------------------------------- 1 | //Wii 2 | #include "input.h" 3 | #include 4 | #include 5 | 6 | double deadZone = 0.5; 7 | 8 | void updateKey(Button* btn, int state); 9 | 10 | void PHL_ScanInput() 11 | { 12 | //btnStartPrev = btnStart; 13 | 14 | WPAD_ScanPads(); 15 | //PAD_ScanPads(); 16 | 17 | u32 pressed = WPAD_ButtonsHeld(0); 18 | //u32 gPressed = PAD_ButtonsHeld(0); 19 | 20 | int pUp = 0, pDown = 0, pLeft = 0, pRight = 0; 21 | int pFaceLeft = 0, pFaceRight = 0, /*pFaceUp = 0,*/ pFaceDown = 0; 22 | int pL = 0, pR = 0; 23 | int pSelect = 0, pStart = 0; 24 | int pAccept = 0, pDecline = 0; 25 | 26 | //if (pressed & WPAD_BUTTON_RIGHT || pressed & WPAD_CLASSIC_BUTTON_UP || gPressed & PAD_BUTTON_RIGHT) { pUp = 1; } 27 | WPADData* cData = WPAD_Data(0); 28 | 29 | if (cData->exp.type == WPAD_EXP_NONE) 30 | { //Normal Wiimote*/ 31 | pUp = pressed & WPAD_BUTTON_RIGHT; 32 | pDown = pressed & WPAD_BUTTON_LEFT; 33 | pLeft = pressed & WPAD_BUTTON_UP; 34 | pRight = pressed & WPAD_BUTTON_DOWN; 35 | 36 | pSelect = pressed & WPAD_BUTTON_MINUS; 37 | pStart = pressed & WPAD_BUTTON_PLUS; 38 | 39 | pR = pressed & WPAD_BUTTON_A; 40 | 41 | pFaceLeft = pressed & WPAD_BUTTON_1; 42 | pFaceDown = pressed & WPAD_BUTTON_2; 43 | pFaceRight = pressed & WPAD_BUTTON_B; 44 | 45 | pAccept = pFaceDown; 46 | pDecline = pFaceLeft; 47 | }else if (cData->exp.type == WPAD_EXP_CLASSIC) 48 | { //Classic Controller 49 | //Get x and y axis from the joystick 50 | //Taken from the Wii SDL source 51 | float mag = 0.0, 52 | ang = 0.0; 53 | 54 | mag = cData->exp.classic.ljs.mag; 55 | ang = cData->exp.classic.ljs.ang; 56 | 57 | double xAxis = mag * sin((3.14159 * ang)/180.0f); 58 | double yAxis = mag * cos((3.14159 * ang)/180.0f); 59 | 60 | if (yAxis < -deadZone || pressed & WPAD_CLASSIC_BUTTON_DOWN) { pDown = 1; } 61 | if (yAxis > deadZone || pressed & WPAD_CLASSIC_BUTTON_UP) { pUp = 1; } 62 | if (xAxis < -deadZone || pressed & WPAD_CLASSIC_BUTTON_LEFT) { pLeft = 1; } 63 | if (xAxis > deadZone || pressed & WPAD_CLASSIC_BUTTON_RIGHT) { pRight = 1; } 64 | 65 | if (pUp == 1 && pDown == 1) { 66 | pUp = 0; 67 | pDown = 0; 68 | } 69 | if (pLeft == 1 && pRight == 1) { 70 | pLeft = 0; 71 | pRight = 0; 72 | } 73 | 74 | pSelect = pressed & WPAD_CLASSIC_BUTTON_MINUS; 75 | pStart = pressed & WPAD_CLASSIC_BUTTON_PLUS; 76 | 77 | pL = pressed & WPAD_CLASSIC_BUTTON_FULL_L; 78 | pR = pressed & WPAD_CLASSIC_BUTTON_FULL_R; 79 | 80 | pFaceLeft = pressed & WPAD_CLASSIC_BUTTON_Y; 81 | pFaceDown = pressed & WPAD_CLASSIC_BUTTON_B; 82 | pFaceRight = pressed & WPAD_CLASSIC_BUTTON_A; 83 | 84 | pAccept = pFaceRight; 85 | pDecline = pFaceDown; 86 | } 87 | 88 | //Gamecube Controller 89 | { 90 | PAD_ScanPads(); 91 | pressed = PAD_ButtonsHeld(0); 92 | 93 | double xAxis = PAD_StickX(0) / 25; 94 | double yAxis = PAD_StickY(0) / 25; 95 | 96 | if (pressed & PAD_BUTTON_UP || yAxis > deadZone) { pUp = 1; } 97 | if (pressed & PAD_BUTTON_DOWN || yAxis < -deadZone) { pDown = 1; } 98 | if (pressed & PAD_BUTTON_LEFT || xAxis < -deadZone) { pLeft = 1; } 99 | if (pressed & PAD_BUTTON_RIGHT || xAxis > deadZone) { pRight = 1; } 100 | 101 | if (pUp == 1 && pDown == 1) { 102 | pUp = 0; 103 | pDown = 0; 104 | } 105 | if (pLeft == 1 && pRight == 1) { 106 | pLeft = 0; 107 | pRight = 0; 108 | } 109 | 110 | if (pressed & PAD_BUTTON_START) { pStart = 1; } 111 | if (pressed & PAD_BUTTON_X) { pSelect = 1; } 112 | 113 | if (pressed & PAD_BUTTON_B) { pFaceLeft = 1; } 114 | if (pressed & PAD_BUTTON_A) { pFaceDown = 1; } 115 | if (pressed & PAD_BUTTON_Y) { pFaceRight = 1; } 116 | 117 | if (pressed & PAD_TRIGGER_L) { pL = 1; } 118 | if (pressed & PAD_TRIGGER_R) { pR = 1; } 119 | 120 | pAccept = pFaceDown; 121 | pDecline = pFaceLeft; 122 | } 123 | 124 | updateKey(&btnUp, pUp); 125 | updateKey(&btnDown, pDown); 126 | updateKey(&btnLeft, pLeft); 127 | updateKey(&btnRight, pRight); 128 | 129 | updateKey(&btnStart, pStart); 130 | updateKey(&btnSelect, pSelect); 131 | 132 | updateKey(&btnL, pL); 133 | updateKey(&btnR, pR); 134 | 135 | updateKey(&btnFaceLeft, pFaceLeft); 136 | updateKey(&btnFaceDown, pFaceDown); 137 | updateKey(&btnFaceRight, pFaceRight); 138 | 139 | updateKey(&btnAccept, pAccept); 140 | updateKey(&btnDecline, pDecline); 141 | } 142 | 143 | void updateKey(Button* btn, int state) 144 | { 145 | if (state) { 146 | if (btn->held == 1) { 147 | btn->pressed = 0; 148 | }else{ 149 | btn->pressed = 1; 150 | } 151 | btn->held = 1; 152 | btn->released = 0; 153 | }else{ 154 | if (btn->held == 1) { 155 | btn->released = 1; 156 | }else{ 157 | btn->released = 0; 158 | } 159 | btn->held = 0; 160 | btn->pressed = 0; 161 | } 162 | } -------------------------------------------------------------------------------- /source/enemies/boar.c: -------------------------------------------------------------------------------- 1 | #include "boar.h" 2 | #include "../game.h" 3 | #include "../hero.h" 4 | #include 5 | 6 | void boarStep(Boar* b); 7 | void boarDraw(Boar* b); 8 | 9 | void createBoar(int x, int y) 10 | { 11 | int i; 12 | for (i = 0; i < MAX_ENEMIES; i++) { 13 | if (enemies[i] == NULL) { 14 | Enemy* e = /*(Enemy*)*/malloc(sizeof *e); 15 | Boar* b = /*(Boar*)*/malloc(sizeof *b); 16 | 17 | b->id = i; 18 | 19 | b->hp = 3; 20 | 21 | b->x = x; 22 | b->y = y; 23 | 24 | b->hsp = 0; 25 | 26 | b->imageIndex = 0; 27 | b->dir = 1; 28 | 29 | b->blink = 0; 30 | 31 | b->state = 0; 32 | b->timer = 0; 33 | 34 | e->data = b; 35 | e->enemyStep = boarStep; 36 | e->enemyDraw = boarDraw; 37 | e->type = 26; 38 | 39 | enemies[i] = e; 40 | i = MAX_ENEMIES; 41 | } 42 | } 43 | } 44 | 45 | void boarStep(Boar* b) 46 | { 47 | //Setup mask 48 | Mask mask; 49 | { 50 | mask.unused = mask.circle = 0; 51 | mask.w = 32; 52 | mask.h = 28; 53 | mask.x = b->x + ((40 - mask.w) / 2); 54 | mask.y = b->y + 40 - mask.h; 55 | } 56 | 57 | //Blink animation 58 | { 59 | if (b->blink > 0) { 60 | b->blink -= 1; 61 | } 62 | } 63 | 64 | //Patterns 65 | { 66 | //Dance 67 | if (b->state == 0) 68 | { 69 | //Animate 70 | b->imageIndex += 0.15; 71 | if (b->imageIndex >= 8) { 72 | b->imageIndex -= 8; 73 | } 74 | 75 | //if player gets near 76 | Mask area; 77 | area.unused = area.circle = 0; 78 | area.x = b->x - 80; 79 | area.y = b->y - 40; 80 | area.w = 200; 81 | area.h = 80; 82 | 83 | if (checkCollision(area, getHeroMask()) == 1) { 84 | b->state = 1; 85 | b->timer = -1; 86 | b->imageIndex = 0; 87 | b->dir = 1; 88 | if (herox < b->x + 20) { 89 | b->dir = -1; 90 | } 91 | } 92 | } 93 | //Rev up 94 | else if (b->state == 1) 95 | { 96 | b->timer += 1; 97 | 98 | //Play sound 99 | if (b->timer % 10 == 0) { 100 | PHL_PlaySound(sounds[sndShot01], CHN_ENEMIES); 101 | } 102 | 103 | //Create effect 104 | if (b->timer % 16 == 0) { 105 | if (b->dir == 1) { 106 | createEffectExtra(3, b->x + 20 - 30, b->y + 8, -1, 0, 0); 107 | } 108 | if (b->dir == -1) { 109 | createEffectExtra(3, b->x + 20 - 10, b->y + 8, 1, 0, 0); 110 | } 111 | } 112 | 113 | if (b->timer >= 60) { 114 | b->state = 2; 115 | b->hsp = 3; 116 | } 117 | } 118 | //Running 119 | else if (b->state == 2) 120 | { 121 | b->x += b->hsp * b->dir; 122 | mask.x = b->x + ((40 - mask.w) / 2); 123 | 124 | //Collide with wall 125 | if (checkTileCollision(1, mask) == 1) { 126 | b->x -= b->hsp * b->dir; 127 | b->dir *= -1; 128 | } 129 | 130 | //On edge 131 | { 132 | mask.x = b->x + ((40 - mask.w) / 2); 133 | 134 | mask.x += mask.w * b->dir; 135 | mask.y += 1; 136 | 137 | PHL_Rect collide = getTileCollision(1, mask); 138 | if (collide.x == -1) { 139 | collide = getTileCollision(3, mask); 140 | } 141 | if (collide.x == -1) { 142 | b->dir *= -1; 143 | } 144 | 145 | mask.y -= 1; 146 | mask.x = b->x + ((40 - mask.w) / 2); 147 | } 148 | 149 | b->hsp -= 0.05; 150 | if (b->hsp <= 0) { 151 | b->state = 0; 152 | } 153 | } 154 | 155 | //Running animation 156 | if (b->state == 1 || b->state == 2) { 157 | //Animate 158 | b->imageIndex += 0.2; 159 | if (b->imageIndex >= 2) { 160 | b->imageIndex -= 2; 161 | } 162 | } 163 | } 164 | 165 | //Collide with hero 166 | { 167 | if (checkCollision(mask, getHeroMask())) { 168 | heroHit(30, mask.x + (mask.w / 2)); 169 | } 170 | } 171 | 172 | //Weapon collision 173 | { 174 | int i; 175 | for (i = 0; i < MAX_WEAPONS; i++) { 176 | if (weapons[i] != NULL) { 177 | if (weapons[i]->cooldown == 0) { 178 | if (checkCollision(mask, weapons[i]->weaponMask)) { 179 | weaponHit(weapons[i]); 180 | b->hp -= 1; 181 | b->blink = 15; 182 | 183 | //Death 184 | if (b->hp <= 0) { 185 | createEffect(2, b->x - 12, b->y - 12); 186 | spawnCollectable(b->x + 20, b->y); 187 | enemyDestroy(b->id); 188 | } 189 | 190 | i = MAX_WEAPONS; 191 | } 192 | } 193 | } 194 | } 195 | } 196 | } 197 | 198 | void boarDraw(Boar* b) 199 | { 200 | if (b->blink % 2 == 0) 201 | { 202 | int cropx = 0, cropy = 360; 203 | int drawx = b->x, drawy = b->y; 204 | 205 | //Dance 206 | if (b->state == 0) { 207 | int animation[8] = {0, 1, 2, 1, 0, 3, 4, 3}; 208 | cropx = 160 + (animation[(int)b->imageIndex] * 40); 209 | } 210 | //Charge 211 | else{ 212 | cropx = (int)b->imageIndex * 40; 213 | 214 | if (b->dir == -1) { 215 | cropx += 80; 216 | } 217 | } 218 | 219 | PHL_DrawSurfacePart(drawx, drawy, cropx, cropy, 40, 40, images[imgEnemies]); 220 | } 221 | } -------------------------------------------------------------------------------- /source/enemies/slime.c: -------------------------------------------------------------------------------- 1 | #include "slime.h" 2 | #include 3 | #include "../PHL.h" 4 | #include "../game.h" 5 | #include "../collision.h" 6 | #include "../hero.h" 7 | #include "../enemy.h" 8 | #include "../weapon.h" 9 | 10 | void slimeStep(Slime* s); 11 | void slimeDraw(Slime* s); 12 | 13 | void createSlime(int x, int y, int type, int offset) 14 | { 15 | int i; 16 | for (i = 0; i < MAX_ENEMIES; i++) { 17 | if (enemies[i] == NULL) { 18 | Enemy* result = malloc(sizeof *result); 19 | Slime* s = malloc(sizeof *s); 20 | 21 | s->id = i; 22 | 23 | s->x = x + 20; 24 | s->y = y; 25 | s->type = type; 26 | s->offset = offset; 27 | 28 | s->hp = 1; 29 | s->state = 0; 30 | s->counter = 0; 31 | s->timer = 0; 32 | s->grav = 0.125; 33 | s->vsp = 0; 34 | s->hsp = 0; 35 | s->imageIndex = 0; 36 | 37 | result->data = s; 38 | result->enemyStep = slimeStep; 39 | result->enemyDraw = slimeDraw; 40 | result->type = 0; 41 | 42 | enemies[i] = result; 43 | i = MAX_ENEMIES; 44 | } 45 | } 46 | } 47 | 48 | void slimeStep(Slime* s) 49 | { 50 | char dead = 0; 51 | 52 | //Stay within room 53 | { 54 | if (s->x > 640) { 55 | s->x = 640; 56 | } 57 | 58 | if (s->x < 0) { 59 | s->x = 0; 60 | } 61 | } 62 | 63 | //Setup Rectangle Mask 64 | Mask mask; 65 | { 66 | mask.unused = 0; 67 | mask.circle = 0; 68 | mask.w = 24; 69 | mask.h = 24; 70 | mask.x = s->x - (mask.w / 2); 71 | mask.y = s->y + 28 - (mask.h / 2); 72 | } 73 | 74 | //Idle 75 | if (s->state == 0) 76 | { 77 | s->imageIndex += 0.25; 78 | 79 | if (s->imageIndex >= 6) { 80 | s->imageIndex = 0; 81 | 82 | if (s->offset <= 0) { 83 | s->state = 1; 84 | 85 | //Red/Yellow Slime 86 | if (s->type == 1 || s->type == 2) 87 | { 88 | s->hsp = 1; 89 | if (s->type == 2) { 90 | s->hsp = 1.5; 91 | } 92 | if ((int)(rand() % 2) == 0) { 93 | s->hsp *= -1; 94 | } 95 | } 96 | 97 | if (s->counter < 2) { 98 | s->vsp = -2; 99 | s->counter += 1; 100 | }else{ 101 | s->vsp = -4; 102 | s->counter = 0; 103 | } 104 | }else{ 105 | s->offset -= 1; 106 | } 107 | } 108 | } 109 | 110 | //Jump 111 | else if (s->state == 1) 112 | { 113 | //Red/Yellow Slime 114 | if (s->type == 1 || s->type == 2) 115 | { 116 | s->x += s->hsp; 117 | mask.x = s->x - (mask.w / 2); 118 | 119 | PHL_Rect collide = getTileCollision(1, mask); 120 | if (collide.x != -1) { 121 | if (s->hsp > 0) { 122 | s->x = collide.x - (mask.w / 2); 123 | }else if (s->hsp < 0) { 124 | s->x = collide.x + 40 + (mask.w / 2); 125 | } 126 | } 127 | 128 | mask.x = s->x - (mask.w / 2); 129 | } 130 | 131 | s->y += s->vsp; 132 | s->vsp += s->grav; 133 | 134 | mask.y = s->y + 28 - (mask.h / 2); 135 | 136 | PHL_Rect collide = getTileCollision(1, mask); 137 | if (collide.x == -1) { 138 | collide = getTileCollision(3, mask); 139 | } 140 | if (collide.x != -1) { 141 | if (s->vsp >= 0) { 142 | s->state = 0; 143 | s->hsp = 0; 144 | s->y = collide.y - 40; 145 | }else{ 146 | s->y = collide.y + 40 - (40 - mask.h) + 1; 147 | } 148 | } 149 | } 150 | 151 | //Setup Collision Mask 152 | { 153 | mask.unused = 0; 154 | mask.circle = 1; 155 | mask.w = 12; 156 | mask.x = s->x; 157 | mask.y = s->y + 28; 158 | } 159 | 160 | //Fell in a pit 161 | { 162 | if (s->y > 480) { 163 | dead = 1; 164 | } 165 | } 166 | 167 | //Collide with hero 168 | { 169 | if (checkCollision(mask, heroMask)) { 170 | int dmg[3] = {10, 20, 20}; 171 | 172 | if (heroHit(dmg[s->type], s->x) == 1 && s->type == 2) { 173 | heroStun(); 174 | } 175 | } 176 | } 177 | 178 | //Sword collision 179 | { 180 | int i; 181 | for (i = 0; i < MAX_WEAPONS; i++) { 182 | if (weapons[i] != NULL) { 183 | if (checkCollision(mask, weapons[i]->weaponMask)) { 184 | weaponHit(weapons[i]); 185 | 186 | spawnCollectable(s->x, s->y + 6); 187 | createEffect(2, s->x - 32, s->y - 12); 188 | dead = 1; 189 | 190 | i = MAX_WEAPONS; 191 | } 192 | } 193 | } 194 | } 195 | 196 | //Destroy object 197 | { 198 | if (dead == 1) { 199 | enemyDestroy(s->id); 200 | } 201 | } 202 | } 203 | 204 | void slimeDraw(Slime* s) 205 | { 206 | int cropX = 0, 207 | cropY = 0; 208 | 209 | //Idle 210 | if (s->state == 0) { 211 | int image[6] = { 0, 1, 2, 3, 4, 6 }; 212 | cropX = image[(int)s->imageIndex] * 40; 213 | } 214 | 215 | //Jump 216 | else if (s->state == 1) { 217 | cropX = 200; 218 | if (s->vsp >= 0) { 219 | cropX += 40; 220 | } 221 | } 222 | 223 | //Color offsets 224 | int addX[3] = {0, 280, 0}; 225 | int addY[3] = {0, 0, 480}; 226 | 227 | PHL_DrawSurfacePart(s->x - 20, s->y + 12, cropX + addX[s->type], cropY + addY[s->type], 40, 40, images[imgEnemies]); 228 | } -------------------------------------------------------------------------------- /source/enemies/ghoul.c: -------------------------------------------------------------------------------- 1 | #include "ghoul.h" 2 | #include "../game.h" 3 | #include "../enemy.h" 4 | #include "../PHL.h" 5 | #include "../hero.h" 6 | #include 7 | 8 | void ghoulStep(Ghoul* g); 9 | void ghoulDraw(Ghoul* g); 10 | 11 | void createGhoul(int x, int y, int type) 12 | { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* e = malloc(sizeof *e); 17 | Ghoul* g = malloc(sizeof *g); 18 | g->id = i; 19 | g->hp = 2; 20 | 21 | g->x = x; 22 | g->y = y; 23 | 24 | g->vsp = 0; 25 | g->grav = 0.1; 26 | 27 | g->dir = 0; 28 | g->type = type; 29 | g->onground = 0; 30 | 31 | g->timer = 0; 32 | g->state = 0; 33 | g->invincible = 0; 34 | 35 | g->imageIndex = 0; 36 | 37 | g->mask.circle = 0; 38 | g->mask.unused = 1; 39 | g->mask.w = 24; 40 | g->mask.h = 32; 41 | g->mask.x = g->x + ((40 - g->mask.w) / 2); 42 | g->mask.y = g->y + (40 - g->mask.h); 43 | 44 | e->data = g; 45 | e->enemyStep = ghoulStep; 46 | e->enemyDraw = ghoulDraw; 47 | e->type = 18; 48 | 49 | enemies[i] = e; 50 | i = MAX_ENEMIES; 51 | } 52 | } 53 | 54 | } 55 | 56 | void ghoulStep(Ghoul* g) 57 | { 58 | if (g->invincible > 0) { 59 | g->invincible -= 1; 60 | } 61 | 62 | if (g->state == 0) { //Wait 63 | Mask area; 64 | area.unused = area.circle = 0; 65 | area.w = 280; 66 | area.h = 80; 67 | area.x = g->x - 120; 68 | area.y = g->y - 20; 69 | 70 | if (checkCollisionXY(area, herox, heroy + 20) == 1) { 71 | g->state = 1; 72 | g->mask.unused = 0; 73 | g->imageIndex = 0; 74 | 75 | g->dir = 1; 76 | if (herox < g->x + 20) { 77 | g->dir = -1; 78 | } 79 | } 80 | } 81 | else if (g->state == 1) { //Pop-up 82 | g->imageIndex += 0.16; 83 | 84 | if (g->imageIndex >= 4) { 85 | g->state = 2; 86 | g->vsp = -1; 87 | g->imageIndex = 0; 88 | PHL_PlaySound(sounds[sndPi05],CHN_ENEMIES); 89 | } 90 | } 91 | else if (g->state == 2) { //Walking 92 | g->mask.unused = 0; 93 | if (g->onground == 0) { 94 | //Vertical movement 95 | g->y += g->vsp; 96 | g->vsp += g->grav; 97 | 98 | g->mask.y = g->y + (40 - g->mask.h); 99 | 100 | PHL_Rect collide = getTileCollision(1, g->mask); 101 | if (collide.x == -1) { 102 | collide = getTileCollision(3, g->mask); 103 | } 104 | if (collide.x != -1) { 105 | g->onground = 1; 106 | g->vsp = 0; 107 | g->y = collide.y - 40; 108 | g->mask.y = g->y + (40 - g->mask.h); 109 | } 110 | } 111 | 112 | g->imageIndex += 0.1; 113 | if (g->imageIndex >= 2) { 114 | g->imageIndex -= 2; 115 | } 116 | 117 | double hsp = 1; 118 | 119 | if ((int)g->imageIndex == 0) { 120 | hsp = 0.5; 121 | } 122 | 123 | //Purple 124 | if (g->type == 1) { 125 | hsp *= 2; 126 | } 127 | 128 | g->x += hsp * g->dir; 129 | g->mask.x = g->x + ((40 - g->mask.w) / 2); 130 | 131 | if (g->onground == 1) { 132 | if ((g->x < -20 || g->x > 660) || checkTileCollision(1, g->mask) == 1) { 133 | g->dir *= -1; 134 | 135 | PHL_Rect collide = getTileCollision(1, g->mask); 136 | if (collide.x != -1) { 137 | g->x = collide.x + (40 * g->dir); 138 | } 139 | } 140 | else { 141 | //check on ledge 142 | g->mask.w = 5; 143 | if (g->dir == 1) { 144 | g->mask.x = g->x + 30; 145 | } 146 | if (g->dir == -1) { 147 | g->mask.x = g->x + 5; 148 | } 149 | g->mask.y += 20; 150 | 151 | if (checkTileCollision(1, g->mask) == 0 && checkTileCollision(3, g->mask) == 0) { 152 | g->dir *= -1; 153 | } 154 | g->mask.w = 24; 155 | g->mask.x = g->x + ((40 - g->mask.w) / 2); 156 | g->mask.y = g->y + (40 - g->mask.h); 157 | } 158 | } 159 | } 160 | 161 | g->mask.x = g->x + ((40 - g->mask.w) / 2); 162 | g->mask.y = g->y + (40 - g->mask.h); 163 | 164 | //Hit Player 165 | { 166 | if (checkCollision(g->mask, getHeroMask())) { 167 | if (heroHit(10, g->x + 20) == 1 && g->type == 1) { 168 | heroPoison(); 169 | } 170 | } 171 | } 172 | 173 | //Weapon Collision 174 | { 175 | int i; 176 | for (i = 0; i < MAX_WEAPONS; i++) { 177 | if (weapons[i] != NULL) { 178 | if (weapons[i]->cooldown == 0) { 179 | if (checkCollision(g->mask, weapons[i]->weaponMask)) { 180 | weaponHit(weapons[i]); 181 | 182 | g->hp -= 1; 183 | g->invincible = 15; 184 | //Death 185 | if (g->hp <= 0) { 186 | createEffect(2, g->x - 12, g->y - 6); 187 | spawnCollectable(g->x + 20, g->y); 188 | enemyDestroy(g->id); 189 | } 190 | i = MAX_WEAPONS; 191 | } 192 | } 193 | } 194 | } 195 | } 196 | 197 | } 198 | 199 | void ghoulDraw(Ghoul* g) 200 | { 201 | if (g->state != 0 && g->invincible % 2 == 0) { 202 | int cx = (int)g->imageIndex * 40, 203 | cy = 160; 204 | 205 | if (g->state == 1) { 206 | cx += 160; 207 | }else{ 208 | if (g->dir == -1) { 209 | cx += 80; 210 | } 211 | } 212 | 213 | //Purple palette 214 | cy += 160 * g->type; 215 | 216 | PHL_DrawSurfacePart(g->x, g->y, cx, cy, 40, 40, images[imgEnemies]); 217 | } 218 | } -------------------------------------------------------------------------------- /source/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "PHL.h" 5 | #include "enemy.h" 6 | #include "enemies/slime.h" 7 | #include "enemies/bat.h" 8 | #include "enemies/slug.h" 9 | #include "enemies/knight.h" 10 | #include "enemies/heads.h" 11 | #include "enemies/gas.h" 12 | #include "enemies/skull.h" 13 | #include "enemies/fish.h" 14 | #include "enemies/waterjumper.h" 15 | #include "enemies/podoboo.h" 16 | #include "enemies/thwomp.h" 17 | #include "enemies/dodo.h" 18 | #include "enemies/batboss.h" 19 | #include "enemies/crab.h" 20 | #include "enemies/skeleton.h" 21 | #include "enemies/ghoul.h" 22 | #include "enemies/seal.h" 23 | #include "enemies/jellyfish.h" 24 | #include "enemies/wizard.h" 25 | #include "enemies/pendulum.h" 26 | #include "enemies/gyra.h" 27 | #include "enemies/lolidra.h" 28 | #include "enemies/bee.h" 29 | #include "enemies/devil.h" 30 | #include "enemies/firewheel.h" 31 | #include "enemies/boar.h" 32 | #include "enemies/golem.h" 33 | #include "enemies/garm.h" 34 | #include "enemies/poisonknight.h" 35 | #include "enemies/dog.h" 36 | #include "enemies/boomknight.h" 37 | #include "enemies/pumpkin.h" 38 | #include "enemies/hydra.h" 39 | #include "object.h" 40 | #include "effect.h" 41 | #include "weapon.h" 42 | #include "platform.h" 43 | 44 | #define TITLE 0 45 | #define GAME 1 46 | #define INVENTORY 2 47 | #define OPTIONS 3 48 | #define SAVING 4 49 | #define LEVELSTART 5 50 | #define GETITEM 6 51 | 52 | //Sound channels 53 | #define CHN_MUSIC 0 54 | #define CHN_SOUND 1 //Various sounds, like menus and fanfares 55 | #define CHN_HERO 2 56 | #define CHN_WEAPONS 3 57 | #define CHN_ENEMIES 4 58 | #define CHN_EFFECTS 5 59 | 60 | Door* lastDoor; 61 | 62 | int secretTimer; 63 | int levelStartTimer; 64 | int saveTimer; 65 | 66 | int quakeTimer; 67 | 68 | int bellFlag; 69 | int bossFlag; 70 | int bossDefeatedFlag; 71 | 72 | char roomDarkness; 73 | 74 | //Used for item get message 75 | int itemGotX; 76 | int itemGotY; 77 | 78 | int roomSecret; 79 | 80 | int collisionTiles[16][12]; 81 | 82 | //Playtime in frames. At 60 frames per second can hold ~828 1/2 days worth of playtime if my math isn't shit 83 | unsigned long playTime; 84 | 85 | //Inventory 86 | unsigned char hasWeapon[5]; 87 | unsigned char hasItem[28]; 88 | unsigned char hasKey[8]; 89 | 90 | //Save data flags 91 | unsigned char flags[60]; 92 | 93 | PHL_Background background, 94 | foreground; 95 | 96 | //Game assets 97 | PHL_Surface images[15]; 98 | PHL_Music bgmMusic; 99 | PHL_Music bgmSecret; 100 | PHL_Music bgmGameover; 101 | PHL_Sound sounds[43]; 102 | 103 | #define MAX_WEAPONS 5 104 | Weapon* weapons[MAX_WEAPONS]; 105 | 106 | #define MAX_OBJECTS 40 107 | Object* objects[MAX_OBJECTS]; 108 | 109 | #define MAX_ENEMIES 20 110 | Enemy* enemies[MAX_ENEMIES]; 111 | 112 | #define MAX_EFFECTS 30 113 | Effect* effects[MAX_EFFECTS]; 114 | 115 | #define MAX_PLATFORMS 10 116 | Platform* platforms[MAX_PLATFORMS]; 117 | 118 | //Graphic names 119 | #define imgTiles 0 120 | #define imgEnemies 1 121 | #define imgHud 2 122 | #define imgMisc20 3 123 | #define imgMisc32 4 124 | #define imgHero 5 125 | #define imgItems 6 126 | #define imgExplosion 7 127 | #define imgBoss 8 128 | #define imgMisc2040 9 129 | #define imgFontKana 10 130 | #define imgBoldFont 11 131 | #define imgDark 12 132 | #define imgMisc6020 13 133 | #define imgTitle01 14 134 | 135 | //Sound names 136 | #define sndBee01 0 137 | #define sndBell01 1 138 | #define sndBom01 2 139 | #define sndBom02 3 140 | #define sndBom03 4 141 | #define sndDoor00 5 142 | #define sndFire01 6 143 | #define sndGas01 7 144 | #define sndGet01 8 145 | #define sndGet02 9 146 | #define sndHit01 10 147 | #define sndHit02 11 148 | #define sndHit03 12 149 | #define sndHit04 13 150 | #define sndHit05 14 151 | #define sndHit06 15 152 | #define sndHit07 16 153 | #define sndJump01 17 154 | #define sndJump02 18 155 | #define sndNg 19 156 | #define sndOk 20 157 | #define sndPi01 21 158 | #define sndPi02 22 159 | #define sndPi03 23 160 | #define sndPi04 24 161 | #define sndPi05 25 162 | #define sndPi06 26 163 | #define sndPi07 27 164 | #define sndPi08 28 165 | #define sndPi09 29 166 | #define sndPi10 30 167 | #define sndPower01 31 168 | #define sndPower02 32 169 | #define sndShot01 33 170 | #define sndShot02 34 171 | #define sndShot03 35 172 | #define sndShot04 36 173 | #define sndShot05 37 174 | #define sndShot06 38 175 | #define sndShot07 39 176 | #define sndStep01 40 177 | #define sndWater01 41 178 | #define sndWolf01 42 179 | 180 | void loadResources(); 181 | void freeResources(); 182 | 183 | void game(); 184 | 185 | void gameSetup(); 186 | void gameCleanup(); 187 | 188 | void enterDoor(); 189 | void getItem(int itemNum); 190 | void saveScreen(); 191 | 192 | void gameEnding(); 193 | 194 | //void enterDoor(Door* d); 195 | void loadScreen(); 196 | 197 | void changeScreen(int dx, int dy); 198 | 199 | int writeSave(char* fname); 200 | void loadSave(char* fname); 201 | 202 | int fileExists(char* fpath); 203 | 204 | void playSecret(); 205 | void secretCountdown(); 206 | 207 | int getDrawHP(); 208 | void setDrawHP(int val); 209 | 210 | int getLevel(); 211 | 212 | void setBossRoom(); 213 | 214 | void setAutoSave(char val); 215 | char getAutoSave(); 216 | 217 | #endif -------------------------------------------------------------------------------- /source/platform.c: -------------------------------------------------------------------------------- 1 | #include "platform.h" 2 | #include "game.h" 3 | #include "PHL.h" 4 | #include "hero.h" 5 | #include 6 | 7 | void createPlatform(int type, int xstart, int ystart, int xend, int yend, int spd, int secret) 8 | { 9 | int i; 10 | for (i = 0; i < MAX_PLATFORMS; i++) { 11 | if (platforms[i] == NULL) { 12 | Platform* p = malloc(sizeof *p); 13 | p->id = i; 14 | p->type = type; 15 | 16 | p->x = p->xstart = xstart; 17 | p->y = p->ystart = ystart; 18 | 19 | p->xend = xend; 20 | p->yend = yend; 21 | 22 | p->timer = 0; 23 | 24 | p->secret = secret; 25 | 26 | if (roomSecret == 1) { 27 | p->secret = 0; 28 | } 29 | 30 | p->visible = 1; 31 | if (p->secret == 1) { 32 | p->visible = 0; 33 | } 34 | 35 | if (type == 1) { 36 | p->xend = p->x + 1; 37 | p->yend = p->y; 38 | } 39 | 40 | p->state = 0; 41 | p->spd = spd; 42 | 43 | p->mask.circle = 0; 44 | p->mask.unused = 0; 45 | if (p->secret == 1) { 46 | p->mask.unused = 1; 47 | } 48 | p->mask.x = xstart; 49 | p->mask.y = ystart; 50 | p->mask.w = p->mask.h = 40; 51 | 52 | platforms[i] = p; 53 | i = MAX_PLATFORMS; 54 | } 55 | } 56 | } 57 | 58 | void platformStep(Platform* p) 59 | { 60 | char isSolid = p->visible; 61 | 62 | //Megaman blocks 63 | if (p->type == 2) { 64 | int myStep = p->xend, 65 | maxSteps = p->yend; 66 | 67 | p->timer += 1; 68 | if (p->timer >= maxSteps * 60 + 60) { 69 | p->timer = 0; 70 | } 71 | 72 | //Play sound 73 | if (p->timer == myStep * 60) { 74 | PHL_PlaySound(sounds[sndPi03], CHN_SOUND); 75 | } 76 | 77 | if (p->timer > myStep * 60 && p->timer <= (myStep * 60) + 60) { 78 | isSolid = 1; 79 | p->visible = 1; 80 | 81 | //Blink effect 82 | if (p->timer > myStep * 60 + 30) { 83 | p->visible = p->timer % 2; 84 | } 85 | }else{ 86 | isSolid = 0; 87 | p->mask.unused = 1; 88 | p->visible = 0; 89 | 90 | //Fall off platform 91 | if (getHeroMask().x > p->mask.x + p->mask.w || getHeroMask().x + getHeroMask().w < p->mask.x) { 92 | }else if (heroy == p->y - 40 && getHeroVsp() >= 0) { 93 | setHeroOnground(0); 94 | } 95 | } 96 | } 97 | 98 | if (isSolid == 1) { 99 | p->mask.unused = 0; 100 | 101 | int targx = p->xend, 102 | targy = p->yend; 103 | 104 | if (p->state == 1) { 105 | targx = p->xstart; 106 | targy = p->ystart; 107 | } 108 | 109 | //Check if the player is standing on top 110 | int isontop = 0; 111 | int isabove = 0; 112 | if (getHeroMask().x > p->mask.x + p->mask.w || getHeroMask().x + getHeroMask().w < p->mask.x) { 113 | }else if (heroy == p->y - 40 && getHeroVsp() >= 0) { 114 | isontop = 1; 115 | }else if (heroy < p->y - 40) { 116 | isabove = 1; 117 | } 118 | 119 | //Move platform 120 | if (p->y != targy) { 121 | if (p->y < targy) { 122 | p->y += p->spd; 123 | if (isontop == 1) { 124 | heroy += p->spd; 125 | } 126 | }else{ 127 | p->y -= p->spd; 128 | if (isontop == 1) { 129 | heroy -= p->spd; 130 | }else{ 131 | p->mask.y = p->y; 132 | if (checkCollision(p->mask, getHeroMask()) && isabove == 1) { 133 | heroy = p->y - 40; 134 | } 135 | } 136 | } 137 | } 138 | 139 | if (p->x != targx) { 140 | if (p->x < targx) { 141 | p->x += p->spd; 142 | if (isontop == 1) { 143 | herox += p->spd; 144 | } 145 | }else{ 146 | p->x -= p->spd; 147 | if (isontop == 1) { 148 | herox -= p->spd; 149 | } 150 | } 151 | } 152 | 153 | if (p->x == targx && p->y == targy) { 154 | if (p->state == 0) { 155 | p->state = 1; 156 | }else{ 157 | p->state = 0; 158 | } 159 | } 160 | 161 | if (p->type == 0) //Moving platform 162 | { 163 | 164 | } 165 | else if (p->type == 1) { //Loose block 166 | if (p->spd != 0) { 167 | p->timer -= 1; 168 | if (p->timer <= 0) { 169 | createRockSmash(p->x + 20, p->y + 20); 170 | if (isontop == 1) { 171 | setHeroOnground(0); 172 | } 173 | platformDestroy(p->id); 174 | /*createEffectExtra(4, p->x, p->y, -1, 0, 0); 175 | createEffectExtra(4, p->x, p->y, -1, 0, 1); 176 | createEffectExtra(4, p->x, p->y, 1, 0, 0); 177 | createEffectExtra(4, p->x, p->y, 1, 0, 1); 178 | */ 179 | } 180 | } 181 | 182 | if (p->spd == 0 && isontop == 1) { 183 | p->spd = 2; 184 | p->timer = 30; 185 | } 186 | } 187 | 188 | //Update Mask 189 | p->mask.x = p->x; 190 | p->mask.y = p->y; 191 | }else{ 192 | //p->mask.unused = 1; 193 | if (p->secret == 1) { 194 | if (roomSecret == 1) { 195 | p->mask.unused = 0; 196 | p->visible = 1; 197 | p->secret = 0; 198 | playSecret(); 199 | } 200 | } 201 | } 202 | } 203 | 204 | void platformDraw(Platform* p) 205 | { 206 | if (p->visible == 1) { 207 | int cropX = p->type * 40; 208 | 209 | if (p->type == 3) { 210 | cropX = 9 * 40; 211 | } 212 | 213 | PHL_DrawSurfacePart(p->x, p->y, cropX, 400, 40, 40, images[imgMisc20]); 214 | } 215 | } 216 | 217 | void platformDestroy(int id) 218 | { 219 | if (platforms[id] != NULL) { 220 | free(platforms[id]); 221 | } 222 | platforms[id] = NULL; 223 | } -------------------------------------------------------------------------------- /source/vita/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of EasyRPG Player. 3 | * 4 | * EasyRPG Player is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * EasyRPG Player is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with EasyRPG Player. If not, see . 16 | */ 17 | 18 | #ifndef _EASYRPG_UTILS_H_ 19 | #define _EASYRPG_UTILS_H_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace Utils { 27 | /** 28 | * Converts a string to lower case. 29 | * 30 | * @param str string to convert. 31 | * @return the converted string. 32 | */ 33 | std::string LowerCase(const std::string& str); 34 | 35 | /** 36 | * Converts a string to upper case. 37 | * 38 | * @param str string to convert. 39 | * @return the converted string. 40 | */ 41 | std::string UpperCase(const std::string& str); 42 | 43 | /** 44 | * Tests if a string ends with a substring. 45 | * 46 | * @param str String to search in 47 | * @param end Substring to check at the end of str 48 | * @return true when the end matches 49 | */ 50 | bool EndsWith(const std::string& str, const std::string& end); 51 | 52 | /** 53 | * Converts Utf8 to UTF-16. 54 | * 55 | * @param str string to convert. 56 | * @return the converted string. 57 | */ 58 | std::u16string DecodeUTF16(const std::string& str); 59 | 60 | /** 61 | * Converts UTF-8 to UTF-32. 62 | * 63 | * @param str string to convert. 64 | * @return the converted string. 65 | */ 66 | std::u32string DecodeUTF32(const std::string& str); 67 | 68 | /** 69 | * Converts UTF-16 to UTF-8. 70 | * 71 | * @param str string to convert. 72 | * @return the converted string. 73 | */ 74 | std::string EncodeUTF(const std::u16string& str); 75 | 76 | /** 77 | * Converts UTF-32 to UTF-8. 78 | * 79 | * @param str string to convert. 80 | * @return the converted string. 81 | */ 82 | std::string EncodeUTF(const std::u32string& str); 83 | 84 | /** 85 | * Converts UTF-8 string to std::wstring. 86 | * 87 | * @param str string to convert. 88 | * @return the converted string. 89 | */ 90 | std::wstring ToWideString(const std::string& str); 91 | 92 | /** 93 | * Converts std::wstring to UTF-8 string. 94 | * 95 | * @param str string to convert. 96 | * @return the converted string. 97 | */ 98 | std::string FromWideString(const std::wstring& str); 99 | 100 | /** 101 | * Converts arithmetic types to a string. 102 | * 103 | * @param n arithmetic type to convert. 104 | * @return the converted string 105 | */ 106 | template 107 | std::string ToString(const T& n) { 108 | std::ostringstream stm ; 109 | stm << n ; 110 | return stm.str(); 111 | } 112 | 113 | /** 114 | * Checks if the platform is big endian 115 | * 116 | * @return true if big, false if little endian 117 | */ 118 | bool IsBigEndian(); 119 | 120 | /** 121 | * Swaps the byte order of the passed number when on big endian systems. 122 | * Does nothing otherwise. 123 | * 124 | * @param us Number to swap 125 | */ 126 | void SwapByteOrder(uint16_t& us); 127 | 128 | /** 129 | * Swaps the byte order of the passed number when on big endian systems. 130 | * Does nothing otherwise. 131 | * 132 | * @param ui Number to swap 133 | */ 134 | void SwapByteOrder(uint32_t& ui); 135 | 136 | /** 137 | * Swaps the byte order of the passed number when on big endian systems. 138 | * Does nothing otherwise. 139 | * 140 | * @param d Number to swap 141 | */ 142 | void SwapByteOrder(double& d); 143 | 144 | /** 145 | * Gets a random number in the inclusive range from - to. 146 | * 147 | * @param from Interval start 148 | * @param to Interval end 149 | * @return Random number in inclusive interval 150 | */ 151 | int32_t GetRandomNumber(int32_t from, int32_t to); 152 | 153 | /** 154 | * Seeds the RNG used by GetRandomNumber 155 | * 156 | * @param seed Seed to use 157 | */ 158 | void SeedRandomNumberGenerator(int32_t seed); 159 | 160 | /** 161 | * Reads a line from a stream and returns it. 162 | * Same as std::getline but handles linebreaks independent of the platform 163 | * correctly. 164 | * 165 | * @param is Input stream to read 166 | * @return Content of the read line 167 | */ 168 | std::string ReadLine(std::istream& is); 169 | 170 | /** 171 | * Splits a string into tokens specified by a predicate function. 172 | * 173 | * @param str_to_tokenize String that is tokenized 174 | * @param token_re Predicate function, must return true when the character is used for splitting. 175 | * @return vector containing the elements between the tokens 176 | */ 177 | std::vector Tokenize(const std::string& str_to_tokenize, const std::function predicate); 178 | 179 | } // namespace Utils 180 | 181 | #endif 182 | -------------------------------------------------------------------------------- /source/enemies/knight.c: -------------------------------------------------------------------------------- 1 | #include "knight.h" 2 | #include "../enemy.h" 3 | #include "../hero.h" 4 | #include "../PHL.h" 5 | #include "../game.h" 6 | #include 7 | 8 | void knightDestroy(Knight* k); 9 | 10 | void createKnight(int x, int y, int type) 11 | { 12 | int i; 13 | for (i = 0; i < MAX_ENEMIES; i++) { 14 | if (enemies[i] == NULL) { 15 | Enemy* e = malloc(sizeof *e); 16 | Knight* k = malloc(sizeof *k); 17 | 18 | k->id = i; 19 | k->type = type; 20 | 21 | k->x = x; 22 | k->y = y; 23 | 24 | //They face the player when they are spawned 25 | k->dir = -1; 26 | if (herox > x + 20) { 27 | k->dir = 1; 28 | } 29 | 30 | k->vsp = 0; 31 | k->grav = 0.2; 32 | 33 | k->state = 0; 34 | k->timer = 60 + (((rand() % 5) + 1) * 60); 35 | k->imageIndex = 0; 36 | 37 | k->hp = 2; 38 | //Shield Knight 39 | if (k->type == 1) { 40 | k->hp = 3; 41 | } 42 | 43 | k->invincible = 0; 44 | k->shieldhit = 0; 45 | 46 | k->mask.circle = 0; 47 | k->mask.unused = 0; 48 | k->mask.x = x + 4; 49 | k->mask.y = y + 8; 50 | k->mask.w = 32; 51 | k->mask.h = 32; 52 | 53 | e->data = k; 54 | e->enemyStep = knightStep; 55 | e->enemyDraw = knightDraw; 56 | e->type = 3; 57 | 58 | enemies[i] = e; 59 | i = MAX_ENEMIES; 60 | } 61 | } 62 | } 63 | 64 | void knightStep(Knight* k) 65 | { 66 | if (k->shieldhit > 0) { 67 | k->shieldhit -= 1; 68 | } 69 | 70 | if (k->invincible > 0) { 71 | k->invincible -= 1; 72 | } 73 | 74 | if (k->state == 0) { //Walk 75 | k->imageIndex += 0.1; 76 | if (k->imageIndex >= 2) { 77 | k->imageIndex -= 2; 78 | } 79 | 80 | double spd = 1; 81 | if (k->type == 1) { 82 | spd = 0.5; 83 | } 84 | spd *= k->dir; 85 | 86 | k->x += spd; 87 | 88 | k->mask.x = k->x + 4; 89 | k->mask.y = k->y + 8; 90 | 91 | Mask emask; 92 | emask.circle = emask.unused = 0; 93 | emask.w = 16; 94 | emask.h = 32; 95 | emask.x = k->x + 12; 96 | emask.y = k->y + 8; 97 | 98 | //Turn when colliding with a wall 99 | if (checkTileCollision(1, emask)) { 100 | k->dir *= -1; 101 | }else{ 102 | //Turn when on an edge 103 | k->mask.x += k->mask.w * k->dir; 104 | k->mask.y += 1; 105 | PHL_Rect collide = getTileCollision(1, k->mask); 106 | if (collide.x == -1) { 107 | collide = getTileCollision(3, k->mask); 108 | } 109 | if (collide.x == -1) { 110 | k->dir *= -1; 111 | } 112 | } 113 | 114 | if (k->x + 20 >= 640 || k->x + 20 <= 0) { 115 | k->dir *= -1; 116 | } 117 | 118 | k->mask.x = k->x + 4; 119 | k->mask.y = k->y + 8; 120 | 121 | k->timer -= 1; 122 | if (k->timer <= 0) { 123 | k->state = 1; 124 | k->timer = 120; 125 | k->imageIndex = 0; 126 | } 127 | } 128 | else if (k->state == 1) { //Wait 129 | k->timer -= 1; 130 | if (k->timer <= 0) { 131 | k->state = 0; 132 | k->dir = 1; 133 | if (herox < k->x + 20) { 134 | k->dir = -1; 135 | } 136 | k->timer = 60 + (((rand() % 5) + 1) * 60); 137 | } 138 | } 139 | 140 | //Green Sword Knight 141 | if (k->type == 0) { 142 | //Hit player 143 | Mask swordMask; 144 | swordMask.unused = 0; 145 | swordMask.circle = 0; 146 | swordMask.x = k->x + (24 * k->dir); 147 | swordMask.y = k->y + 20; 148 | swordMask.w = 40; 149 | swordMask.h = 10; 150 | 151 | if (checkCollision(getHeroMask(), swordMask)) { 152 | heroHit(30, k->x + 20); 153 | } 154 | } 155 | 156 | if (checkCollision(getHeroMask(), k->mask)) { 157 | heroHit(15, k->x + 20); 158 | } 159 | 160 | //Weapon collision 161 | int i; 162 | for (i = 0; i < MAX_WEAPONS; i++) { 163 | if (weapons[i] != NULL) { 164 | if (weapons[i]->cooldown == 0) { 165 | if (checkCollision(k->mask, weapons[i]->weaponMask)) { 166 | char gotHit = 1; 167 | 168 | int weapondir = weapons[i]->dir; 169 | weaponHit(weapons[i]); 170 | 171 | //Shield Collision 172 | if (k->type == 1) { 173 | if (weapondir == k->dir * -1) { 174 | gotHit = 0; 175 | k->shieldhit = 15; 176 | PHL_PlaySound(sounds[sndHit03], CHN_WEAPONS); 177 | } 178 | } 179 | 180 | if (gotHit == 1) { 181 | k->hp -= 1; 182 | k->invincible = 15; 183 | 184 | i = MAX_WEAPONS; 185 | } 186 | 187 | if (k->hp <= 0) { 188 | knightDestroy(k); 189 | } 190 | } 191 | } 192 | } 193 | } 194 | } 195 | 196 | void knightDraw(Knight* k) 197 | { 198 | if (k->invincible % 2 == 0) { 199 | int cx = 0, cy = 200; 200 | 201 | //Green Knight's Sword 202 | if (k->type == 0) { 203 | int swordimg = 0; 204 | if (k->dir == -1) { 205 | swordimg = 1; 206 | } 207 | int posx = 24, posy = 8; 208 | if ((int)k->imageIndex == 1) { 209 | posx -= 2; 210 | posy -= 2; 211 | } 212 | PHL_DrawSurfacePart(k->x + (posx * k->dir), k->y + posy, 160 + (swordimg * 40), 200, 40, 40, images[imgEnemies]); 213 | } 214 | 215 | //Shield Knight 216 | if (k->type == 1) { 217 | cx = 240; 218 | } 219 | 220 | if (k->dir == -1) { 221 | cx += 80; 222 | } 223 | PHL_DrawSurfacePart(k->x, k->y, cx + ((int)k->imageIndex * 40), cy, 40, 40, images[imgEnemies]); 224 | } 225 | } 226 | 227 | void knightDestroy(Knight* k) 228 | { 229 | createEffect(2, k->x - 12, k->y - 6); 230 | spawnCollectable(k->x + 20, k->y); 231 | enemyDestroy(k->id); 232 | } -------------------------------------------------------------------------------- /source/enemies/thwomp.c: -------------------------------------------------------------------------------- 1 | #include "thwomp.h" 2 | #include "../enemy.h" 3 | #include "../hero.h" 4 | #include "../game.h" 5 | #include "../PHL.h" 6 | #include "../effect.h" 7 | #include 8 | 9 | void thwompStep(Thwomp* t); 10 | void thwompDraw(Thwomp* t); 11 | 12 | void createThwomp(int x, int y, int type, int offset, int delay, int dir) 13 | { 14 | int i; 15 | for (i = 0; i < MAX_ENEMIES; i++) { 16 | if (enemies[i] == NULL) { 17 | Enemy* e = malloc(sizeof *e); 18 | Thwomp* t = malloc(sizeof *t); 19 | 20 | t->id = i; 21 | 22 | t->x = x; 23 | t->y = y; 24 | 25 | t->vsp = 0; 26 | t->grav = 0.3; 27 | 28 | t->imageIndex = 0; 29 | 30 | t->type = type; 31 | t->state = 0; 32 | t->timer = offset * 30; 33 | t->delay = delay * 30; 34 | //default delay is 60 35 | if (delay == 0) { 36 | t->delay = 60; 37 | } 38 | 39 | t->dir = dir; 40 | 41 | t->hp = 3; 42 | t->blink = 0; 43 | 44 | e->data = t; 45 | e->enemyStep = thwompStep; 46 | e->enemyDraw = thwompDraw; 47 | e->type = 16; 48 | 49 | enemies[i] = e; 50 | i = MAX_ENEMIES; 51 | } 52 | } 53 | } 54 | 55 | void thwompStep(Thwomp* t) 56 | { 57 | //Animate 58 | { 59 | t->imageIndex += 0.1; 60 | if (t->imageIndex >= 3) { 61 | t->imageIndex -= 3; 62 | } 63 | } 64 | 65 | //Counters 66 | { 67 | if (t->blink > 0) { 68 | t->blink -= 1; 69 | } 70 | } 71 | 72 | //Setup Mask 73 | Mask mask; 74 | { 75 | mask.unused = mask.circle = 0; 76 | mask.w = mask.h = 36; 77 | mask.x = t->x + ((40 - mask.w) / 2); 78 | mask.y = t->y + ((40 - mask.h) / 2); 79 | } 80 | 81 | //Wait 82 | if (t->state == 0) { 83 | t->vsp = 0; 84 | 85 | //Waiter 86 | if (t->type == 0) { 87 | Mask area; 88 | area.unused = area.circle = 0; 89 | area.x = t->x - 40; 90 | area.y = t->y; 91 | area.w = 120; 92 | area.h = 160; 93 | 94 | if (checkCollisionXY(area, herox, heroy)) { 95 | t->state = 1; 96 | } 97 | } 98 | 99 | //Automatic 100 | else{ 101 | t->timer -= 1; 102 | if (t->timer <= 0) { 103 | t->state = 1; 104 | } 105 | } 106 | } 107 | 108 | //Fall 109 | else if (t->state == 1) { 110 | //Down 111 | if (t->dir == 0) { 112 | t->y += t->vsp; 113 | } 114 | //Left 115 | if (t->dir == 1) { 116 | t->x -= t->vsp; 117 | } 118 | //Right 119 | if (t->dir == 2) { 120 | t->x += t->vsp; 121 | } 122 | 123 | t->vsp += t->grav; 124 | 125 | if (t->vsp >= 7) { 126 | t->vsp = 7; 127 | } 128 | 129 | //Update Mask 130 | mask.x = t->x + ((40 - mask.w) / 2); 131 | mask.y = t->y + ((40 - mask.h) / 2); 132 | 133 | PHL_Rect collide = getTileCollision(1, mask); 134 | if (collide.x != -1) { 135 | int effX = t->x, 136 | effY = t->y; 137 | //Down 138 | if (t->dir == 0) { 139 | t->y = collide.y - 40; 140 | effY = t->y + 20; 141 | } 142 | //Left 143 | if (t->dir == 1) { 144 | t->x = collide.x + 40; 145 | effX = t->x - 20; 146 | } 147 | //Right 148 | if (t->dir == 2) { 149 | t->x = collide.x - 40; 150 | effX = t->x + 20; 151 | } 152 | 153 | t->state = 2; 154 | t->timer = 60; 155 | createEffect(1, effX, effY); 156 | PHL_PlaySound(sounds[sndHit07], CHN_ENEMIES); 157 | } 158 | } 159 | else if (t->state == 2) { 160 | if (t->type == 1) { //Automatic 161 | t->timer -= 1; 162 | if (t->timer <= 0) { 163 | t->state = 3; 164 | } 165 | } 166 | } 167 | else if (t->state == 3) { //rise up 168 | //Down 169 | if (t->dir == 0) { 170 | t->y -= 2; 171 | } 172 | //Left 173 | if (t->dir == 1) { 174 | t->x += 2; 175 | } 176 | //Right 177 | if (t->dir == 2) { 178 | t->x -= 2; 179 | } 180 | 181 | //Update Mask 182 | mask.x = t->x + ((40 - mask.w) / 2); 183 | mask.y = t->y + ((40 - mask.h) / 2); 184 | 185 | if (t->dir == 0) { 186 | mask.y -= 4; 187 | } 188 | if (t->dir == 1) { 189 | mask.x += 4; 190 | } 191 | if (t->dir == 2) { 192 | mask.x -= 4; 193 | } 194 | 195 | PHL_Rect collide = getTileCollision(1, mask); 196 | if (collide.x != -1) { 197 | //Down 198 | if (t->dir == 0) { 199 | t->y = collide.y + 40 + 2; 200 | } 201 | //Left 202 | if (t->dir == 1) { 203 | t->x = collide.x - 40 + 2; 204 | } 205 | //Right 206 | if (t->dir == 2) { 207 | t->x = collide.x + 40 + 2; 208 | } 209 | 210 | t->state = 0; 211 | t->timer = t->delay; 212 | } 213 | } 214 | 215 | //Update Mask 216 | { 217 | mask.x = t->x + ((40 - mask.w) / 2); 218 | mask.y = t->y + ((40 - mask.h) / 2); 219 | } 220 | 221 | //Hit Player 222 | { 223 | if (checkCollision(mask, getHeroMask())) { 224 | heroHit(15, mask.x + (mask.w / 2)); 225 | } 226 | } 227 | 228 | //Weapon collision 229 | { 230 | int i; 231 | for (i = 0; i < MAX_WEAPONS; i++) { 232 | if (weapons[i] != NULL) { 233 | if (weapons[i]->cooldown == 0) { 234 | if (checkCollision(mask, weapons[i]->weaponMask)) { 235 | weaponHit(weapons[i]); 236 | 237 | if (hasItem[16] == 1) { //Has blue paper 238 | t->hp -= 1; 239 | t->blink = 15; 240 | 241 | if (t->hp <= 0) { 242 | createRockSmash(t->x + 20, t->y + 20); 243 | spawnCollectable(t->x + 20, t->y); 244 | enemyDestroy(t->id); 245 | } 246 | }else{ 247 | //Tink 248 | PHL_PlaySound(sounds[sndHit03], CHN_WEAPONS); 249 | } 250 | 251 | i = MAX_WEAPONS; 252 | } 253 | } 254 | } 255 | } 256 | } 257 | 258 | } 259 | 260 | void thwompDraw(Thwomp* t) 261 | { 262 | if (t->blink % 2 == 0) { 263 | PHL_DrawSurfacePart(t->x, t->y, 240 + ((int)t->imageIndex * 40), 400, 40, 40, images[imgMisc20]); 264 | } 265 | } -------------------------------------------------------------------------------- /source/psp/graphics.c: -------------------------------------------------------------------------------- 1 | #include "graphics.h" 2 | #include "../game.h" 3 | #include "../qda.h" 4 | 5 | int screenOffsetX = 80; 6 | int screenOffsetY = 16; 7 | int fullscreen = 0; 8 | int blurFilter = 0; 9 | 10 | //One time graphics setup 11 | void PHL_GraphicsInit() 12 | { 13 | oslInit(0); 14 | oslInitGfx(OSL_PF_8888, 1); 15 | 16 | screen = oslCreateImage(320, 240, OSL_IN_VRAM, OSL_PF_5650); 17 | 18 | PHL_StartDrawing(); 19 | } 20 | 21 | void PHL_GraphicsExit() 22 | { 23 | oslEndGfx(); 24 | oslDeleteImage(screen); 25 | 26 | //closeQDA(); 27 | } 28 | 29 | void PHL_StartDrawing() 30 | { 31 | oslStartDrawing(); 32 | oslSetDrawBuffer(screen); 33 | } 34 | 35 | void PHL_EndDrawing() 36 | { 37 | oslSetDrawBuffer(OSL_DEFAULT_BUFFER); 38 | 39 | oslSetBilinearFilter(blurFilter); 40 | oslDrawImageXY(screen, screenOffsetX, screenOffsetY); 41 | oslSetBilinearFilter(0); 42 | 43 | oslEndDrawing(); 44 | oslEndFrame(); 45 | oslSyncFrame(); 46 | } 47 | 48 | void PHL_ForceScreenUpdate() 49 | { 50 | oslSetDrawBuffer(OSL_DEFAULT_BUFFER); 51 | oslDrawImageXY(screen, screenOffsetX, screenOffsetY); 52 | oslEndDrawing(); 53 | oslAudioVSync(); 54 | oslSyncFrame(); 55 | 56 | oslStartDrawing(); 57 | oslSetDrawBuffer(screen); 58 | } 59 | 60 | void PHL_SetDrawbuffer(OSL_IMAGE* surf) 61 | { 62 | //unused in psp version 63 | } 64 | 65 | void PHL_ResetDrawbuffer() 66 | { 67 | //unused in psp version 68 | } 69 | 70 | void PHL_SetColorKey(OSL_IMAGE* surf, int r, int g, int b) 71 | { 72 | 73 | } 74 | 75 | OSL_IMAGE* PHL_NewSurface(int w, int h) 76 | { 77 | OSL_IMAGE* surf = oslCreateImage(w, h, OSL_IN_RAM, OSL_PF_8BIT); 78 | 79 | return surf; 80 | } 81 | 82 | void PHL_FreeSurface(OSL_IMAGE* surf) 83 | { 84 | if (surf) { 85 | oslDeleteImage(surf); 86 | surf = NULL; 87 | } 88 | } 89 | 90 | OSL_IMAGE* PHL_LoadBMP(int index) 91 | { 92 | OSL_IMAGE* result = NULL; 93 | 94 | FILE* f; 95 | if ( (f = fopen("bmp.qda", "rb")) ) { 96 | //Load QDA file data 97 | unsigned char* QDAFile = (unsigned char*)malloc(headers[index].size); 98 | fseek(f, headers[index].offset, SEEK_SET); 99 | fread(QDAFile, headers[index].size, 1, f); 100 | 101 | OSL_COLOR palette[20][18]; 102 | 103 | //Read data from header 104 | unsigned short w, h; 105 | 106 | memcpy(&w, &QDAFile[18], 2); 107 | memcpy(&h, &QDAFile[22], 2); 108 | 109 | result = oslCreateImage(w, h, OSL_IN_RAM, OSL_PF_8888); 110 | oslUnswizzleImage(result); 111 | oslClearImage(result, RGBA(255, 255, 255, 255)); 112 | 113 | //Load Palette 114 | int dx, dy; 115 | int count = 0; 116 | for (dx = 0; dx < 20; dx++) { 117 | for (dy = 0; dy < 16; dy++) { 118 | palette[dx][dy] = RGB(QDAFile[54 + count + 2], QDAFile[54 + count + 1], QDAFile[54 + count]); 119 | count += 4; 120 | } 121 | } 122 | 123 | OSL_COLOR alphaKey = palette[0][0]; 124 | 125 | //Darkness special case 126 | if (index == 27) { 127 | alphaKey = RGB(0, 0, 0); 128 | } 129 | 130 | //Edit surface pixels 131 | oslLockImage(result); 132 | for (dx = w; dx > 0; dx--) { 133 | for (dy = h; dy >= 0; dy--) { 134 | int pix = w - dx + w * dy; 135 | 136 | int px = QDAFile[1078 + pix] / 16; 137 | int py = QDAFile[1078 + pix] % 16; 138 | 139 | if (palette[px][py] == alphaKey) { 140 | oslSetImagePixel(result, w - dx, h - dy - 1, RGBA(0, 0, 0, 0)); 141 | }else{ 142 | oslSetImagePixel(result, w - dx, h - dy - 1, palette[px][py]); 143 | } 144 | } 145 | } 146 | oslUnlockImage(result); 147 | 148 | oslSwizzleImage(result); 149 | 150 | free(QDAFile); 151 | } 152 | 153 | fclose(f); 154 | 155 | return result; 156 | } 157 | 158 | void PHL_DrawRect(int x, int y, int w, int h, OSL_COLOR col) 159 | { 160 | oslDrawFillRect(x/2, y/2, (x + w) / 2, (y + h) / 2, col); 161 | } 162 | 163 | void PHL_DrawSurface(double x, double y, OSL_IMAGE* surface) 164 | { 165 | oslDrawImageXY(surface, (int)(x/2), (int)(y/2)); 166 | } 167 | 168 | void PHL_DrawSurfacePart(double x, double y, int cropx, int cropy, int cropw, int croph, OSL_IMAGE* surface) 169 | { 170 | //Consider earthquake 171 | if (quakeTimer > 0) { 172 | int val = quakeTimer % 4; 173 | if (val == 0) { 174 | y -= 2; 175 | }else if (val == 2) { 176 | y += 2; 177 | } 178 | } 179 | 180 | OSL_IMAGE *crop = oslCreateImageTileSize(surface, cropx/2, cropy/2, cropw/2, croph/2); 181 | oslDrawImageXY(crop, (int)(x/2), (int)(y/2)); 182 | oslDeleteImage(crop); 183 | } 184 | 185 | void PHL_DrawBackground(PHL_Background back, PHL_Background fore) 186 | { 187 | int xx, yy; 188 | 189 | for (yy = 0; yy < 12; yy++) 190 | { 191 | for (xx = 0; xx < 16; xx++) 192 | { 193 | //Draw Background tiles 194 | PHL_DrawSurfacePart(xx * 40, yy * 40, back.tileX[xx][yy] * 40, back.tileY[xx][yy] * 40, 40, 40, images[imgTiles]); 195 | 196 | //Only draw foreground tile if not a blank tile 197 | if (fore.tileX[xx][yy] != 0 || fore.tileY[xx][yy] != 0) { 198 | PHL_DrawSurfacePart(xx * 40, yy * 40, fore.tileX[xx][yy] * 40, fore.tileY[xx][yy] * 40, 40, 40, images[imgTiles]); 199 | } 200 | } 201 | } 202 | } 203 | 204 | void PHL_UpdateBackground(PHL_Background back, PHL_Background fore) 205 | { 206 | //Unused in psp version 207 | } 208 | 209 | void setBlur(int blur) 210 | { 211 | blurFilter = blur; 212 | } 213 | 214 | int getBlur() 215 | { 216 | return blurFilter; 217 | } 218 | 219 | void setScreenSize(int size) 220 | { 221 | int screenW = 320; 222 | int screenH = 240; 223 | 224 | if (size == 1) { 225 | screenW = 368; 226 | screenH = 272; 227 | } 228 | if (size == 2) { 229 | screenW = 480; 230 | screenH = 272; 231 | } 232 | 233 | screenOffsetX = (480 - screenW) / 2; 234 | screenOffsetY = (272 - screenH) / 2; 235 | 236 | screen->stretchX = screenW; 237 | screen->stretchY = screenH; 238 | } 239 | 240 | int getScreenSize() 241 | { 242 | if (screen->stretchX == 368) { 243 | return 1; 244 | } 245 | if (screen->stretchX == 480) { 246 | return 2; 247 | } 248 | return 0; 249 | } -------------------------------------------------------------------------------- /source/enemies/boomknight.c: -------------------------------------------------------------------------------- 1 | #include "boomknight.h" 2 | #include "../game.h" 3 | #include "../hero.h" 4 | #include 5 | 6 | void boomknightStep(Boomknight* b); 7 | void boomknightDraw(Boomknight* b); 8 | 9 | void boomStep(Boom* b); 10 | void boomDraw(Boom* b); 11 | 12 | void createBoomknight(int x, int y) 13 | { 14 | int i; 15 | for (i = 0; i < MAX_ENEMIES; i++) { 16 | if (enemies[i] == NULL) { 17 | Enemy* e = malloc(sizeof *e); 18 | Boomknight* b = malloc(sizeof *b); 19 | b->id = i; 20 | 21 | b->hp = 2; 22 | b->blink = 0; 23 | 24 | b->x = x; 25 | b->y = y; 26 | 27 | b->dir = 1; 28 | if (herox < b->x + 20) { 29 | b->dir = -1; 30 | } 31 | 32 | b->imageIndex = 0; 33 | 34 | b->state = 0; 35 | b->timer = 0; 36 | 37 | e->data = b; 38 | e->enemyStep = boomknightStep; 39 | e->enemyDraw = boomknightDraw; 40 | e->type = 31; 41 | 42 | enemies[i] = e; 43 | i = MAX_ENEMIES; 44 | } 45 | } 46 | } 47 | 48 | void boomknightStep(Boomknight* b) 49 | { 50 | //Animate 51 | { 52 | b->imageIndex += 0.1; 53 | if (b->imageIndex >= 2) { 54 | b->imageIndex -= 2; 55 | } 56 | 57 | if (b->blink > 0) { 58 | b->blink -= 1; 59 | } 60 | } 61 | 62 | //Setup Mask 63 | Mask mask; 64 | { 65 | mask.circle = mask.unused = 0; 66 | mask.w = 30; 67 | mask.h = 32; 68 | mask.x = b->x + ((40 - mask.w) / 2); 69 | mask.y = b->y + (40 - mask.h); 70 | } 71 | 72 | //Walk 73 | if (b->state == 0) { 74 | //Movement 75 | { 76 | double hsp = 0.5; 77 | b->x += hsp * b->dir; 78 | mask.x = b->x + ((40 - mask.w) / 2); 79 | } 80 | 81 | //Hit wall 82 | { 83 | if (checkTileCollision(1, mask) == 1) { 84 | b->dir *= -1; 85 | } 86 | } 87 | 88 | //On edge 89 | { 90 | mask.x += mask.w * b->dir; 91 | mask.y += 20; 92 | 93 | PHL_Rect collide = getTileCollision(1, mask); 94 | if (collide.x == -1) { 95 | collide = getTileCollision(3, mask); 96 | } 97 | 98 | if (collide.x == -1) { 99 | b->dir *= -1; 100 | } 101 | } 102 | 103 | //Player is close 104 | { 105 | if (b->timer <= 0) { 106 | Mask area; 107 | { 108 | area.circle = area.unused = 0; 109 | area.w = 120; 110 | area.h = 40; 111 | area.x = b->x + 20; 112 | if (b->dir == -1) { 113 | area.x -= area.w; 114 | } 115 | area.y = b->y; 116 | } 117 | if (checkCollision(area, getHeroMask()) == 1) { 118 | b->state = 1; 119 | b->timer = 0; 120 | } 121 | 122 | }else{ 123 | b->timer -= 1; 124 | } 125 | } 126 | 127 | } 128 | 129 | //Throw 130 | else if (b->state == 1) { 131 | //Animate 132 | { 133 | b->imageIndex = 0; 134 | if (b->timer >= 15) { 135 | b->imageIndex = 2; 136 | } 137 | } 138 | 139 | b->timer += 1; 140 | if (b->timer == 15) { 141 | createBoom(b->x, b->y, b->dir); 142 | PHL_PlaySound(sounds[sndPi05], CHN_ENEMIES); 143 | } 144 | 145 | if (b->timer >= 110) { 146 | b->state = 0; 147 | b->imageIndex = 0; 148 | b->timer = 120; 149 | } 150 | } 151 | 152 | //Update Mask 153 | mask.x = b->x + ((40 - mask.w) / 2); 154 | mask.y = b->y + (40 - mask.h); 155 | 156 | //Hero Collision 157 | { 158 | if (checkCollision(mask, getHeroMask()) == 1) { 159 | heroHit(15, mask.x + (mask.w / 2)); 160 | } 161 | } 162 | 163 | //Weapon Collision 164 | { 165 | int i; 166 | for (i = 0; i < MAX_WEAPONS; i++) { 167 | if (weapons[i] != NULL) { 168 | if (weapons[i]->cooldown == 0) { 169 | if (checkCollision(mask, weapons[i]->weaponMask)) { 170 | weaponHit(weapons[i]); 171 | 172 | b->hp -= 1; 173 | b->blink = 15; 174 | 175 | //Death 176 | if (b->hp <= 0) { 177 | createEffect(2, b->x - 12, b->y - 6); 178 | spawnCollectable(b->x + 20, b->y); 179 | enemyDestroy(b->id); 180 | } 181 | 182 | i = MAX_WEAPONS; 183 | } 184 | } 185 | } 186 | } 187 | } 188 | 189 | } 190 | 191 | void boomknightDraw(Boomknight* b) 192 | { 193 | if (b->blink % 2 == 0) { 194 | int cropX = 400 + ((int)b->imageIndex * 40); 195 | 196 | if (b->dir == -1) { 197 | cropX += 120; 198 | } 199 | 200 | PHL_DrawSurfacePart(b->x, b->y, cropX, 400, 40, 40, images[imgEnemies]); 201 | } 202 | } 203 | 204 | 205 | //Enemy boomerang 206 | void createBoom(int x, int y, int dir) 207 | { 208 | int i; 209 | for (i = 0; i < MAX_ENEMIES; i++) { 210 | if (enemies[i] == NULL) { 211 | Enemy* e = malloc(sizeof *e); 212 | Boom* b = malloc(sizeof *b); 213 | b->id = i; 214 | 215 | b->dir = dir; 216 | b->x = x; 217 | b->y = y; 218 | 219 | b->hsp = 6 * b->dir; 220 | b->imageIndex = 0; 221 | 222 | b->timer = 90; 223 | 224 | e->data = b; 225 | e->enemyStep = boomStep; 226 | e->enemyDraw = boomDraw; 227 | e->type = -1; 228 | 229 | enemies[i] = e; 230 | i = MAX_ENEMIES; 231 | } 232 | } 233 | } 234 | 235 | void boomStep(Boom* b) 236 | { 237 | //Animate 238 | { 239 | b->imageIndex += 0.33; 240 | if (b->imageIndex >= 8) { 241 | b->imageIndex -= 8; 242 | } 243 | } 244 | 245 | //Movement 246 | { 247 | b->x += b->hsp; 248 | 249 | double fric = 0.125; 250 | b->hsp -= fric * b->dir; 251 | } 252 | 253 | //Hero collision 254 | { 255 | Mask mask; 256 | { 257 | mask.circle = mask.unused = 0; 258 | mask.w = 24; 259 | mask.h = 24; 260 | mask.x = b->x + ((40 - mask.w) / 2); 261 | mask.y = b->y + ((40 - mask.h) / 2); 262 | } 263 | 264 | if (checkCollision(mask, getHeroMask()) == 1) { 265 | heroHit(10, mask.x + (mask.w / 2)); 266 | } 267 | } 268 | 269 | b->timer -= 1; 270 | if (b->timer <= 0) { 271 | createEffectExtra(5, b->x + 20, b->y + 20, 0, 0, 0); 272 | enemyDestroy(b->id); 273 | } 274 | } 275 | 276 | void boomDraw(Boom* b) 277 | { 278 | int cropX = (int)b->imageIndex * 40; 279 | 280 | if (b->dir == -1) { 281 | cropX += 320; 282 | } 283 | 284 | PHL_DrawSurfacePart(b->x, b->y, cropX, 360, 40, 40, images[imgMisc20]); 285 | } -------------------------------------------------------------------------------- /source/enemies/dog.c: -------------------------------------------------------------------------------- 1 | #include "dog.h" 2 | #include "../game.h" 3 | #include "../hero.h" 4 | #include 5 | 6 | void dogStep(Dog* d); 7 | void dogDraw(Dog* d); 8 | 9 | int hitWall(Dog* d, Mask mask); 10 | 11 | void createDog(int x, int y) 12 | { 13 | int i; 14 | for (i = 0; i < MAX_ENEMIES; i++) { 15 | if (enemies[i] == NULL) { 16 | Enemy* e = malloc(sizeof *e); 17 | Dog* d = malloc(sizeof *d); 18 | d->id = i; 19 | d->hp = 3; 20 | d->blink = 0; 21 | 22 | d->x = x; 23 | d->y = y; 24 | 25 | d->hsp = 0; 26 | d->vsp = 0; 27 | 28 | d->imageIndex = 0; 29 | 30 | d->dir = 1; 31 | if (herox < d->x) { 32 | d->dir = -1; 33 | } 34 | 35 | d->state = 0; 36 | d->timer = 0; 37 | d->counter = 0; 38 | 39 | e->data = d; 40 | e->enemyStep = dogStep; 41 | e->enemyDraw = dogDraw; 42 | e->type = 30; 43 | 44 | enemies[i] = e; 45 | i = MAX_ENEMIES; 46 | } 47 | } 48 | } 49 | 50 | void dogStep(Dog* d) 51 | { 52 | double grav = 0.175; 53 | 54 | char onground = 0; 55 | char wallhit = 0; 56 | 57 | //Setup Mask 58 | Mask mask; 59 | { 60 | mask.circle = mask.unused = 0; 61 | mask.w = 32; 62 | mask.h = 32; 63 | mask.x = d->x + ((40 - mask.w) / 2); 64 | mask.y = d->y + (40 - mask.h); 65 | } 66 | 67 | //Blink animation 68 | { 69 | if (d->blink > 0) { 70 | d->blink -= 1; 71 | } 72 | } 73 | 74 | //Horizontal movement 75 | { 76 | d->x += d->hsp; 77 | mask.x = d->x + ((40 - mask.w) / 2); 78 | 79 | //Wall collision 80 | if (hitWall(d, mask) == 1) { 81 | wallhit = 1; 82 | mask.x = d->x + ((40 - mask.w) / 2); 83 | } 84 | } 85 | 86 | //Vertical Movement 87 | { 88 | d->vsp += grav; 89 | d->y += d->vsp; 90 | mask.y = d->y + (40 - mask.h); 91 | 92 | PHL_Rect collide = getTileCollision(1, mask); 93 | if (collide.x == -1) { 94 | collide = getTileCollision(3, mask); 95 | } 96 | if (collide.x != -1) { 97 | //Floor 98 | if (d->vsp >= 0) { 99 | onground = 1; 100 | d->vsp = 0; 101 | d->y = collide.y - 40; 102 | } 103 | //Ceiling 104 | if (d->vsp < 0) { 105 | d->y = collide.y + 40 - (40 - mask.h); 106 | } 107 | mask.y = d->y + (40 - mask.h); 108 | } 109 | } 110 | 111 | //Wait 112 | if (d->state == 0) 113 | { 114 | double fric = 0.1; 115 | 116 | //Animate 117 | { 118 | d->imageIndex += 0.1; 119 | if (d->imageIndex >= 2) { 120 | d->imageIndex -= 2; 121 | } 122 | } 123 | 124 | //Collide with wall 125 | { 126 | if (wallhit == 1 && onground == 1) { 127 | d->hsp *= -1; 128 | } 129 | } 130 | 131 | //Slide to hault 132 | if (d->hsp > 0) { 133 | d->dir = 1; 134 | 135 | d->hsp -= fric; 136 | if (d->hsp <= 0) { 137 | d->hsp = 0; 138 | } 139 | } 140 | if (d->hsp < 0) { 141 | d->dir = -1; 142 | 143 | d->hsp += fric; 144 | if (d->hsp >= 0) { 145 | d->hsp = 0; 146 | } 147 | } 148 | 149 | //Player is close 150 | { 151 | if (d->hsp == 0) { 152 | Mask area; 153 | area.unused = area.circle = 0; 154 | area.w = 220; 155 | area.h = 60; 156 | area.x = d->x - 90; 157 | area.y = d->y - 20; 158 | 159 | if (checkCollision(area, getHeroMask()) == 1) { 160 | d->state = 1; 161 | d->counter = 0; 162 | d->vsp = 1; 163 | } 164 | } 165 | } 166 | 167 | } 168 | 169 | //Hopping 170 | else if (d->state == 1) 171 | { 172 | int spd = 2; 173 | 174 | d->hsp = spd * d->dir; 175 | 176 | //Land on floor 177 | { 178 | if (onground == 1) { 179 | 180 | //Landed 181 | d->counter += 1; 182 | d->vsp = -1.5; 183 | if (d->counter == 3) { 184 | d->vsp = -4; 185 | } 186 | if (d->counter == 4) { 187 | d->state = 0; 188 | d->counter = 0; 189 | d->vsp = 0; 190 | d->hsp = spd * d->dir; 191 | }else{ 192 | PHL_PlaySound(sounds[sndPi05], CHN_ENEMIES); 193 | d->dir = 1; 194 | if (herox < d->x + 20) { 195 | d->dir = -1; 196 | } 197 | } 198 | } 199 | } 200 | 201 | //Animate 202 | { 203 | d->imageIndex = 1; 204 | if (d->vsp < 0) { 205 | d->imageIndex = 2; 206 | } 207 | } 208 | 209 | } 210 | 211 | //Update mask to be safe 212 | mask.x = d->x + ((40 - mask.w) / 2); 213 | mask.y = d->y + (40 - mask.h); 214 | 215 | //Hit Player 216 | { 217 | if (checkCollision(mask, getHeroMask())) { 218 | if (heroHit(10, mask.x + (mask.w / 2)) == 1) { 219 | heroStun(); 220 | } 221 | } 222 | } 223 | 224 | //Weapon collision 225 | { 226 | int i; 227 | for (i = 0; i < MAX_WEAPONS; i++) { 228 | if (weapons[i] != NULL) { 229 | if (weapons[i]->cooldown == 0) { 230 | if (checkCollision(mask, weapons[i]->weaponMask)) { 231 | weaponHit(weapons[i]); 232 | //Hit 233 | d->blink = 15; 234 | d->hp -= 1; 235 | 236 | //Death 237 | if (d->hp <= 0) { 238 | createEffect(2, d->x - 12, d->y - 6); 239 | spawnCollectable(d->x + 20, d->y); 240 | enemyDestroy(d->id); 241 | } 242 | 243 | i = MAX_WEAPONS; 244 | } 245 | } 246 | } 247 | } 248 | } 249 | 250 | } 251 | 252 | void dogDraw(Dog* d) 253 | { 254 | if (d->blink % 2 == 0) { 255 | int cropX = 240 + ((int)d->imageIndex * 40); 256 | 257 | if (d->dir == -1) { 258 | cropX += 120; 259 | } 260 | 261 | PHL_DrawSurfacePart(d->x, d->y, cropX, 40, 40, 40, images[imgEnemies]); 262 | } 263 | } 264 | 265 | int hitWall(Dog* d, Mask mask) 266 | { 267 | PHL_Rect collide = getTileCollision(1, mask); 268 | 269 | if (collide.x == -1) { 270 | collide = getTileCollision(3, mask); 271 | } 272 | 273 | if (collide.x != -1) { 274 | int dir = 1; 275 | if (d->hsp < 0) { 276 | dir = -1; 277 | } 278 | d->x = collide.x + 20 - ((20 + (mask.w / 2)) * dir) - 20; 279 | 280 | return 1; 281 | }else{ 282 | if (d->x < -20) { 283 | d->x = -20; 284 | return 1; 285 | } 286 | 287 | if (d->x > 620) { 288 | d->x = 620; 289 | return 1; 290 | } 291 | } 292 | 293 | return 0; 294 | } -------------------------------------------------------------------------------- /source/enemies/firewheel.c: -------------------------------------------------------------------------------- 1 | #include "firewheel.h" 2 | #include "../game.h" 3 | #include "../PHL.h" 4 | #include "../hero.h" 5 | #include 6 | 7 | void firewheelRotate(Firewheel* f, int clockwise); 8 | 9 | void firewheelStep(Firewheel* f); 10 | void firewheelDraw(Firewheel* f); 11 | 12 | void createFirewheel(int x, int y, int dir) 13 | { 14 | int i; 15 | for (i = 0; i < MAX_ENEMIES; i++) { 16 | if (enemies[i] == NULL) { 17 | Enemy* e = malloc(sizeof *e); 18 | Firewheel* f = malloc(sizeof *f); 19 | 20 | f->id = i; 21 | 22 | f->x = x; 23 | f->y = y; 24 | 25 | f->imageIndex = 0; 26 | 27 | f->hp = 2; 28 | f->blink = 0; 29 | 30 | f->hsp = 1; 31 | f->vsp = 0; 32 | 33 | f->wallx = 0; 34 | f->wally = 1; 35 | 36 | f->timer = 0; 37 | if (x % 40 != 0) { 38 | f->timer = 20; 39 | } 40 | 41 | //Start on ceiling 42 | { 43 | Mask mask; 44 | mask.circle = mask.unused = 0; 45 | mask.w = 40; 46 | mask.h = 40; 47 | mask.x = f->x; 48 | mask.y = f->y + 10; 49 | 50 | PHL_Rect collide = getTileCollision(1, mask); 51 | if (collide.x == -1) { 52 | collide = getTileCollision(3, mask); 53 | } 54 | 55 | if (collide.x == -1) { 56 | f->wally = -1; 57 | f->hsp *= -1; 58 | } 59 | } 60 | 61 | f->dir = 1; 62 | if (dir == 1) { 63 | f->hsp *= -1; 64 | f->dir = -1; 65 | } 66 | 67 | e->data = f; 68 | e->enemyStep = firewheelStep; 69 | e->enemyDraw = firewheelDraw; 70 | e->type = 27; 71 | 72 | enemies[i] = e; 73 | i = MAX_ENEMIES; 74 | } 75 | } 76 | } 77 | 78 | void firewheelStep(Firewheel* f) 79 | { 80 | //Animate 81 | { 82 | f->imageIndex += 0.33; 83 | if (f->imageIndex >= 4) { 84 | f->imageIndex -= 4; 85 | } 86 | 87 | if (f->blink > 0) { 88 | f->blink -= 1; 89 | } 90 | } 91 | 92 | //Movement 93 | int spd = 2; 94 | f->x += spd * f->hsp; 95 | f->y += spd * f->vsp; 96 | 97 | //Setup mask 98 | Mask mask; 99 | mask.circle = mask.unused = 0; 100 | mask.w = 40; 101 | mask.h = 40; 102 | mask.x = f->x; 103 | mask.y = f->y; 104 | 105 | //Check if ready to change angle 106 | if ( (f->hsp != 0 && (int)f->x % 20 == 0) || (f->vsp != 0 && (int)f->y % 20 == 0) ) 107 | { 108 | int doCheck = 1; 109 | while (doCheck == 1) { 110 | doCheck = 0; 111 | 112 | //Check on edge 113 | mask.x += (f->wallx * 10); 114 | mask.y += (f->wally * 10); 115 | 116 | PHL_Rect collide = getTileCollision(1, mask); 117 | if (collide.x == -1) { 118 | collide = getTileCollision(3, mask); 119 | } 120 | 121 | //Outside of room 122 | if (f->y <= -40) { 123 | collide.x = 1; 124 | } 125 | 126 | //On edge 127 | if (collide.x == -1) { 128 | int tempHsp = f->hsp; 129 | int tempVsp = f->vsp; 130 | f->hsp = f->wallx; 131 | f->vsp = f->wally; 132 | 133 | f->wallx = -tempHsp; 134 | f->wally = -tempVsp; 135 | doCheck = 1; 136 | } 137 | //Hit wall 138 | else { 139 | mask.x = f->x; 140 | mask.y = f->y; 141 | mask.x += f->hsp * 10; 142 | mask.y += f->vsp * 10; 143 | 144 | collide = getTileCollision(1, mask); 145 | if (collide.x == -1) { 146 | collide = getTileCollision(3, mask); 147 | } 148 | 149 | //Outside of room 150 | if (collide.x == -1) { 151 | if (f->y <= -40 && f->vsp != 1) { 152 | collide.x = 1; 153 | } 154 | } 155 | 156 | //Did collide with wall 157 | if (collide.x != -1) { 158 | int tempWallx = f->wallx; 159 | int tempWally = f->wally; 160 | f->wallx = f->hsp; 161 | f->wally = f->vsp; 162 | 163 | f->hsp = -tempWallx; 164 | f->vsp = -tempWally; 165 | 166 | doCheck = 1; 167 | } 168 | 169 | } 170 | } 171 | 172 | /* 173 | mask.x += f->hsp * 10; 174 | mask.y += f->vsp * 10; 175 | 176 | //Collide with wall 177 | PHL_Rect collide = getTileCollision(1, mask); 178 | if (collide.x == -1) { 179 | collide = getTileCollision(3, mask); 180 | } 181 | 182 | //Outside of room 183 | if (collide.x == -1) { 184 | if (mask.y <= 0 && f->vsp < 0) { 185 | collide.x = f->x; 186 | collide.y = -40; 187 | collide.w = 40; 188 | collide.h = 40; 189 | } 190 | } 191 | 192 | //Did collide with wall 193 | if (collide.x != -1) { 194 | int tempWallx = f->wallx; 195 | int tempWally = f->wally; 196 | f->wallx = f->hsp; 197 | f->wally = f->vsp; 198 | 199 | f->hsp = -tempWallx; 200 | f->vsp = -tempWally; 201 | } 202 | //Edge rotate 203 | else{ 204 | mask.x = f->x; 205 | mask.y = f->y; 206 | mask.x += (f->wallx * 10); 207 | mask.y += (f->wally * 10); 208 | 209 | collide = getTileCollision(1, mask); 210 | if (collide.x == -1) { 211 | collide = getTileCollision(3, mask); 212 | } 213 | 214 | if (collide.x == -1) { 215 | int tempHsp = f->hsp; 216 | int tempVsp = f->vsp; 217 | f->hsp = f->wallx; 218 | f->vsp = f->wally; 219 | 220 | f->wallx = -tempHsp; 221 | f->wally = -tempVsp; 222 | } 223 | } 224 | */ 225 | } 226 | 227 | //Update Mask 228 | mask.w = 30; 229 | mask.h = 30; 230 | mask.x = f->x + 5; 231 | mask.y = f->y + 5; 232 | 233 | //Collide with hero 234 | if (checkCollision(mask, getHeroMask())) { 235 | heroHit(20, mask.x + (mask.w / 2)); 236 | } 237 | 238 | //Weapon collision 239 | for (int i = 0; i < MAX_WEAPONS; i++) { 240 | if (weapons[i] != NULL) { 241 | if (weapons[i]->cooldown == 0) { 242 | if (checkCollision(mask, weapons[i]->weaponMask)) { 243 | weaponHit(weapons[i]); 244 | f->hp -= 1; 245 | f->blink = 15; 246 | 247 | //Death 248 | if (f->hp <= 0) { 249 | createEffect(2, f->x - 12, f->y - 12); 250 | spawnCollectable(f->x + 20, f->y); 251 | enemyDestroy(f->id); 252 | } 253 | 254 | i = MAX_WEAPONS; 255 | } 256 | } 257 | } 258 | } 259 | 260 | } 261 | 262 | void firewheelDraw(Firewheel* f) 263 | { 264 | if (f->blink % 2 == 0) { 265 | int cy = 80; 266 | if (f->dir == -1) { 267 | cy += 40; 268 | } 269 | 270 | PHL_DrawSurfacePart(f->x, f->y, 480 + ((int)f->imageIndex * 40), cy, 40, 40, images[imgEnemies]); 271 | } 272 | } -------------------------------------------------------------------------------- /Makefile.wii: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | # Clear the implicit built in rules 3 | #--------------------------------------------------------------------------------- 4 | .SUFFIXES: 5 | #--------------------------------------------------------------------------------- 6 | ifeq ($(strip $(DEVKITPPC)),) 7 | $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") 8 | endif 9 | 10 | include $(DEVKITPPC)/wii_rules 11 | 12 | #--------------------------------------------------------------------------------- 13 | # TARGET is the name of the output 14 | # BUILD is the directory where object files & intermediate files will be placed 15 | # SOURCES is a list of directories containing source code 16 | # INCLUDES is a list of directories containing extra header files 17 | #--------------------------------------------------------------------------------- 18 | TARGET := $(notdir $(CURDIR)) 19 | BUILD := build 20 | SOURCES := source 21 | SOURCES += source/wii 22 | SOURCES += source/enemies 23 | #DATA := data 24 | INCLUDES := 25 | 26 | #--------------------------------------------------------------------------------- 27 | # options for code generation 28 | #--------------------------------------------------------------------------------- 29 | 30 | CFLAGS = -g -O2 -D_WII -Wall $(MACHDEP) $(INCLUDE) 31 | CXXFLAGS = $(CFLAGS) 32 | 33 | LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map 34 | 35 | #--------------------------------------------------------------------------------- 36 | # any extra libraries we wish to link with the project 37 | #--------------------------------------------------------------------------------- 38 | LIBS := -lSDL_net -lSDL_ttf -lSDL_gfx -lSDL_mixer -lSDL_image -lsmpeg \ 39 | -lSDL -ljpeg -lpng15 -lfreetype -lvorbisidec \ 40 | -lz -lfat -lwiiuse -lbte -lwiikeyboard -logc -lm 41 | 42 | #--------------------------------------------------------------------------------- 43 | # list of directories containing libraries, this must be the top level containing 44 | # include and lib 45 | #--------------------------------------------------------------------------------- 46 | LIBDIRS := $(DEVKITPRO)/portlibs/ppc 47 | 48 | #--------------------------------------------------------------------------------- 49 | # no real need to edit anything past this point unless you need to add additional 50 | # rules for different file extensions 51 | #--------------------------------------------------------------------------------- 52 | ifneq ($(BUILD),$(notdir $(CURDIR))) 53 | #--------------------------------------------------------------------------------- 54 | 55 | export OUTPUT := $(CURDIR)/$(TARGET) 56 | 57 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 58 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 59 | 60 | export DEPSDIR := $(CURDIR)/$(BUILD) 61 | 62 | #--------------------------------------------------------------------------------- 63 | # automatically build a list of object files for our project 64 | #--------------------------------------------------------------------------------- 65 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 66 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 67 | sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 68 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) 69 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 70 | 71 | #--------------------------------------------------------------------------------- 72 | # use CXX for linking C++ projects, CC for standard C 73 | #--------------------------------------------------------------------------------- 74 | ifeq ($(strip $(CPPFILES)),) 75 | export LD := $(CC) 76 | else 77 | export LD := $(CXX) 78 | endif 79 | 80 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 81 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ 82 | $(sFILES:.s=.o) $(SFILES:.S=.o) 83 | 84 | #--------------------------------------------------------------------------------- 85 | # build a list of include paths 86 | #--------------------------------------------------------------------------------- 87 | export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ 88 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 89 | -I$(CURDIR)/$(BUILD) \ 90 | -I$(LIBOGC_INC) 91 | 92 | #--------------------------------------------------------------------------------- 93 | # build a list of library paths 94 | #--------------------------------------------------------------------------------- 95 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ 96 | -L$(LIBOGC_LIB) 97 | 98 | export OUTPUT := $(CURDIR)/$(TARGET) 99 | .PHONY: $(BUILD) clean 100 | 101 | #--------------------------------------------------------------------------------- 102 | $(BUILD): 103 | @[ -d $@ ] || mkdir -p $@ 104 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 105 | 106 | #--------------------------------------------------------------------------------- 107 | clean: 108 | @echo clean ... 109 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol 110 | 111 | #--------------------------------------------------------------------------------- 112 | run: 113 | wiiload $(TARGET).dol 114 | 115 | 116 | #--------------------------------------------------------------------------------- 117 | else 118 | 119 | DEPENDS := $(OFILES:.o=.d) 120 | 121 | #--------------------------------------------------------------------------------- 122 | # main targets 123 | #--------------------------------------------------------------------------------- 124 | $(OUTPUT).dol: $(OUTPUT).elf 125 | $(OUTPUT).elf: $(OFILES) 126 | 127 | #--------------------------------------------------------------------------------- 128 | # This rule links in binary data with the .jpg extension 129 | #--------------------------------------------------------------------------------- 130 | %.jpg.o : %.jpg 131 | #--------------------------------------------------------------------------------- 132 | @echo $(notdir $<) 133 | $(bin2o) 134 | 135 | -include $(DEPENDS) 136 | 137 | #--------------------------------------------------------------------------------- 138 | endif 139 | #--------------------------------------------------------------------------------- 140 | --------------------------------------------------------------------------------