From 1fa1177f53a8e127a87f9c9af6796a7f14270181 Mon Sep 17 00:00:00 2001 From: RodrigoDornelles Date: Wed, 1 Nov 2023 20:42:06 -0300 Subject: [PATCH] chore: desmodularize project --- CMakeLists.txt | 7 +- cocobattleroyale.c | 25 -- kokobatoru.c | 25 -- lib/globals.h | 143 --------- src/anim.c | 82 ----- src/anim.h | 11 - src/draw.c | 119 -------- src/draw.h | 13 - src/game.c | 722 ++++++++++++++++++++++++++++++++++++++++++++- src/game.h | 9 - src/i18n.c | 59 ---- src/ia.c | 141 --------- src/ia.h | 7 - src/screen.c | 117 -------- src/screen.h | 8 - src/spawn.c | 43 --- src/spawn.h | 6 - 17 files changed, 725 insertions(+), 812 deletions(-) delete mode 100644 cocobattleroyale.c delete mode 100644 kokobatoru.c delete mode 100644 lib/globals.h delete mode 100644 src/anim.c delete mode 100644 src/anim.h delete mode 100644 src/draw.c delete mode 100644 src/draw.h delete mode 100644 src/game.h delete mode 100644 src/i18n.c delete mode 100644 src/ia.c delete mode 100644 src/ia.h delete mode 100644 src/screen.c delete mode 100644 src/screen.h delete mode 100644 src/spawn.c delete mode 100644 src/spawn.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f29abd..f9b64ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.5) include("${CMAKE_SOURCE_DIR}/cc65-find.cmake") +include_directories("${CMAKE_SOURCE_DIR}/lib") set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cc65-toolchain.cmake") project(kokobatoru C ASM) @@ -16,11 +17,13 @@ set(CMAKE_EXE_LINKER_FLAGS "-C nrom_128_horz.cfg ${CMAKE_EXE_LINKER_FLAGS}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) add_executable("kokobatoru" - "${CMAKE_SOURCE_DIR}/kokobatoru.c" + "${CMAKE_SOURCE_DIR}/src/game.c" "${CMAKE_SOURCE_DIR}/asm/crt0.s" ) add_executable("cocobattleroyale" - "${CMAKE_SOURCE_DIR}/cocobattleroyale.c" + "${CMAKE_SOURCE_DIR}/src/game.c" "${CMAKE_SOURCE_DIR}/asm/crt0.s" ) + +target_compile_definitions("kokobatoru" PRIVATE FAMICON_VERSION=1) diff --git a/cocobattleroyale.c b/cocobattleroyale.c deleted file mode 100644 index df5d9d9..0000000 --- a/cocobattleroyale.c +++ /dev/null @@ -1,25 +0,0 @@ -#define FAMICON_VERSION (0) -#include "src/anim.h" -#include "src/draw.h" -#include "src/ia.h" -#include "src/screen.h" -#include "src/spawn.h" -#include "lib/micromages.h" -#include "lib/neslib.h" -#include "lib/globals.h" -#include "src/i18n.c" -#include "src/ia.c" -#include "src/draw.c" -#include "src/screen.c" -#include "src/game.c" -#include "src/anim.c" -#include "src/spawn.c" - -void main(void) -{ - game_setup(); - - for (;;) { - game_loop(); - } -} \ No newline at end of file diff --git a/kokobatoru.c b/kokobatoru.c deleted file mode 100644 index 83b145c..0000000 --- a/kokobatoru.c +++ /dev/null @@ -1,25 +0,0 @@ -#define FAMICON_VERSION (1) -#include "src/anim.h" -#include "src/draw.h" -#include "src/ia.h" -#include "src/screen.h" -#include "src/spawn.h" -#include "lib/micromages.h" -#include "lib/neslib.h" -#include "lib/globals.h" -#include "src/i18n.c" -#include "src/ia.c" -#include "src/draw.c" -#include "src/screen.c" -#include "src/game.c" -#include "src/anim.c" -#include "src/spawn.c" - -void main(void) -{ - game_setup(); - - for (;;) { - game_loop(); - } -} \ No newline at end of file diff --git a/lib/globals.h b/lib/globals.h deleted file mode 100644 index 968aa18..0000000 --- a/lib/globals.h +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @todo: refact this cheat. - */ -#ifndef MAX_ENIMIES -#define MAX_ENIMIES (20) -#endif -#ifndef MAX_PLAYERS -#define MAX_PLAYERS (4) -#endif -#define SPEED (3) -#define MIN_ARENA_X (6) -#define MAX_ARENA_X (242) -#define MID_ARENA_X ((MAX_ARENA_X/2)+MIN_ARENA_X) -#define MIN_ARENA_Y (22) -#define MAX_ARENA_Y (208) -#define MID_ARENA_Y ((MAX_ARENA_Y/2)+MIN_ARENA_Y) -#define RANGE_ARENA (40) -#define LOOK_RIGHT (0) -#define LOOK_LEFT (1) -#define PLAYER_1 (0) -#define PLAYER_2 (1) -#define FRAME_PREPARE (7) -#define FRAME_ATTACKING (6) -#define FRAME_RECOVERY (2) -#define DIGIT_WINNER (22) -#define DIGIT_NOOB (21) - -/** - * FUNCTIONS - */ -#define SEED_PACK(v) ((unsigned char)(v-256)) -#define SEED_UNPACK(v) ((unsigned int)(v+256)) -#define ABS(v) (v<0?-v:v) -#define POW(v) (v*v) -#define PRESSING(g,b) ((g&b)==b) -#define CLAMP(v,min,max) (MIN(max,MAX(min,v))) -#define DISTANCE(a,b) (a>b?a-b:b-a) -#define DISTANCE2D(a1,a2,b1,b2) ((int)DISTANCE(a1,a2)+DISTANCE(b1,b2)) - -/** - * SPRITES - */ -#define SPR_EDGE 0xD7 -#define SPR_EDGE_1 0xB9 -#define SPR_EDGE_2 0xCD -#define SPR_POINTER 0xBC - -/** - * TYPES - */ -enum fsm_game_e { - FSM_MUSIC_MENU, - FSM_MUSIC_ARENA, - FSM_DRAW_MENU, - FSM_DRAW_ARENA, - FSM_DRAW_CELEBRATION, - FSM_MENU, - FSM_COUNT, - FSM_GAMEPLAY, - FSM_CELEBRATION, - FSM_RESTART -}; - -struct coco_s { - unsigned char x; - unsigned char y; - unsigned char framedata; - union { - signed char sprite; - struct { - unsigned char walking: 1; - unsigned char attacking: 1; - unsigned char recovering: 1; - unsigned char colorvar: 2; - unsigned char death: 1; - unsigned char flipped: 1; - } status; - } info; -}; - -struct framecount_s { - unsigned char frames: 2; - unsigned char hunter_last: 2; - unsigned char hunter_step: 4; -}; - -static const unsigned char good_seeds[] = { - SEED_PACK(283), SEED_PACK(285), SEED_PACK(499), - SEED_PACK(301), SEED_PACK(305), SEED_PACK(274), - SEED_PACK(332), SEED_PACK(336), SEED_PACK(353), - SEED_PACK(368), SEED_PACK(378), SEED_PACK(395), - SEED_PACK(451), SEED_PACK(507) -}; - - -const char paletteBackgroundMenu[] = { - 0x0f, 0x30, 0x30, 0x30, - 0x0f, 0x30, 0x0f, 0x30, - 0x0f, 0x30, 0x0f, 0x0f -}; - -const char paletteBackground[] = { - 0x0f, 0x30, 0x30, 0x30, - 0x0f, 0x30, 0x30, 0x30, - 0x0f, 0x30, 0x30, 0x30, - 0x0f, 0x27, 0x30, 0x0f -}; - -const char paletteSprite[] = { - 0x0f,0x30,0x27,0x16, - 0x0f,0x2C,0x24,0x29, - 0x0f,0x26,0x21,0x2a, - 0x0f,0x15,0x14,0x38, -}; - -const char digit_lockup[2][] = { - {' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0x5F, '1', '2', '3'}, - {' ', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', 0x5E, 0xC5, 0xC6, 0xC7} -}; - -/** GLOBAL VARIABLES **/ -static struct framecount_s framecount; /** IA manager groups **/ -static unsigned int framecount_seed; /** IA Behavior seed**/ -static struct coco_s players[MAX_ENIMIES]; /** all cocks entitys **/ -static enum fsm_game_e gamestate; /** finite state machine **/ -static unsigned char seed; /** randomness control **/ -static unsigned char roosters_count; /** cocks counter **/ -static unsigned char roosters_total; /** total of cocks arrive **/ - -/** micromages 4 players **/ -static unsigned char joysticks = 1; /** local multiplayer mode **/ -static unsigned char gamepad_old[MAX_PLAYERS]; /** last frame joysticks inputs **/ -static const unsigned char* const gamepad = &joy1; /** joystick inputs **/ - -/** score rank 4 players **/ -static unsigned char player_score[4] = {0, 1, 11, 21}; -static unsigned char player_rank[4] = {186, 186, 202, 105}; - -/** GENERAL VARIABLES **/ -static signed char s; -static unsigned int big1, big2; -static unsigned char i,j,l,r; -static unsigned char spr; diff --git a/src/anim.c b/src/anim.c deleted file mode 100644 index 9aeb023..0000000 --- a/src/anim.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "anim.h" -#include "game.h" - -static unsigned char step_1; -static unsigned char step_2; -static unsigned char step_3; -static unsigned char step_4; - -void anim_reset() -{ - step_1 = 0; - step_2 = 0; - step_3 = 0; - step_4 = 0; -} - -void anim_menu() -{ - if (step_1 < second) { - ++step_1; - } else if (step_2 < 7) { - step_1 = 1; - ++step_2; - } else { - static const unsigned colors[] = {0x30, 0x29, 0x21, 0x30, 0x29}; - pal_col(1, colors[0 + step_4]); - pal_col(2, colors[1 + step_4]); - pal_col(3, colors[2 + step_4]); - pal_col(17, colors[2 + step_4]); - step_4 = (step_3>>3) % 3; - ++step_3; - } -} - -bool anim_count(unsigned char end) -{ - bool finish = false; - if (++step_1 > second) { - sfx_play(2, 1); - step_1 = 0; - ++step_2; - } - if (step_2 >= end) { - sfx_play(3, 1); - music_pause(0); - finish = true; - } - spr = oam_spr(100 + (8 * 3), (10 * 8), ('0' + end - step_2), 0, spr); - spr = oam_spr((27 * 8), (1 * 8) -1, '?', 3, spr); - spr = oam_spr((28 * 8), (1 * 8) -1, '?', 3, spr); - for (i = 0; i < 8; ++i) { - spr = oam_spr(100 + (i << 3), (9 * 8), I18N_EN_COUNT[i], 0, spr); - } - for (i = 0; i < 4; ++i) { - spr = oam_spr(100 + (i << 3), (10 * 8), I18N_EN_COUNT[i + 8], 0, spr); - } - for (i = 0; i < 3; ++i) { - spr = oam_spr(100 + (8 * 4) + (i << 3), (10 * 8), ((step_1 >> 3) > i)? '.': ' ', 0, spr); - } - oam_edge(MIN_ARENA_X, MIN_ARENA_Y, MAX_ARENA_X, MAX_ARENA_Y); - return finish; -} - -void anim_winner_color() -{ - static unsigned char s0 = 0; - static unsigned char s1 = 0; - static unsigned char s2 = 0; - if (++s0 >= 5) { - s0 = 0; - ++s1; - } - if (s1 >= 4) { - s1 = 0; - ++s2; - } - if (s2 >= 3) { - s2 = 0; - } - s = s1 << 2; - i = s2; -} \ No newline at end of file diff --git a/src/anim.h b/src/anim.h deleted file mode 100644 index 9f037e3..0000000 --- a/src/anim.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef H_ANIM_KOKOBATORU -#define H_ANIM_KOKOBATORU - -#include - -void anim_reset(void); -void anim_menu(void); -bool anim_count(unsigned char end); -void anim_winner_color(void); - -#endif diff --git a/src/draw.c b/src/draw.c deleted file mode 100644 index 3e48570..0000000 --- a/src/draw.c +++ /dev/null @@ -1,119 +0,0 @@ -void oam_edge(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) -{ - spr = oam_spr(x1 - 6, y1 - 7, SPR_EDGE, 0xC0, spr); - spr = oam_spr(x2 + 6, y1 - 7, SPR_EDGE, 0x80, spr); - spr = oam_spr(x1 - 6, y2 + 7, SPR_EDGE, 0x40, spr); - spr = oam_spr(x2 + 6, y2 + 7, SPR_EDGE, 0x00, spr); -} - -void put_all(const char c) -{ - vram_adr(NTADR_A(0,0)); - vram_fill(c, 32*30); -} - -void put_str(unsigned int adr,const char *str) -{ - unsigned char fixed_x = (adr & 0x1f); - vram_adr(adr); - for (;*str != '\0'; ++str) { - /** line feed */ - if (*str == '\n') { - /** y + 1*/ - adr += 32; - vram_adr(adr); - continue; - } - /** carrier return */ - if (*str == '\r') { - /** x = fixed_x */ - adr = fixed_x | (adr & 0xffe0); - vram_adr(adr); - continue; - } - /** print */ - vram_put(*str); - ++adr; - } -} - -void put_ret(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) -{ - /** adjust size **/ - x2 += 1; - y2 += 1; - j = x2 - x1; - - /** draw horizontal lines **/ - for (j = x1 + 1; j < x2; ++j) - { - vram_adr(NTADR_A(j,y1)); - vram_put(SPR_EDGE_1 + (j % 3)); - vram_adr(NTADR_A(j,y2)); - vram_put(SPR_EDGE_1 + (j % 3)); - } - - /** draw vertical lines **/ - for (j = y1 + 1; j < y2; ++j) - { - vram_adr(NTADR_A(x1, j)); - vram_put(SPR_EDGE_2 + (j % 3)); - vram_adr(NTADR_A(x2, j)); - vram_put(SPR_EDGE_2 + (j % 3)); - } -} - -void put_borders() -{ - put_ret(MIN_ARENA_X/8, MIN_ARENA_Y/8, MAX_ARENA_X/8, MAX_ARENA_Y/8); - vram_adr(ATADR_A(0, 1)); - vram_fill(BR_BL_TR_TL(0,0,3,3), 8); - vram_adr(ATADR_A(0, 27)); - vram_fill(BR_BL_TR_TL(0,0,1,1), 8); - for (i = 5; i < 25; i += 2) { - vram_adr(ATADR_A(0, i)); - vram_put(BR_BL_TR_TL(3,1,3,1)); - vram_adr(ATADR_A(30, i)); - vram_put(BR_BL_TR_TL(2,3,2,3)); - } -} - -void put_logo() -{ - for (i = 0; i < 6; i++){ - vram_adr(NTADR_A(7, 4 + i)); - vram_write((jp? I18N_JP_LOGO: I18N_EN_LOGO) + (i*17), 17); - } -} - -void put_rank() -{ - for (l = 0; l < joysticks; ++l) { - s = player_rank[l]; - vram_put(SPR_POINTER + l); - vram_put('P'); - if (s && s <= 3) { - s += DIGIT_NOOB; - } - else if (s == MAX_ENIMIES) { - s = DIGIT_NOOB; - } - vram_put(digit_lockup[1][s]); - vram_put(digit_lockup[0][s]); - } -} - -void put_score() -{ - for (l = 0; l < joysticks; ++l) { - s = player_score[l]; - vram_put(SPR_POINTER + l); - vram_put('P'); - if (s) { - vram_put(digit_lockup[1][s]); - vram_put(digit_lockup[0][s]); - } else { - vram_write("00", 2); - } - } -} diff --git a/src/draw.h b/src/draw.h deleted file mode 100644 index 4908e2b..0000000 --- a/src/draw.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef H_DRAW_KOKOBATORU -#define H_DRAW_KOKOBATORU - -void oam_edge(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2); -void put_all(const char c); -void put_str(unsigned int adr,const char *str); -void put_ret(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2); -void put_borders(); -void put_logo(); -void put_rank(); -void put_score(); - -#endif diff --git a/src/game.c b/src/game.c index 8320800..dc0ddf1 100644 --- a/src/game.c +++ b/src/game.c @@ -15,8 +15,181 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#include "neslib.h" +#include "micromages.h" +#include + +#ifndef FAMICON_VERSION +#define FAMICON_VERSION (0) +#endif +#ifndef MAX_ENIMIES +#define MAX_ENIMIES (20) +#endif +#ifndef MAX_PLAYERS +#define MAX_PLAYERS (4) +#endif +#ifndef SPEED +#define SPEED (3) +#endif +#define MIN_ARENA_X (6) +#define MAX_ARENA_X (242) +#define MID_ARENA_X ((MAX_ARENA_X/2)+MIN_ARENA_X) +#define MIN_ARENA_Y (22) +#define MAX_ARENA_Y (208) +#define MID_ARENA_Y ((MAX_ARENA_Y/2)+MIN_ARENA_Y) +#define RANGE_ARENA (40) +#define LOOK_RIGHT (0) +#define LOOK_LEFT (1) +#define PLAYER_1 (0) +#define PLAYER_2 (1) +#define FRAME_PREPARE (7) +#define FRAME_ATTACKING (6) +#define FRAME_RECOVERY (2) +#define DIGIT_WINNER (22) +#define DIGIT_NOOB (21) + +/** + * FUNCTIONS + */ +#define SEED_PACK(v) ((unsigned char)(v-256)) +#define SEED_UNPACK(v) ((unsigned int)(v+256)) +#define ABS(v) (v<0?-v:v) +#define POW(v) (v*v) +#define PRESSING(g,b) ((g&b)==b) +#define CLAMP(v,min,max) (MIN(max,MAX(min,v))) +#define DISTANCE(a,b) (a>b?a-b:b-a) +#define DISTANCE2D(a1,a2,b1,b2) ((int)DISTANCE(a1,a2)+DISTANCE(b1,b2)) + +/** + * SPRITES + */ +#define SPR_EDGE 0xD7 +#define SPR_EDGE_1 0xB9 +#define SPR_EDGE_2 0xCD +#define SPR_POINTER 0xBC +#define SPR_JP_HITO 0x06 +#define SPR_JP_O 0x07 +#define SPR_JP_N 0x0E +#define SPR_JP_DO 0x0F +#define SPR_JP_RI 0x16 +#define SPR_JP_TSU 0x17 +#define SPR_JP_DZU 0x1E +#define SPR_JP_KU 0x1F + +/** + * TYPES + */ +enum fsm_game_e { + FSM_MUSIC_MENU, + FSM_MUSIC_ARENA, + FSM_DRAW_MENU, + FSM_DRAW_ARENA, + FSM_DRAW_CELEBRATION, + FSM_MENU, + FSM_COUNT, + FSM_GAMEPLAY, + FSM_CELEBRATION, + FSM_RESTART +}; + +struct coco_s { + unsigned char x; + unsigned char y; + unsigned char framedata; + union { + signed char sprite; + struct { + unsigned char walking: 1; + unsigned char attacking: 1; + unsigned char recovering: 1; + unsigned char colorvar: 2; + unsigned char death: 1; + unsigned char flipped: 1; + } status; + } info; +}; + +struct framecount_s { + unsigned char frames: 2; + unsigned char hunter_last: 2; + unsigned char hunter_step: 4; +}; + +static const unsigned char good_seeds[] = { + SEED_PACK(283), SEED_PACK(285), SEED_PACK(499), + SEED_PACK(301), SEED_PACK(305), SEED_PACK(274), + SEED_PACK(332), SEED_PACK(336), SEED_PACK(353), + SEED_PACK(368), SEED_PACK(378), SEED_PACK(395), + SEED_PACK(451), SEED_PACK(507) +}; + + +const char paletteBackgroundMenu[] = { + 0x0f, 0x30, 0x30, 0x30, + 0x0f, 0x30, 0x0f, 0x30, + 0x0f, 0x30, 0x0f, 0x0f +}; + +const char paletteBackground[] = { + 0x0f, 0x30, 0x30, 0x30, + 0x0f, 0x30, 0x30, 0x30, + 0x0f, 0x30, 0x30, 0x30, + 0x0f, 0x27, 0x30, 0x0f +}; + +const char paletteSprite[] = { + 0x0f,0x30,0x27,0x16, + 0x0f,0x2C,0x24,0x29, + 0x0f,0x26,0x21,0x2a, + 0x0f,0x15,0x14,0x38, +}; + +enum fsm_ia_e { + FSM_DEFAULT, + FSM_RANDOM, + FSM_HUNTER_WAIT, + FSM_HUNTER, + FSM_SCAPE_WAIT, + FSM_SCAPE, + FSM_WINNER +}; + +struct npc_ia_s { + unsigned char target; + unsigned char input; + enum fsm_ia_e state; +}; + +const char digit_lockup[2][] = { + {' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0x5F, '1', '2', '3'}, + {' ', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', 0x5E, 0xC5, 0xC6, 0xC7} +}; + +/** GLOBAL VARIABLES **/ +static struct framecount_s framecount; /** IA manager groups **/ +static unsigned int framecount_seed; /** IA Behavior seed**/ +static struct coco_s players[MAX_ENIMIES]; /** all cocks entitys **/ +static enum fsm_game_e gamestate; /** finite state machine **/ +static unsigned char seed; /** randomness control **/ +static unsigned char roosters_count; /** cocks counter **/ +static unsigned char roosters_total; /** total of cocks arrive **/ +static struct npc_ia_s npcs[MAX_ENIMIES]; + +/** micromages 4 players **/ +static unsigned char joysticks = 1; /** local multiplayer mode **/ +static unsigned char gamepad_old[MAX_PLAYERS]; /** last frame joysticks inputs **/ +static const unsigned char* const gamepad = &joy1; /** joystick inputs **/ + +/** score rank 4 players **/ +static unsigned char player_score[4] = {0, 1, 11, 21}; +static unsigned char player_rank[4] = {186, 186, 202, 105}; + +/** GENERAL VARIABLES **/ +static signed char s; +static unsigned int big1, big2; +static unsigned char i,j,l,r; +static unsigned char spr; -static void game_move(void); static unsigned char second; static unsigned char speed; @@ -27,6 +200,542 @@ static signed char earthquake; static signed char eqx; static signed char eqy; +const char I18N_EN_SCORE[] = " SCORE: "; +const char I18N_EN_COUNT[] = "STARTINGAT\xdc\xdc"; +const char I18N_EN_CONTINUE[] = "CONTINUE!"; +const char I18N_EN_1_PLAYERS[] = "1 PLAYERS"; +const char I18N_EN_2_PLAYERS[] = "2 PLAYERS"; +const char I18N_EN_3_PLAYERS[] = "3 PLAYERS"; +const char I18N_EN_4_PLAYERS[] = "4 PLAYERS"; +const char I18N_EN_LOOSER[] = "#XX\r\nYOU ARE FRIED."; +const char I18N_EN_WINNER[] = "#1\r\nYOU ARE\r\nULTIMATE\r\nHOT CHICKEN!!"; +const char I18N_EN_CREDITS_1[] = "RODRIGO DORNELLES (C) 2022"; +const char I18N_EN_CREDITS_2[] = "HTTP://PSYWAVE-GAMES.GITHUB.IO"; +const char I18N_EN_RESTART_CNT[] = "STARTING IN SECONDS..."; +const char I18N_EN_RESTART_BTN[] = " HOLD (ATACK) FOR NEW BATTLE!"; +const char I18N_EN_RESTART_COIN[] = "INSERT (COIN) FOR NEW BATTLE!! "; +const char I18N_EN_GAMEPLAY_NAME[] = " COCO BATTLE ROYALE II "; + +const char I18N_EN_LOGO[] = { + 0x60, 0x61, 0xA2, 0xA3, 0x64, 0x65, 0xA2, 0xA3, 0x20, 0x20, 0x20, 0xC9, 0xCA, 0xCB, 0xC9, 0xCA, 0xCB, + 0x70, 0x71, 0xCC, 0xB3, 0x74, 0x75, 0xCC, 0xB3, 0x20, 0x20, 0x20, 0xD9, 0xDA, 0xDB, 0xD9, 0xDA, 0xDB, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x84, 0x85, 0xA6, 0xA7, 0x62, 0x63, 0xEA, 0xEB, 0x20, 0xEA, 0xEB, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x94, 0x95, 0xB6, 0xB7, 0x72, 0x73, 0xEA, 0xEB, 0x20, 0xEA, 0xEB, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x82, 0x83, 0xA6, 0xA7, 0x62, 0x63, 0xEA, 0xEB, 0x20, 0xEA, 0xEB, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0x92, 0x93, 0xB6, 0xB7, 0x72, 0x73, 0xFA, 0xFB, 0x20, 0xFA, 0xFB +}; + +const char jp = FAMICON_VERSION; +const char I18N_JP_CONTINUE[] = { + ' ', ' ', ' ', SPR_JP_TSU, SPR_JP_DZU, SPR_JP_KU, ' ', ' ', ' ' +}; +const char I18N_JP_1_PLAYERS[] = { + ' ', '1', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' +}; +const char I18N_JP_2_PLAYERS[] = { + ' ', '2', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' +}; +const char I18N_JP_3_PLAYERS[] = { + ' ', '3', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' +}; +const char I18N_JP_4_PLAYERS[] = { + ' ', '4', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' +}; + +const char I18N_JP_LOGO[] = { + 0x20, 0xC0, 0xC1, 0xC2, 0xC0, 0xC1, 0xC2, 0x20, 0xC4, 0xF3, 0xD6, 0xF3, 0x20, 0x20, 0xF3, 0xF3, 0x20, + 0x20, 0x20, 0x20, 0xD2, 0x20, 0x20, 0xD2, 0x20, 0xD4, 0xD5, 0x20, 0xEA, 0xE0, 0xE1, 0xEA, 0xEA, 0x20, + 0x20, 0x20, 0x20, 0xE2, 0x20, 0x20, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xEA, 0xE8, 0xE9, 0xE7, 0xEA, 0xC3, + 0x20, 0xF0, 0xF1, 0xF2, 0xF0, 0xF1, 0xF2, 0xF5, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xD0, 0xD1, 0xD3, + 0x20, 0x5B, 0x5C, 0x5D, 'U', 'L', 'T', 'I', 'M', 'A', 'T', 'E', ' ', 'C', 'O', 'C', 'O', + 0x20, 'B', 'A', 'T', 'T', 'L', 'E', ' ', 'R', 'O', 'Y', 'A', 'L', 'E', ' ', 'I', 'I' +}; + +void oam_edge(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) +{ + spr = oam_spr(x1 - 6, y1 - 7, SPR_EDGE, 0xC0, spr); + spr = oam_spr(x2 + 6, y1 - 7, SPR_EDGE, 0x80, spr); + spr = oam_spr(x1 - 6, y2 + 7, SPR_EDGE, 0x40, spr); + spr = oam_spr(x2 + 6, y2 + 7, SPR_EDGE, 0x00, spr); +} + +void put_all(const char c) +{ + vram_adr(NTADR_A(0,0)); + vram_fill(c, 32*30); +} + +void put_str(unsigned int adr,const char *str) +{ + unsigned char fixed_x = (adr & 0x1f); + vram_adr(adr); + for (;*str != '\0'; ++str) { + /** line feed */ + if (*str == '\n') { + /** y + 1*/ + adr += 32; + vram_adr(adr); + continue; + } + /** carrier return */ + if (*str == '\r') { + /** x = fixed_x */ + adr = fixed_x | (adr & 0xffe0); + vram_adr(adr); + continue; + } + /** print */ + vram_put(*str); + ++adr; + } +} + +void put_ret(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) +{ + /** adjust size **/ + x2 += 1; + y2 += 1; + j = x2 - x1; + + /** draw horizontal lines **/ + for (j = x1 + 1; j < x2; ++j) + { + vram_adr(NTADR_A(j,y1)); + vram_put(SPR_EDGE_1 + (j % 3)); + vram_adr(NTADR_A(j,y2)); + vram_put(SPR_EDGE_1 + (j % 3)); + } + + /** draw vertical lines **/ + for (j = y1 + 1; j < y2; ++j) + { + vram_adr(NTADR_A(x1, j)); + vram_put(SPR_EDGE_2 + (j % 3)); + vram_adr(NTADR_A(x2, j)); + vram_put(SPR_EDGE_2 + (j % 3)); + } +} + +void put_borders() +{ + put_ret(MIN_ARENA_X/8, MIN_ARENA_Y/8, MAX_ARENA_X/8, MAX_ARENA_Y/8); + vram_adr(ATADR_A(0, 1)); + vram_fill(BR_BL_TR_TL(0,0,3,3), 8); + vram_adr(ATADR_A(0, 27)); + vram_fill(BR_BL_TR_TL(0,0,1,1), 8); + for (i = 5; i < 25; i += 2) { + vram_adr(ATADR_A(0, i)); + vram_put(BR_BL_TR_TL(3,1,3,1)); + vram_adr(ATADR_A(30, i)); + vram_put(BR_BL_TR_TL(2,3,2,3)); + } +} + +void put_logo() +{ + for (i = 0; i < 6; i++){ + vram_adr(NTADR_A(7, 4 + i)); + vram_write((jp? I18N_JP_LOGO: I18N_EN_LOGO) + (i*17), 17); + } +} + +void put_rank() +{ + for (l = 0; l < joysticks; ++l) { + s = player_rank[l]; + vram_put(SPR_POINTER + l); + vram_put('P'); + if (s && s <= 3) { + s += DIGIT_NOOB; + } + else if (s == MAX_ENIMIES) { + s = DIGIT_NOOB; + } + vram_put(digit_lockup[1][s]); + vram_put(digit_lockup[0][s]); + } +} + +void put_score() +{ + for (l = 0; l < joysticks; ++l) { + s = player_score[l]; + vram_put(SPR_POINTER + l); + vram_put('P'); + if (s) { + vram_put(digit_lockup[1][s]); + vram_put(digit_lockup[0][s]); + } else { + vram_write("00", 2); + } + } +} + +void spawn() +{ + unsigned char colorvar = 2; + + /** reset scores**/ + for (i = 0; i < MAX_PLAYERS; i++) { + player_score[i] = 0; + player_rank[i] = 0; + } + /** reset postions **/ + for (i = 0; i < MAX_ENIMIES; i++) + { + if (joysticks == 1 && i == 0){ + // single player center + players[i].x = MID_ARENA_X; + players[i].y = MID_ARENA_Y; + } + else if (i < joysticks) { + // multi player positions + players[i].x = MID_ARENA_X + (i&1? RANGE_ARENA/2: RANGE_ARENA/(-2)); + players[i].y = MID_ARENA_Y + (i&2? RANGE_ARENA/2: RANGE_ARENA/(-2)); + } + else do { + // random npc positions + players[i].x = rand8(); + players[i].y = rand8(); + // reset npc behavior + npcs[i].input = 0; + npcs[i].state = FSM_DEFAULT; + } + while ( + // uncenter npc positions + players[i].x > MID_ARENA_X - RANGE_ARENA && players[i].x < MID_ARENA_X + RANGE_ARENA + && players[i].y > MID_ARENA_Y - RANGE_ARENA && players[i].y < MID_ARENA_Y + RANGE_ARENA + ); + // look to center + players[i].info.status.flipped = players[i].x > MID_ARENA_X? LOOK_LEFT: LOOK_RIGHT; + players[i].info.status.colorvar = (++colorvar >> 2) % 3; + players[i].info.status.death = FALSE; + } +} + +void ia_hunter_cycle() +{ + /** verify cycle is completed **/ + if (framecount.hunter_last == framecount.frames++) { + return; + } + + /** verify steps to execute **/ + if (++framecount.hunter_step) { + return; + } + + /** next group **/ + framecount.hunter_last += 1; + + /** search by hunter **/ + for (i = framecount.hunter_last; i < MAX_ENIMIES; i += 4) { + /** finded **/ + if (npcs[i].state == FSM_HUNTER_WAIT) { + big1 = 0xFFFF; + for (j = 0; j < MAX_ENIMIES; j++) { + if (i == j) { + continue; + } + if (players[j].info.status.death) { + continue; + } + // calc distance aproximy + big2 = DISTANCE2D(players[i].x, players[j].x, players[i].y, players[j].y); + if (big2 > big1) { + continue; + } + npcs[i].state = FSM_HUNTER; + npcs[i].target = j; + big1 = big2; + } + break; + } + } +} + +void ia_process(unsigned char npc) +{ + switch (npcs[npc].state) { + case FSM_DEFAULT: + npcs[npc].input = NULL; + npcs[npc].state = FSM_RANDOM; + break; + + case FSM_HUNTER: + j = npcs[npc].target; + if (players[j].info.status.death) { + npcs[npc].state = FSM_RANDOM; + break; + } + npcs[npc].input = 0; + npcs[npc].input |= players[npc].x > players[j].x? PAD_LEFT: PAD_RIGHT; + npcs[npc].input |= players[npc].y > players[j].y? PAD_UP: PAD_DOWN; + npcs[npc].input |= DISTANCE2D(players[i].x, players[j].x, players[i].y, players[j].y) < 8? PAD_A: NULL; + r = rand8(); + if (roosters_total > 2 && r < 10){ + npcs[npc].state = FSM_RANDOM; + } + else if (npcs[npc].state == FSM_HUNTER && npcs[j].state == FSM_HUNTER && r < 10) { + npcs[npc].state = FSM_RANDOM; + } + if (r < 25) { + npcs[npc].input ^= (PAD_LEFT | PAD_RIGHT); + } + else if (r < 50) { + npcs[npc].input ^= (PAD_UP | PAD_DOWN); + } + break; + + case FSM_WINNER: + if (players[npc].y < MID_ARENA_Y - 8) { + npcs[npc].input = PAD_DOWN; + } + else if (players[npc].y > MID_ARENA_Y + 8) { + npcs[npc].input = PAD_UP; + } + else if (players[npc].x > MID_ARENA_X + 32) { + npcs[npc].input = PAD_LEFT; + } + else if (players[npc].x < MID_ARENA_X - 32) { + npcs[npc].input = PAD_RIGHT; + } + else if (rand8() < 64) { + npcs[npc].input = rand8() % 2? PAD_LEFT: PAD_RIGHT; + } + break; + + default: + if (gamestate == FSM_CELEBRATION) { + npcs[npc].state = FSM_WINNER; + } + else if (j < 60) { + npcs[npc].state = FSM_HUNTER_WAIT; + } + else + { + case FSM_HUNTER_WAIT: + j = rand8(); + if (j < 90) { + npcs[npc].input ^= (rand8() + npc + j) & (PAD_LEFT | PAD_RIGHT); + // fixed ambiguous input on axis x + if (npcs[npc].input & PAD_LEFT && npcs[npc].input & PAD_RIGHT) { + npcs[npc].input ^= (PAD_LEFT | PAD_RIGHT); + } + } + else if (j < 120) { + npcs[npc].input ^= (rand8() + npc + j) & (PAD_DOWN | PAD_UP); + // fixed ambiguous input on axis x + if (npcs[npc].input & PAD_DOWN && npcs[npc].input & PAD_UP) { + npcs[npc].input ^= (PAD_DOWN | PAD_UP); + } + } + } + break; + } +} + + +static unsigned char step_1; +static unsigned char step_2; +static unsigned char step_3; +static unsigned char step_4; + +void anim_reset() +{ + step_1 = 0; + step_2 = 0; + step_3 = 0; + step_4 = 0; +} + +void anim_menu() +{ + if (step_1 < second) { + ++step_1; + } else if (step_2 < 7) { + step_1 = 1; + ++step_2; + } else { + static const unsigned colors[] = {0x30, 0x29, 0x21, 0x30, 0x29}; + pal_col(1, colors[0 + step_4]); + pal_col(2, colors[1 + step_4]); + pal_col(3, colors[2 + step_4]); + pal_col(17, colors[2 + step_4]); + step_4 = (step_3>>3) % 3; + ++step_3; + } +} + +bool anim_count(unsigned char end) +{ + bool finish = false; + if (++step_1 > second) { + sfx_play(2, 1); + step_1 = 0; + ++step_2; + } + if (step_2 >= end) { + sfx_play(3, 1); + music_pause(0); + finish = true; + } + spr = oam_spr(100 + (8 * 3), (10 * 8), ('0' + end - step_2), 0, spr); + spr = oam_spr((27 * 8), (1 * 8) -1, '?', 3, spr); + spr = oam_spr((28 * 8), (1 * 8) -1, '?', 3, spr); + for (i = 0; i < 8; ++i) { + spr = oam_spr(100 + (i << 3), (9 * 8), I18N_EN_COUNT[i], 0, spr); + } + for (i = 0; i < 4; ++i) { + spr = oam_spr(100 + (i << 3), (10 * 8), I18N_EN_COUNT[i + 8], 0, spr); + } + for (i = 0; i < 3; ++i) { + spr = oam_spr(100 + (8 * 4) + (i << 3), (10 * 8), ((step_1 >> 3) > i)? '.': ' ', 0, spr); + } + oam_edge(MIN_ARENA_X, MIN_ARENA_Y, MAX_ARENA_X, MAX_ARENA_Y); + return finish; +} + +void anim_winner_color() +{ + static unsigned char s0 = 0; + static unsigned char s1 = 0; + static unsigned char s2 = 0; + if (++s0 >= 5) { + s0 = 0; + ++s1; + } + if (s1 >= 4) { + s1 = 0; + ++s2; + } + if (s2 >= 3) { + s2 = 0; + } + s = s1 << 2; + i = s2; +} + +void screen_menu() +{ + ppu_off(); + pal_bg(paletteBackgroundMenu); + oam_clear(); + /** reset nametable */ + put_all(' '); + /** reset attribute table*/ + vram_adr(ATADR_A(0, 1)); + vram_fill(BR_BL_TR_TL(0,0,0,0), 3*8); + vram_fill(BR_BL_TR_TL(2,2,2,2), 5*8); + /** colorize logo */ + vram_adr(ATADR_A(7,7)); + vram_put(BR_BL_TR_TL(2,0,2,0)); + vram_adr(ATADR_A(7,9)); + vram_put(BR_BL_TR_TL(0,0,2,0)); + vram_adr(ATADR_A(8,7)); + vram_fill(BR_BL_TR_TL(2,2,2,2), 4); + vram_adr(ATADR_A(8,8)); + vram_fill(BR_BL_TR_TL(0,0,2,2), 4); + vram_adr(ATADR_A(18,6)); + vram_put(BR_BL_TR_TL(1,2,2,2)); + vram_put(BR_BL_TR_TL(2,1,2,2)); + /** colorize link */ + vram_adr(ATADR_A(1,26)); + vram_fill(BR_BL_TR_TL(1,1,2,2), 8); + /** game title */ + put_ret(5, 3, 25, 9); + put_logo(); + /** put menu options */ + vram_adr(NTADR_A(11,16)); + vram_write(jp? I18N_JP_1_PLAYERS: I18N_EN_1_PLAYERS, 9); +#if MAX_PLAYERS >= 2 + vram_adr(NTADR_A(11,17)); + vram_write(jp? I18N_JP_2_PLAYERS: I18N_EN_2_PLAYERS, 9); +#endif +#if MAX_PLAYERS >= 3 + vram_adr(NTADR_A(11,18)); + vram_write(jp? I18N_JP_3_PLAYERS: I18N_EN_3_PLAYERS, 9); +#endif +#if MAX_PLAYERS >= 4 + vram_adr(NTADR_A(11,19)); + vram_write(jp? I18N_JP_4_PLAYERS: I18N_EN_4_PLAYERS, 9); +#endif + /** put copyright */ + put_str(NTADR_A(3,25), I18N_EN_CREDITS_1); + put_str(NTADR_A(1,26), I18N_EN_CREDITS_2); + /** put menu option 'continue' */ + if (roosters_count) { + vram_adr(NTADR_A(11,15)); + vram_write(jp? I18N_JP_CONTINUE: I18N_EN_CONTINUE, 9); + } + ppu_on_all(); + gamestate = FSM_MENU; +} + +void screen_arena() +{ + ppu_off(); + oam_clear(); + pal_bg(paletteBackground); + pal_spr(paletteSprite); + /** reset nametable */ + put_all(' '); + /** reset attribute table*/ + vram_adr(ATADR_A(0, 1)); + vram_fill(BR_BL_TR_TL(3,3,3,3), 8*8); + /** put borders */ + put_borders(); + /* put footer */ + put_str(NTADR_A(0,28), I18N_EN_GAMEPLAY_NAME); + /* put header */ + vram_adr(NTADR_A(0, 1)); + put_rank(); + vram_adr(NTADR_A(26,1)); + vram_put(0x00); + vram_write(" /20", 5); + ppu_on_all(); +} + +void screen_celebration() +{ + ppu_off(); + oam_clear(); + pal_bg(paletteBackground); + pal_spr(paletteSprite); + put_all(' '); + put_borders(); + + /** print scoreboards **/ + put_str(NTADR_A(1, 1), "RANK: "); + put_str(NTADR_A(1, 28), "KILLS:"); + vram_adr(NTADR_A(31 - (joysticks * 4), 1)); + put_rank(); + vram_adr(NTADR_A(31 - (joysticks * 4), 28)); + put_score(); + + /** print rank */ + for (l = 0x7f, i = 0; i < joysticks; ++i) + { + if (player_rank[i] < l) { + l = player_rank[i]; + } + } + + if (l <= 1) { + put_str(NTADR_A(12, 4), I18N_EN_WINNER); + } else { + put_str(NTADR_A(12, 4), I18N_EN_LOOSER); + vram_adr(NTADR_A(13, 4)); + vram_put(digit_lockup[1][l]); + vram_put(digit_lockup[0][l]); + } + + gamestate = FSM_CELEBRATION; + ppu_on_all(); +} + +void game_move(); + void game_setup() { pal_spr(paletteSprite); @@ -406,4 +1115,13 @@ static void game_move() /** arena colision **/ player.x = CLAMP(player.x, MIN_ARENA_X, MAX_ARENA_X); player.y = CLAMP(player.y, MIN_ARENA_Y, MAX_ARENA_Y); -} \ No newline at end of file +} + +void main(void) +{ + game_setup(); + + for (;;) { + game_loop(); + } +} diff --git a/src/game.h b/src/game.h deleted file mode 100644 index 2daef6f..0000000 --- a/src/game.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef H_GAME_KOKOBATORU -#define H_GAME_KOKOBATORU - -extern unsigned char second; - -void game_setup(void); -void game_loop(void); - -#endif diff --git a/src/i18n.c b/src/i18n.c deleted file mode 100644 index 62bc6b0..0000000 --- a/src/i18n.c +++ /dev/null @@ -1,59 +0,0 @@ -#define SPR_JP_HITO 0x06 -#define SPR_JP_O 0x07 -#define SPR_JP_N 0x0E -#define SPR_JP_DO 0x0F -#define SPR_JP_RI 0x16 -#define SPR_JP_TSU 0x17 -#define SPR_JP_DZU 0x1E -#define SPR_JP_KU 0x1F - -const char I18N_EN_SCORE[] = " SCORE: "; -const char I18N_EN_COUNT[] = "STARTINGAT\xdc\xdc"; -const char I18N_EN_CONTINUE[] = "CONTINUE!"; -const char I18N_EN_1_PLAYERS[] = "1 PLAYERS"; -const char I18N_EN_2_PLAYERS[] = "2 PLAYERS"; -const char I18N_EN_3_PLAYERS[] = "3 PLAYERS"; -const char I18N_EN_4_PLAYERS[] = "4 PLAYERS"; -const char I18N_EN_LOOSER[] = "#XX\r\nYOU ARE FRIED."; -const char I18N_EN_WINNER[] = "#1\r\nYOU ARE\r\nULTIMATE\r\nHOT CHICKEN!!"; -const char I18N_EN_CREDITS_1[] = "RODRIGO DORNELLES (C) 2022"; -const char I18N_EN_CREDITS_2[] = "HTTP://PSYWAVE-GAMES.GITHUB.IO"; -const char I18N_EN_RESTART_CNT[] = "STARTING IN SECONDS..."; -const char I18N_EN_RESTART_BTN[] = " HOLD (ATACK) FOR NEW BATTLE!"; -const char I18N_EN_RESTART_COIN[] = "INSERT (COIN) FOR NEW BATTLE!! "; -const char I18N_EN_GAMEPLAY_NAME[] = " COCO BATTLE ROYALE II "; - -const char I18N_EN_LOGO[] = { - 0x60, 0x61, 0xA2, 0xA3, 0x64, 0x65, 0xA2, 0xA3, 0x20, 0x20, 0x20, 0xC9, 0xCA, 0xCB, 0xC9, 0xCA, 0xCB, - 0x70, 0x71, 0xCC, 0xB3, 0x74, 0x75, 0xCC, 0xB3, 0x20, 0x20, 0x20, 0xD9, 0xDA, 0xDB, 0xD9, 0xDA, 0xDB, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x84, 0x85, 0xA6, 0xA7, 0x62, 0x63, 0xEA, 0xEB, 0x20, 0xEA, 0xEB, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x94, 0x95, 0xB6, 0xB7, 0x72, 0x73, 0xEA, 0xEB, 0x20, 0xEA, 0xEB, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x82, 0x83, 0xA6, 0xA7, 0x62, 0x63, 0xEA, 0xEB, 0x20, 0xEA, 0xEB, - 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0x92, 0x93, 0xB6, 0xB7, 0x72, 0x73, 0xFA, 0xFB, 0x20, 0xFA, 0xFB -}; - -const char jp = FAMICON_VERSION; -const char I18N_JP_CONTINUE[] = { - ' ', ' ', ' ', SPR_JP_TSU, SPR_JP_DZU, SPR_JP_KU, ' ', ' ', ' ' -}; -const char I18N_JP_1_PLAYERS[] = { - ' ', '1', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' -}; -const char I18N_JP_2_PLAYERS[] = { - ' ', '2', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' -}; -const char I18N_JP_3_PLAYERS[] = { - ' ', '3', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' -}; -const char I18N_JP_4_PLAYERS[] = { - ' ', '4', SPR_JP_HITO, ' ', SPR_JP_O, SPR_JP_N, SPR_JP_DO, SPR_JP_RI, ' ' -}; - -const char I18N_JP_LOGO[] = { - 0x20, 0xC0, 0xC1, 0xC2, 0xC0, 0xC1, 0xC2, 0x20, 0xC4, 0xF3, 0xD6, 0xF3, 0x20, 0x20, 0xF3, 0xF3, 0x20, - 0x20, 0x20, 0x20, 0xD2, 0x20, 0x20, 0xD2, 0x20, 0xD4, 0xD5, 0x20, 0xEA, 0xE0, 0xE1, 0xEA, 0xEA, 0x20, - 0x20, 0x20, 0x20, 0xE2, 0x20, 0x20, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xEA, 0xE8, 0xE9, 0xE7, 0xEA, 0xC3, - 0x20, 0xF0, 0xF1, 0xF2, 0xF0, 0xF1, 0xF2, 0xF5, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xD0, 0xD1, 0xD3, - 0x20, 0x5B, 0x5C, 0x5D, 'U', 'L', 'T', 'I', 'M', 'A', 'T', 'E', ' ', 'C', 'O', 'C', 'O', - 0x20, 'B', 'A', 'T', 'T', 'L', 'E', ' ', 'R', 'O', 'Y', 'A', 'L', 'E', ' ', 'I', 'I' -}; diff --git a/src/ia.c b/src/ia.c deleted file mode 100644 index 050f8a0..0000000 --- a/src/ia.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "ia.h" - -enum fsm_ia_e { - FSM_DEFAULT, - FSM_RANDOM, - FSM_HUNTER_WAIT, - FSM_HUNTER, - FSM_SCAPE_WAIT, - FSM_SCAPE, - FSM_WINNER -}; - -struct npc_ia_s { - unsigned char target; - unsigned char input; - enum fsm_ia_e state; -}; - -static struct npc_ia_s npcs[MAX_ENIMIES]; - -void ia_hunter_cycle() -{ - /** verify cycle is completed **/ - if (framecount.hunter_last == framecount.frames++) { - return; - } - - /** verify steps to execute **/ - if (++framecount.hunter_step) { - return; - } - - /** next group **/ - framecount.hunter_last += 1; - - /** search by hunter **/ - for (i = framecount.hunter_last; i < MAX_ENIMIES; i += 4) { - /** finded **/ - if (npcs[i].state == FSM_HUNTER_WAIT) { - big1 = 0xFFFF; - for (j = 0; j < MAX_ENIMIES; j++) { - if (i == j) { - continue; - } - if (players[j].info.status.death) { - continue; - } - // calc distance aproximy - big2 = DISTANCE2D(players[i].x, players[j].x, players[i].y, players[j].y); - if (big2 > big1) { - continue; - } - npcs[i].state = FSM_HUNTER; - npcs[i].target = j; - big1 = big2; - } - break; - } - } -} - -void ia_process(unsigned char npc) -{ - switch (npcs[npc].state) { - case FSM_DEFAULT: - npcs[npc].input = NULL; - npcs[npc].state = FSM_RANDOM; - break; - - case FSM_HUNTER: - j = npcs[npc].target; - if (players[j].info.status.death) { - npcs[npc].state = FSM_RANDOM; - break; - } - npcs[npc].input = 0; - npcs[npc].input |= players[npc].x > players[j].x? PAD_LEFT: PAD_RIGHT; - npcs[npc].input |= players[npc].y > players[j].y? PAD_UP: PAD_DOWN; - npcs[npc].input |= DISTANCE2D(players[i].x, players[j].x, players[i].y, players[j].y) < 8? PAD_A: NULL; - r = rand8(); - if (roosters_total > 2 && r < 10){ - npcs[npc].state = FSM_RANDOM; - } - else if (npcs[npc].state == FSM_HUNTER && npcs[j].state == FSM_HUNTER && r < 10) { - npcs[npc].state = FSM_RANDOM; - } - if (r < 25) { - npcs[npc].input ^= (PAD_LEFT | PAD_RIGHT); - } - else if (r < 50) { - npcs[npc].input ^= (PAD_UP | PAD_DOWN); - } - break; - - case FSM_WINNER: - if (players[npc].y < MID_ARENA_Y - 8) { - npcs[npc].input = PAD_DOWN; - } - else if (players[npc].y > MID_ARENA_Y + 8) { - npcs[npc].input = PAD_UP; - } - else if (players[npc].x > MID_ARENA_X + 32) { - npcs[npc].input = PAD_LEFT; - } - else if (players[npc].x < MID_ARENA_X - 32) { - npcs[npc].input = PAD_RIGHT; - } - else if (rand8() < 64) { - npcs[npc].input = rand8() % 2? PAD_LEFT: PAD_RIGHT; - } - break; - - default: - if (gamestate == FSM_CELEBRATION) { - npcs[npc].state = FSM_WINNER; - } - else if (j < 60) { - npcs[npc].state = FSM_HUNTER_WAIT; - } - else - { - case FSM_HUNTER_WAIT: - j = rand8(); - if (j < 90) { - npcs[npc].input ^= (rand8() + npc + j) & (PAD_LEFT | PAD_RIGHT); - // fixed ambiguous input on axis x - if (npcs[npc].input & PAD_LEFT && npcs[npc].input & PAD_RIGHT) { - npcs[npc].input ^= (PAD_LEFT | PAD_RIGHT); - } - } - else if (j < 120) { - npcs[npc].input ^= (rand8() + npc + j) & (PAD_DOWN | PAD_UP); - // fixed ambiguous input on axis x - if (npcs[npc].input & PAD_DOWN && npcs[npc].input & PAD_UP) { - npcs[npc].input ^= (PAD_DOWN | PAD_UP); - } - } - } - break; - } -} \ No newline at end of file diff --git a/src/ia.h b/src/ia.h deleted file mode 100644 index 9187b8b..0000000 --- a/src/ia.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef H_IA_KOKOBATORU -#define H_IA_KOKOBATORU - -void ia_hunter_cycle(); -void ia_process(unsigned char npc); - -#endif \ No newline at end of file diff --git a/src/screen.c b/src/screen.c deleted file mode 100644 index f231586..0000000 --- a/src/screen.c +++ /dev/null @@ -1,117 +0,0 @@ -void screen_menu() -{ - ppu_off(); - pal_bg(paletteBackgroundMenu); - oam_clear(); - /** reset nametable */ - put_all(' '); - /** reset attribute table*/ - vram_adr(ATADR_A(0, 1)); - vram_fill(BR_BL_TR_TL(0,0,0,0), 3*8); - vram_fill(BR_BL_TR_TL(2,2,2,2), 5*8); - /** colorize logo */ - vram_adr(ATADR_A(7,7)); - vram_put(BR_BL_TR_TL(2,0,2,0)); - vram_adr(ATADR_A(7,9)); - vram_put(BR_BL_TR_TL(0,0,2,0)); - vram_adr(ATADR_A(8,7)); - vram_fill(BR_BL_TR_TL(2,2,2,2), 4); - vram_adr(ATADR_A(8,8)); - vram_fill(BR_BL_TR_TL(0,0,2,2), 4); - vram_adr(ATADR_A(18,6)); - vram_put(BR_BL_TR_TL(1,2,2,2)); - vram_put(BR_BL_TR_TL(2,1,2,2)); - /** colorize link */ - vram_adr(ATADR_A(1,26)); - vram_fill(BR_BL_TR_TL(1,1,2,2), 8); - /** game title */ - put_ret(5, 3, 25, 9); - put_logo(); - /** put menu options */ - vram_adr(NTADR_A(11,16)); - vram_write(jp? I18N_JP_1_PLAYERS: I18N_EN_1_PLAYERS, 9); -#if MAX_PLAYERS >= 2 - vram_adr(NTADR_A(11,17)); - vram_write(jp? I18N_JP_2_PLAYERS: I18N_EN_2_PLAYERS, 9); -#endif -#if MAX_PLAYERS >= 3 - vram_adr(NTADR_A(11,18)); - vram_write(jp? I18N_JP_3_PLAYERS: I18N_EN_3_PLAYERS, 9); -#endif -#if MAX_PLAYERS >= 4 - vram_adr(NTADR_A(11,19)); - vram_write(jp? I18N_JP_4_PLAYERS: I18N_EN_4_PLAYERS, 9); -#endif - /** put copyright */ - put_str(NTADR_A(3,25), I18N_EN_CREDITS_1); - put_str(NTADR_A(1,26), I18N_EN_CREDITS_2); - /** put menu option 'continue' */ - if (roosters_count) { - vram_adr(NTADR_A(11,15)); - vram_write(jp? I18N_JP_CONTINUE: I18N_EN_CONTINUE, 9); - } - ppu_on_all(); - gamestate = FSM_MENU; -} - -void screen_arena() -{ - ppu_off(); - oam_clear(); - pal_bg(paletteBackground); - pal_spr(paletteSprite); - /** reset nametable */ - put_all(' '); - /** reset attribute table*/ - vram_adr(ATADR_A(0, 1)); - vram_fill(BR_BL_TR_TL(3,3,3,3), 8*8); - /** put borders */ - put_borders(); - /* put footer */ - put_str(NTADR_A(0,28), I18N_EN_GAMEPLAY_NAME); - /* put header */ - vram_adr(NTADR_A(0, 1)); - put_rank(); - vram_adr(NTADR_A(26,1)); - vram_put(0x00); - vram_write(" /20", 5); - ppu_on_all(); -} - -void screen_celebration() -{ - ppu_off(); - oam_clear(); - pal_bg(paletteBackground); - pal_spr(paletteSprite); - put_all(' '); - put_borders(); - - /** print scoreboards **/ - put_str(NTADR_A(1, 1), "RANK: "); - put_str(NTADR_A(1, 28), "KILLS:"); - vram_adr(NTADR_A(31 - (joysticks * 4), 1)); - put_rank(); - vram_adr(NTADR_A(31 - (joysticks * 4), 28)); - put_score(); - - /** print rank */ - for (l = 0x7f, i = 0; i < joysticks; ++i) - { - if (player_rank[i] < l) { - l = player_rank[i]; - } - } - - if (l <= 1) { - put_str(NTADR_A(12, 4), I18N_EN_WINNER); - } else { - put_str(NTADR_A(12, 4), I18N_EN_LOOSER); - vram_adr(NTADR_A(13, 4)); - vram_put(digit_lockup[1][l]); - vram_put(digit_lockup[0][l]); - } - - gamestate = FSM_CELEBRATION; - ppu_on_all(); -} \ No newline at end of file diff --git a/src/screen.h b/src/screen.h deleted file mode 100644 index f9d66f6..0000000 --- a/src/screen.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef H_SCREEN_KOKOBATORU -#define H_SCREEN_KOKOBATORU - -void screen_menu(); -void screen_arena(); -void screen_celebration(); - -#endif diff --git a/src/spawn.c b/src/spawn.c deleted file mode 100644 index 37fe412..0000000 --- a/src/spawn.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "spawn.h" - -void spawn() -{ - unsigned char colorvar = 2; - - /** reset scores**/ - for (i = 0; i < MAX_PLAYERS; i++) { - player_score[i] = 0; - player_rank[i] = 0; - } - /** reset postions **/ - for (i = 0; i < MAX_ENIMIES; i++) - { - if (joysticks == 1 && i == 0){ - // single player center - players[i].x = MID_ARENA_X; - players[i].y = MID_ARENA_Y; - } - else if (i < joysticks) { - // multi player positions - players[i].x = MID_ARENA_X + (i&1? RANGE_ARENA/2: RANGE_ARENA/(-2)); - players[i].y = MID_ARENA_Y + (i&2? RANGE_ARENA/2: RANGE_ARENA/(-2)); - } - else do { - // random npc positions - players[i].x = rand8(); - players[i].y = rand8(); - // reset npc behavior - npcs[i].input = 0; - npcs[i].state = FSM_DEFAULT; - } - while ( - // uncenter npc positions - players[i].x > MID_ARENA_X - RANGE_ARENA && players[i].x < MID_ARENA_X + RANGE_ARENA - && players[i].y > MID_ARENA_Y - RANGE_ARENA && players[i].y < MID_ARENA_Y + RANGE_ARENA - ); - // look to center - players[i].info.status.flipped = players[i].x > MID_ARENA_X? LOOK_LEFT: LOOK_RIGHT; - players[i].info.status.colorvar = (++colorvar >> 2) % 3; - players[i].info.status.death = FALSE; - } -} diff --git a/src/spawn.h b/src/spawn.h deleted file mode 100644 index 87055f2..0000000 --- a/src/spawn.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef H_SPAWN_KOKOBATORU -#define H_SPAWN_KOKOBATORU - -void spawn(void); - -#endif