From a3ddd06d49127e62f2e240efc54b5cf38f5c25cc Mon Sep 17 00:00:00 2001 From: jordism Date: Wed, 24 Apr 2019 23:21:52 +0200 Subject: [PATCH 1/3] try to get zx_print working --- alley.c | 11 ++- font.asm | 7 ++ game.font | Bin 0 -> 768 bytes game_zx.asm | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ game_zx.h | 14 +++ zproject.lst | 4 +- 6 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 font.asm create mode 100644 game.font create mode 100644 game_zx.asm create mode 100644 game_zx.h diff --git a/alley.c b/alley.c index 6ec9e6c..3599fb8 100644 --- a/alley.c +++ b/alley.c @@ -9,6 +9,7 @@ #include #include #include "int.h" +#include "game_zx.h" #define RIGHTC1 1 #define RIGHTC2 33 @@ -142,6 +143,12 @@ uint8_t repaint_lives = 1; uint8_t idx; struct sprite * collided_sprite; +// for printing +unsigned char screen_paper; +unsigned char screen_ink; +unsigned char tbuffer[7]; + + static void initialiseColourBlue(unsigned int count, struct sp1_cs *c) { (void)count; /* Suppress compiler warning about unused parameter */ @@ -569,6 +576,7 @@ void check_fsm() { void all_lives_lost() { zx_border(INK_BLACK); + zx_print_ink(INK_WHITE); sp1_Invalidate(&full_screen); lives = 5; points = 0; @@ -712,7 +720,8 @@ int main() if(repaint_lives) { - sp1_PrintAtInv(0, 8, INK_CYAN | PAPER_BLACK, 48 + lives); + zx_print_int(0, 8, lives); + //sp1_PrintAtInv(0, 8, INK_CYAN | PAPER_BLACK, 48 + lives); repaint_lives = 0; } diff --git a/font.asm b/font.asm new file mode 100644 index 0000000..d95696e --- /dev/null +++ b/font.asm @@ -0,0 +1,7 @@ +SECTION FONT + +PUBLIC _game_font + +_game_font: + + BINARY "game.font" diff --git a/game.font b/game.font new file mode 100644 index 0000000000000000000000000000000000000000..668eda5d2234d99e12dfa6fdd08c1eca3aceae53 GIT binary patch literal 768 zcmXw1v1;5v5FHXBu2_u9EsQPj6<4aYOc4pqpvLc$Hwa!RuS}xS@_k=a0|M&o#x^^{qU*n0o zs!h~&)ULt$G1rBWt!F3U2Bt0aka>)Ymb4P61^*KO;VcemX{M!ygLeT6u5 z^h5Wx_?gNiQYXIh!y!H9gI1!qz`g9RvX$h^w(Pq_mSc|VJinQLW^59TN%AaO6;aNw E|7oA#Gynhq literal 0 HcmV?d00001 diff --git a/game_zx.asm b/game_zx.asm new file mode 100644 index 0000000..43d8ed8 --- /dev/null +++ b/game_zx.asm @@ -0,0 +1,238 @@ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRINTING UTILITIES ;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +SECTION code_user + +; void zx_print_str(unsigned char ui_row, unsigned char ui_col, unsigned char *s) +; callee linkage + +PUBLIC _zx_print_str + +EXTERN asm_zx_cxy2saddr, asm_zx_saddr2aaddr +EXTERN _game_font, _screen_ink, _screen_paper + +_zx_print_str: + +IF __SDCC + + pop af + pop hl ; l = row, h = col + pop de ; de = s + push af + + ld a,l + ld l,h + ld h,a + +ENDIF + +IF __SCCZ80 + + pop hl + pop de ; de = s + pop bc ; c = col + ex (sp),hl ; l = row + + ld h,l + ld l,c + +ENDIF + +zx_print_str: + + ; h = y coord + ; l = x coord + ; de = char *s + + call asm_zx_cxy2saddr ; z88dk function: character y,x to screen address + ex de,hl + +zps_sloop: + + ; de = char *screen + ; hl = char *s + + ld a,(hl) + + or a + ret z + + push de + push hl + + ld l,a + ld h,0 + + ; hl = char c + ; de = char *screen + ; stack = char *screen, char *s + + add hl,hl + add hl,hl + add hl,hl + ld bc, _game_font - 256 + add hl,bc + + ld b,8 + +zps_cloop: + + ld a,(hl) + ld (de),a + inc hl + inc d + + djnz zps_cloop + + dec d + ex de,hl + + call asm_zx_saddr2aaddr ; z88dk function: screen address to attribute address + + ld a,(_screen_ink) + ld b,a + ld a,(_screen_paper) + or b + + ld (hl),a + + pop hl + pop de + + inc e + inc hl + + jr zps_sloop + + +; void zx_print_int(unsigned char ui_row, unsigned char ui_col, unsigned int val) +; callee linkage + +PUBLIC _zx_print_int + +EXTERN l_small_utoa, _tbuffer + +_zx_print_int: + +IF __SDCC + + pop af + pop de ; e = row, d = col + pop hl ; hl = val + push af + + ld a,e + ld e,d + ld d,a + +ENDIF + +IF __SCCZ80 + + pop af + pop hl ; hl = val + pop de ; e = col + pop bc ; c = row + push af + + ld d,c + +ENDIF + +zx_print_int: + + ; e = col + ; d = row + ; hl = val + + push de + ld de,_tbuffer + + ; hl = unsigned int val + ; de = char *buffer + ; stack = row/col + + scf ; request leading zeroes + call l_small_utoa ; z88dk function: unsigned int to ascii buffer + + ; ld a,'0' + + ; ld (de),a ; add trailing zero to multiply scores by 10 + ; inc de + + xor a + ld (de),a ; zero terminate + + pop hl + ld de,_tbuffer + + ; de = char *buffer + ; h = row + ; l = col + + jp zx_print_str + + +; void zx_print_chr(unsigned char ui_row, unsigned char ui_col, unsigned char val) +; callee linkage + +PUBLIC _zx_print_chr + +EXTERN l_small_utoa, _tbuffer + +_zx_print_chr: + +IF __SDCC + + pop hl + dec sp + pop de ; d = row + ex (sp),hl ; l = col, h = val + + ld e,l + ld l,h + ld h,0 + +ENDIF + +IF __SCCZ80 + + pop af + pop hl ; hl = val + pop de ; e = col + pop bc ; c = row + push af + + ld d,c + +ENDIF + +zx_print_chr: + + ; e = col + ; d = row + ; hl = val + + push de + ld de,_tbuffer + + ; hl = unsigned int val + ; de = char *buffer + ; stack = row/col + + scf ; request leading zeroes + call l_small_utoa ; z88dk function: unsigned int to ascii buffer + + xor a + ld (de),a ; zero terminate + + pop hl + ld de,_tbuffer+2 ; print last three digits only + + ; de = char *buffer + ; h = row + ; l = col + + jp zx_print_str diff --git a/game_zx.h b/game_zx.h new file mode 100644 index 0000000..2fc5875 --- /dev/null +++ b/game_zx.h @@ -0,0 +1,14 @@ +#ifndef GAME_ZX +#define GAME_ZX + +#include +#include + +#define zx_print_ink(a) (screen_ink = (a)) + + +extern void zx_print_chr(unsigned char ui_row, unsigned char ui_col, unsigned char val) __z88dk_callee; +extern void zx_print_int(unsigned char ui_row, unsigned char ui_col, unsigned int val) __z88dk_callee; +extern void zx_print_str(unsigned char ui_row, unsigned char ui_col, unsigned char *s) __z88dk_callee; + +#endif diff --git a/zproject.lst b/zproject.lst index 62220ca..d703681 100644 --- a/zproject.lst +++ b/zproject.lst @@ -1,3 +1,5 @@ @build/binaries.lst +font +game_zx alley.c -int.c \ No newline at end of file +int.c From de9761481ccb9d6c525484a2178088014b1b5a2c Mon Sep 17 00:00:00 2001 From: jordism Date: Sun, 28 Apr 2019 18:21:38 +0200 Subject: [PATCH 2/3] reorder the house --- .DS_Store | Bin 6148 -> 8196 bytes alley.c | 582 +-------------------------------------------------- game_zx.asm | 238 --------------------- game_zx.c | 18 ++ game_zx.h | 7 +- globals.c | 67 ++++++ globals.h | 112 ++++++++++ logic.c | 320 ++++++++++++++++++++++++++++ logic.h | 18 ++ sprites.c | 106 ++++++++++ sprites.h | 25 +++ zproject.lst | 5 +- 12 files changed, 675 insertions(+), 823 deletions(-) delete mode 100644 game_zx.asm create mode 100644 game_zx.c create mode 100644 globals.c create mode 100644 globals.h create mode 100644 logic.c create mode 100644 logic.h create mode 100644 sprites.c create mode 100644 sprites.h diff --git a/.DS_Store b/.DS_Store index aa0e99b3db14cecdf1a6172eda239f3f5f10cf90..58a5c5769bde6e472e9699593be6b8ef2816d473 100644 GIT binary patch literal 8196 zcmeHMTWl0n7(U<9!WlZyp;lVa&2C+x1WRa3OM|Fg+JZt$T5U_qMcUb&5k{voWoLE^ zv?bL`R6-l_Mc^pp)GGTFjmbN<5UG|Wz^iD2)(F_N-UI=5Q6L(Gcse|XvTIki^fKR zC<0Lgq6kD0h$0Y0;MRx$y|YE(OT71`Hfo~?L=m_xBOuO)Bvpaw5T_&tM+Y@Q3P31Q zfS}MdA6Ee&oazRc-`l^_UyHu*>9O+Lt16K>-f6mn7KK_4-Z(5;f}SrdB^YqKRvpC zjBJC6hP3MO@y6!nx@2QZ^JHCeyrreSF4?qo+vFtYRqGob+A})(@got~U2^aEMf&W||WkhUhP+u6LW`{qvD?zK*tBrEr_IoGy(T+b424h;I{318?I zsRj>vZq9EHoDFGO-ZLLJ$(L0yJIJFqXwj6yP=j)5byecNjhh==9!&3=F4xvnsFmv4 zfr8~(8Qbh1vkd>(0o}`*j$t`R57NVNeCtWe%qeS7r}R1ch&f$Reb>6X?}^73jxKr` z%xA3QdCNbkr8t*!)WlPY_5nX^(CzGV4dKxUH1V2vE$4@Xygg@9E5+)jc%7o@yw9V% zmM*ra4T|O|eNWSqm!?hXHm(^;zpZCXTZ*=;JGj=V3>0Li%&fo>SgmXBLi+B}p;vKw;_wXS;!Ke5f zUtk(P;1~Rg-|#!G;h$J(Y-KF`u^ub3y{EVgiLpw;IUAbT9)6IEUA!^d6T2UIbdTD3 z>$3goYC-WkD(_rdm0Z7ROVjp;+h&Qd;MvdRU_d*`tAKAsJ_V0^K8fXCP!s(`OY_81 zTS8kQwhx~cqigO>Bs4)j+1*e}-56~S*}cCmp=!&B`bsdkzClfBrNnZnZQiD;S_y3f zseNDvX_ph>rM5LrS{CZcY7;6~ZWejJX5X+D}FM;WS7LxkOo7PJywJFpA8 z(T&H@i$3(@2!@HcS)%R;TpUM^=sSVan8Gu77BAu~k@sc1f(u06*YG;tz+1S4w~5A= zafN975z+V?BJowsgybxewrf6V@zZ?L7J74z?K($ETC|vN5cO_G1eQrB)#6CmweaZ2Lc9QBaRZ+yaDT#pzH94f55!kyZH~G%PYhH delta 169 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{MGjUEV6q~50$jG!YU^nAr0~wad`~qT($0n-@ zG^mMISDWZ4Sen=BC{&x98|WyQSs2vTa&U;N8rpg$ #include #include +#include "logic.h" +#include "sprites.h" +#include "globals.h" #include "int.h" #include "game_zx.h" -#define RIGHTC1 1 -#define RIGHTC2 33 -#define LEFTC1 65 -#define LEFTC2 97 -#define UP1 129 -#define UP2 161 -#define DOWN1 193 -#define DOWN2 225 -#define DECIDED_DIRECTION 1 -#define UNDECIDED 0 - -#define GHOST_RED 1 -#define GHOST_RED2 33 -#define GHOST_CYAN 65 -#define GHOST_CYAN2 97 -#define GHOST_YELLOW 129 -#define GHOST_YELLOW2 161 -#define GHOST_MAGENTA 193 -#define GHOST_MAGENTA2 225 - -#define DIR_UP 1 -#define DIR_DOWN 2 -#define DIR_LEFT 3 -#define DIR_RIGHT 4 -#define NONE 250 -#define JAILED 20 -#define JAILED_EXITING 1 -#define ACTIVE 0 - -#define AYCTRL 65533 -#define AYDATA 49149 - -// screen rectangle -struct sp1_Rect full_screen = {0, 0, 32, 24}; -// it comes from built binaries: -extern uint8_t sprite_protar1[]; -extern uint8_t sprite_protar2[]; -// red ghost -extern uint8_t red_ghost1[]; -extern uint8_t red_ghost2[]; -// using UDG from ASM -extern uint8_t horizontal[]; -extern uint8_t vertical[]; -extern uint8_t corner_left[]; -extern uint8_t corner_right[]; -extern uint8_t corner_bottom_right[]; -extern uint8_t corner_bottom_left[]; -extern uint8_t pill[]; -extern uint8_t vertileft[]; -extern uint8_t vertiright[]; -extern uint8_t topvertileft[]; -extern uint8_t topvertiright[]; -extern uint8_t ghostpill[]; - -uint8_t random_value; - -// or using UDG from just code -uint8_t map[25][32] = { -{3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,14,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4}, -{2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2}, -{2,9,9,9,9,9,9,9,9,9,9,9,9,9,0,8,12,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2}, -{2,9,0,3,1,4,9,0,3,1,1,1,4,9,0,8,12,9,0,3,1,1,1,4,9,0,3,1,4,9,0,2}, -{2,11,0,2,0,2,9,0,2,0,0,0,2,9,0,8,12,9,0,2,0,0,0,2,9,0,2,0,2,11,0,2}, -{2,9,0,5,1,6,9,0,5,1,1,1,6,9,0,8,12,9,0,5,1,1,1,6,9,0,5,1,6,9,0,2}, -{2,9,0,0,0,0,9,0,0,0,0,0,0,9,0,0,0,9,0,0,0,0,0,0,9,0,0,0,0,9,0,2}, -{2,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2}, -{2,9,0,1,1,1,9,0,2,9,0,1,1,1,1,13,14,1,1,1,1,9,0,2,9,0,1,1,1,9,0,2}, -{2,9,0,0,0,0,9,0,2,9,0,0,0,0,0,8,12,0,0,0,0,9,0,2,9,0,0,0,0,9,0,2}, -{2,9,9,9,9,9,9,0,2,9,9,9,9,9,0,8,12,9,9,9,9,9,0,2,9,9,9,9,9,9,0,2}, -{5,1,1,1,1,1,9,0,2,1,1,1,1,9,0,8,12,9,0,1,1,1,1,2,9,0,1,1,1,1,1,6}, -{0,0,0,0,0,0,9,0,2,0,0,0,0,9,0,0,0,9,0,0,0,0,0,2,9,0,0,0,0,0,0,0}, -{0,9,9,9,9,9,9,0,2,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2,9,9,9,9,9,9,0,0}, -{3,1,1,1,1,1,9,0,2,9,0,3,1,1,1,0,0,1,1,1,4,9,0,2,9,0,1,1,1,1,1,4}, -{2,0,0,0,0,0,9,0,2,9,0,2,0,0,0,0,0,0,0,0,2,9,0,2,9,0,0,0,0,0,0,2}, -{2,9,9,9,9,9,9,0,2,9,0,2,0,0,0,0,0,0,0,0,2,9,0,2,9,9,9,9,9,9,0,2}, -{2,9,0,3,1,4,9,0,2,9,0,5,1,1,1,1,1,1,1,1,6,9,0,2,9,0,3,1,4,9,0,2}, -{2,9,0,2,0,2,9,0,0,9,0,0,0,0,0,0,0,0,0,0,0,9,0,0,9,0,2,0,2,9,0,2}, -{2,11,0,2,0,2,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2,0,2,11,0,2}, -{2,9,0,5,1,6,9,0,1,1,1,1,9,0,1,1,1,1,9,0,1,1,1,1,9,0,5,1,6,9,0,2}, -{2,9,0,0,0,0,9,0,0,0,0,0,9,0,0,0,0,0,9,0,0,0,0,0,9,0,0,0,0,9,0,2}, -{2,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2}, -{5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,6}, -}; - - -// 15 -uint8_t correspondence[] = {' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}; -uint8_t colors[] = {INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_WHITE, INK_BLUE, INK_MAGENTA, INK_BLUE, INK_BLUE, INK_BLUE}; - -extern uint8_t cartoon0[]; - -// globals are supposed to generate less code and with 128k of memory it's important -struct sprite { - struct sp1_ss* sp; - uint8_t x; - uint8_t y; - uint8_t offset; - uint8_t currentoffset; - uint8_t active; - int8_t dx; - int8_t dy; - uint8_t default_x; - uint8_t default_y; - void *default_color; -}; - -uint8_t pill_eaten = NONE; -struct sprite pacman; -struct sprite ghost_red; -struct sprite ghost_cyan; -struct sprite ghost_magenta; -struct sprite ghost_yellow; - -struct sprite * ghosts[4] = {&ghost_red, &ghost_cyan, &ghost_magenta, &ghost_yellow}; - -JOYFUNC joy; -// redefine this array to allow define keys -udk_t joy_keys = { IN_KEY_SCANCODE_SPACE, IN_KEY_SCANCODE_p, IN_KEY_SCANCODE_o, IN_KEY_SCANCODE_a, IN_KEY_SCANCODE_q }; -uint16_t in; -// reusable vars -uint8_t row; -uint8_t col; -uint8_t current; -uint16_t points = 0; - -uint8_t frame = 0; - -uint8_t lives = 0; -uint8_t repaint_lives = 1; -uint8_t idx; -struct sprite * collided_sprite; - -// for printing -unsigned char screen_paper; -unsigned char screen_ink; -unsigned char tbuffer[7]; - - -static void initialiseColourBlue(unsigned int count, struct sp1_cs *c) -{ - (void)count; /* Suppress compiler warning about unused parameter */ - - c->attr_mask = SP1_AMASK_INK; - c->attr = INK_BLUE; -} - -static void initialiseColourWhite(unsigned int count, struct sp1_cs *c) -{ - (void)count; /* Suppress compiler warning about unused parameter */ - - c->attr_mask = SP1_AMASK_INK; - c->attr = INK_WHITE; -} - -static void initialiseColourYellow(unsigned int count, struct sp1_cs *c) -{ - (void)count; /* Suppress compiler warning about unused parameter */ - - c->attr_mask = SP1_AMASK_INK; - c->attr = INK_YELLOW; -} - -static void initialiseColourGhostRed(unsigned int count, struct sp1_cs *c) -{ - // count defines each 8x8 block in the sprite, and thus it is possible to have a - // multicolor sprite in 8x8 blocks - (void)count; /* Suppress compiler warning about unused parameter */ - - c->attr_mask = SP1_AMASK_INK; - - c->attr = INK_RED; -} - -static void initialiseColourGhostCyan(unsigned int count, struct sp1_cs *c) -{ - // count defines each 8x8 block in the sprite, and thus it is possible to have a - // multicolor sprite in 8x8 blocks - (void)count; /* Suppress compiler warning about unused parameter */ - - c->attr_mask = SP1_AMASK_INK; - c->attr = INK_CYAN; -} - -static void initialiseColourGhostMagenta(unsigned int count, struct sp1_cs *c) -{ - // count defines each 8x8 block in the sprite, and thus it is possible to have a - // multicolor sprite in 8x8 blocks - (void)count; /* Suppress compiler warning about unused parameter */ - - c->attr_mask = SP1_AMASK_INK; - c->attr = INK_MAGENTA; -} - -struct sp1_ss * add_sprite() { - struct sp1_ss * sp; - sp = sp1_CreateSpr(SP1_DRAW_XOR1LB, SP1_TYPE_1BYTE, 3, (int)sprite_protar1, 1); - sp1_AddColSpr(sp, SP1_DRAW_XOR1, SP1_TYPE_1BYTE, (int)sprite_protar2, 1); - - sp1_AddColSpr(sp, SP1_DRAW_XOR1RB, SP1_TYPE_1BYTE, 0, 0); - - sp1_IterateSprChar(sp, initialiseColourYellow); - - return sp; -} - -struct sp1_ss * add_ghost_sprite() { - struct sp1_ss * sp; - sp = sp1_CreateSpr(SP1_DRAW_LOAD1LB, SP1_TYPE_1BYTE, 3, (int)red_ghost1, 1); - sp1_AddColSpr(sp, SP1_DRAW_LOAD1, SP1_TYPE_1BYTE, (int)red_ghost2, 1); - - sp1_AddColSpr(sp, SP1_DRAW_LOAD1RB, SP1_TYPE_1BYTE, 0, 0); - - return sp; -} - -struct sp1_ss * add_ghost_red_sprite() { - struct sp1_ss * sp = add_ghost_sprite(); - - - return sp; -} - -struct sp1_ss * add_ghost_cyan_sprite() { - struct sp1_ss * sp = add_ghost_sprite(); - - - return sp; -} - -struct sp1_ss * add_ghost_magenta_sprite() { - struct sp1_ss * sp = add_ghost_sprite(); - - - return sp; -} - -struct sp1_ss * add_ghost_yellow_sprite() { - struct sp1_ss * sp = add_ghost_sprite(); - - - return sp; -} - -uint8_t allow_next(uint8_t next) { - return next == 9 || next == 16 || next == 11 || next == 18; -} - - -void check_keys() -{ - // checks keys - // allow jump in directions - if ((in & IN_STICK_UP) && allow_next(map[row - 1][col])) { - pacman.dy = -1; - pacman.currentoffset = UP1; - - } else if((in & IN_STICK_DOWN) && allow_next(map[row + 1][col])) { - pacman.dy = 1; - pacman.currentoffset = DOWN1; - } - - if((in & IN_STICK_LEFT) && allow_next(map[row][col - 1])) { - pacman.dx = -1; - pacman.currentoffset = LEFTC1; - } else if((in & IN_STICK_RIGHT) && allow_next(map[row][col + 1])) { - pacman.dx = 1; - pacman.currentoffset = RIGHTC1; - } -} - -void iteratecolours(void * func) { - sp1_IterateSprChar(ghost_red.sp, func); - sp1_IterateSprChar(ghost_cyan.sp, func); - sp1_IterateSprChar(ghost_magenta.sp, func); - sp1_IterateSprChar(ghost_yellow.sp, func); -} - -void set_eaten(struct sprite * for_who) { - for_who->x = for_who->default_x; - for_who->y = for_who->default_y; - for_who->active = JAILED; - for_who->dx = 0; - for_who->dy = 0; - sp1_IterateSprChar(for_who->sp, for_who->default_color); -} - - -uint8_t goto_xy(struct sprite * for_who, uint8_t x, uint8_t y) { - if(for_who->x != x) { - if(for_who->x > x) { - --for_who->x; - } else if(for_who->x < x) { - ++for_who->x; - } - } else { - if(for_who->y > y) { - --for_who->y; - } else if(for_who->y < y) { - ++for_who->y; - } else { - return ACTIVE; - } - } - return JAILED_EXITING; -} - -struct sprite * has_collision() { - for(idx = 0; idx != 4; ++idx) { - if(pacman.x == ghosts[idx]->x && pacman.y == ghosts[idx]->y) { - // eat - return ghosts[idx]; - } - } - return NULL; -} - -uint8_t allow_next_ghost_pos(int8_t dy, int8_t dx) { - row = ghosts[idx]->y + 1; - return allow_next(map[row + dy][ghosts[idx]->x + dx]); -} - -uint8_t could_go(uint8_t dir) { - switch(dir) { - case DIR_RIGHT: - return allow_next(map[row][ghosts[idx]->x + 1]) && ghosts[idx]->dx != -1; - break; - case DIR_LEFT: - return allow_next(map[row][ghosts[idx]->x - 1]) && ghosts[idx]->dx != 1; - break; - case DIR_DOWN: - return allow_next(map[row + 1][ghosts[idx]->x]) && ghosts[idx]->dy != -1; - break; - case DIR_UP: - return allow_next(map[row - 1][ghosts[idx]->x]) && ghosts[idx]->dy != 1; - break; - } - return 0; -} - -void remember_where_we_go(int8_t dy, int8_t dx) { - ghosts[idx]->dx = dx; - ghosts[idx]->dy = dy; -} - -void then_go(uint8_t dir) { - switch(dir) { - case DIR_RIGHT: - remember_where_we_go(0, 1); - ghosts[idx]->x += 1; - break; - case DIR_LEFT: - remember_where_we_go(0, -1); - ghosts[idx]->x -= 1; - break; - case DIR_DOWN: - remember_where_we_go(1, 0); - ghosts[idx]->y += 1; - break; - case DIR_UP: - remember_where_we_go(-1, 0); - ghosts[idx]->y -= 1; - break; - } -} - -void move_one_ghost(uint8_t t1, uint8_t t2, uint8_t t3, uint8_t t4) { - if((random_value < t1) && could_go(DIR_RIGHT)) { - then_go(DIR_RIGHT); - return; - } else if((random_value < t2) && could_go(DIR_LEFT)) { - then_go(DIR_LEFT); - return; - } - - if((random_value < t3) && could_go(DIR_DOWN)) { - then_go(DIR_DOWN); - return; - } else if((random_value < t4) && could_go(DIR_UP)) { - then_go(DIR_UP); - return; - } - if(pill_eaten != NONE) { - if(pacman.x < ghosts[idx]->x && could_go(DIR_RIGHT)) { - then_go(DIR_RIGHT); - } else if(pacman.x > ghosts[idx]->x && could_go(DIR_LEFT)) { - then_go(DIR_LEFT); - } else if(pacman.y < ghosts[idx]->y && could_go(DIR_DOWN)) { - then_go(DIR_DOWN); - } else if(pacman.y > ghosts[idx]->y && could_go(DIR_UP)) { - then_go(DIR_UP); - } else if(allow_next(map[row + ghosts[idx]->dy][ghosts[idx]->x + ghosts[idx]->dx])) { - ghosts[idx]->x += ghosts[idx]->dx; - ghosts[idx]->y += ghosts[idx]->dy; - } - } else { - if(pacman.x > ghosts[idx]->x && could_go(DIR_RIGHT)) { - then_go(DIR_RIGHT); - } else if(pacman.x < ghosts[idx]->x && could_go(DIR_LEFT)) { - then_go(DIR_LEFT); - } else if(pacman.y > ghosts[idx]->y && could_go(DIR_DOWN)) { - then_go(DIR_DOWN); - } else if(pacman.y < ghosts[idx]->y && could_go(DIR_UP)) { - then_go(DIR_UP); - } else if(allow_next(map[row + ghosts[idx]->dy][ghosts[idx]->x + ghosts[idx]->dx])) { - ghosts[idx]->x += ghosts[idx]->dx; - ghosts[idx]->y += ghosts[idx]->dy; - } - } -} - -void move_ghosts() { - // &ghost_red, &ghost_cyan, &ghost_magenta, &ghost_yellow - row = ghosts[idx]->y + 1; - - switch(idx) { - case 0: // Rojo: Intenta estár detrás de Pac-Man en modo "Acoso" - move_one_ghost(40, 80, 40, 100); - break; - case 1: - // hasta que Pac-Man captura al menos 30 pildoras - move_one_ghost(90, 120, 100, 160); - break; - case 2: - // su comportamiento siempre es llegar hacia el punto donde Pac-Man - move_one_ghost(10, 20, 10, 20); - break; - case 3: - // "a su bola" - move_one_ghost(125, 255, 125, 255); - } - -/* - // se queda un poco de tiempo en la "Casa de los Fantasmas" en el primer nivel - // hasta que Pac-Man captura al menos 30 pildoras - idx = 1; - random_value = rand(); - move_one_ghost(90, 120, 80, 100); - - // Pink: su comportamiento siempre es llegar hacia el punto donde Pac-Man se está moviendo. - idx = 2; - random_value = rand(); - move_one_ghost(3, 5, 3, 6); - - // podemos explicar mejor como "a su bola" - idx = 3; - random_value = rand(); - move_one_ghost(125, 250, 130, 250);*/ - -} - -void check_fsm() { - random_value = rand(); - row = pacman.y + 1; - if(row > 22) { - row = 22; - } - col = pacman.x; - if(col > 31) { - col = 31; - } - // row and col must be set at this point - check_keys(); - - // pill eat - current = map[row][col]; - if(current != 16 && current != 18) { - map[row][col] = current + 7; // 9 + 7 = 16, 11 + 7 = 18 - sp1_PrintAtInv(row, col, INK_BLACK, ' '); - - if(current == 9) { - points += 10; // ten points each - } else if(current == 11) { - points += 50; // energizers - are worth 50 points each - pill_eaten = 125; - iteratecolours(initialiseColourBlue); - } - } - - - - // side change - if(pacman.y == 12) { - if(pacman.x < 2 && pacman.dx == -1) { - pacman.x = 29; - } else if(pacman.x > 28 && pacman.dx == 1) { - pacman.x = 1; - } - } - - if(ghosts[frame]->y == 12) { - if(ghosts[frame]->x < 2 && ghosts[frame]->dx == -1) { - ghosts[frame]->x = 29; - } else if(ghosts[frame]->x > 28 && ghosts[frame]->dx == 1) { - ghosts[frame]->x = 1; - } - } - - - if(allow_next(map[row + pacman.dy][col + pacman.dx])) { - pacman.y += pacman.dy; - pacman.x += pacman.dx; - } else if (pacman.dy != 0) { - pacman.dy = 0; - pacman.dx = 0; - } - - if((tick & 1) == 0) { - pacman.offset = pacman.currentoffset + 32; - ghosts[frame]->offset = ghosts[frame]->currentoffset + 32; - } else { - pacman.offset = pacman.currentoffset; - ghosts[frame]->offset = ghosts[frame]->currentoffset; - } - - // IA FOR GHOSTS - for(idx = 0; idx != 4; ++idx) { - if(ghosts[idx]->active == JAILED_EXITING) { - if(points > 300 || (points > 10 && idx != 1)) { - ghosts[idx]->active = goto_xy(ghosts[idx], 15, 12); - } - } else if(ghosts[idx]->active == ACTIVE) { - move_ghosts(); - } else { - --ghosts[idx]->active; - } - } - // while has eaten pill - if(pill_eaten != NONE) { - --pill_eaten; - // initialiseColourWhite, initialiseColourBlue - if(pill_eaten < 40) { - if((frame & 1) == 0) { - iteratecolours(initialiseColourBlue); - } else { - iteratecolours(initialiseColourWhite); - } - } - - collided_sprite = has_collision(); - if(collided_sprite != NULL) { - // eat - set_eaten(collided_sprite); - } - } - - if(pill_eaten == 0) { - pill_eaten = NONE; - sp1_IterateSprChar(ghost_red.sp, initialiseColourGhostRed); - sp1_IterateSprChar(ghost_cyan.sp, initialiseColourGhostCyan); - sp1_IterateSprChar(ghost_magenta.sp, initialiseColourGhostMagenta); - sp1_IterateSprChar(ghost_yellow.sp, initialiseColourYellow); - } - - if(pill_eaten == NONE) { - collided_sprite = has_collision(); - if(collided_sprite != NULL) { - loose_a_live(); - } - } -} void all_lives_lost() { zx_border(INK_BLACK); - zx_print_ink(INK_WHITE); sp1_Invalidate(&full_screen); lives = 5; points = 0; @@ -653,21 +95,6 @@ void all_lives_lost() { } - -void loose_a_live() { - repaint_lives = 1; - --lives; - set_eaten(&ghost_magenta); - set_eaten(&ghost_red); - set_eaten(&ghost_cyan); - set_eaten(&ghost_yellow); - - pacman.y = 21; - pacman.x = 14; - pacman.dx = 0; - pacman.dy = 0; -} - int main() { setup_int(); @@ -720,8 +147,7 @@ int main() if(repaint_lives) { - zx_print_int(0, 8, lives); - //sp1_PrintAtInv(0, 8, INK_CYAN | PAPER_BLACK, 48 + lives); + sp1_PrintAtInv(0, 8, INK_CYAN | PAPER_BLACK, 48 + lives); repaint_lives = 0; } diff --git a/game_zx.asm b/game_zx.asm deleted file mode 100644 index 43d8ed8..0000000 --- a/game_zx.asm +++ /dev/null @@ -1,238 +0,0 @@ - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; PRINTING UTILITIES ;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -SECTION code_user - -; void zx_print_str(unsigned char ui_row, unsigned char ui_col, unsigned char *s) -; callee linkage - -PUBLIC _zx_print_str - -EXTERN asm_zx_cxy2saddr, asm_zx_saddr2aaddr -EXTERN _game_font, _screen_ink, _screen_paper - -_zx_print_str: - -IF __SDCC - - pop af - pop hl ; l = row, h = col - pop de ; de = s - push af - - ld a,l - ld l,h - ld h,a - -ENDIF - -IF __SCCZ80 - - pop hl - pop de ; de = s - pop bc ; c = col - ex (sp),hl ; l = row - - ld h,l - ld l,c - -ENDIF - -zx_print_str: - - ; h = y coord - ; l = x coord - ; de = char *s - - call asm_zx_cxy2saddr ; z88dk function: character y,x to screen address - ex de,hl - -zps_sloop: - - ; de = char *screen - ; hl = char *s - - ld a,(hl) - - or a - ret z - - push de - push hl - - ld l,a - ld h,0 - - ; hl = char c - ; de = char *screen - ; stack = char *screen, char *s - - add hl,hl - add hl,hl - add hl,hl - ld bc, _game_font - 256 - add hl,bc - - ld b,8 - -zps_cloop: - - ld a,(hl) - ld (de),a - inc hl - inc d - - djnz zps_cloop - - dec d - ex de,hl - - call asm_zx_saddr2aaddr ; z88dk function: screen address to attribute address - - ld a,(_screen_ink) - ld b,a - ld a,(_screen_paper) - or b - - ld (hl),a - - pop hl - pop de - - inc e - inc hl - - jr zps_sloop - - -; void zx_print_int(unsigned char ui_row, unsigned char ui_col, unsigned int val) -; callee linkage - -PUBLIC _zx_print_int - -EXTERN l_small_utoa, _tbuffer - -_zx_print_int: - -IF __SDCC - - pop af - pop de ; e = row, d = col - pop hl ; hl = val - push af - - ld a,e - ld e,d - ld d,a - -ENDIF - -IF __SCCZ80 - - pop af - pop hl ; hl = val - pop de ; e = col - pop bc ; c = row - push af - - ld d,c - -ENDIF - -zx_print_int: - - ; e = col - ; d = row - ; hl = val - - push de - ld de,_tbuffer - - ; hl = unsigned int val - ; de = char *buffer - ; stack = row/col - - scf ; request leading zeroes - call l_small_utoa ; z88dk function: unsigned int to ascii buffer - - ; ld a,'0' - - ; ld (de),a ; add trailing zero to multiply scores by 10 - ; inc de - - xor a - ld (de),a ; zero terminate - - pop hl - ld de,_tbuffer - - ; de = char *buffer - ; h = row - ; l = col - - jp zx_print_str - - -; void zx_print_chr(unsigned char ui_row, unsigned char ui_col, unsigned char val) -; callee linkage - -PUBLIC _zx_print_chr - -EXTERN l_small_utoa, _tbuffer - -_zx_print_chr: - -IF __SDCC - - pop hl - dec sp - pop de ; d = row - ex (sp),hl ; l = col, h = val - - ld e,l - ld l,h - ld h,0 - -ENDIF - -IF __SCCZ80 - - pop af - pop hl ; hl = val - pop de ; e = col - pop bc ; c = row - push af - - ld d,c - -ENDIF - -zx_print_chr: - - ; e = col - ; d = row - ; hl = val - - push de - ld de,_tbuffer - - ; hl = unsigned int val - ; de = char *buffer - ; stack = row/col - - scf ; request leading zeroes - call l_small_utoa ; z88dk function: unsigned int to ascii buffer - - xor a - ld (de),a ; zero terminate - - pop hl - ld de,_tbuffer+2 ; print last three digits only - - ; de = char *buffer - ; h = row - ; l = col - - jp zx_print_str diff --git a/game_zx.c b/game_zx.c new file mode 100644 index 0000000..fb6bbcc --- /dev/null +++ b/game_zx.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +// reversed order digit extract +void print_points(uint16_t number) { + uint8_t pos = 18; + + while (number > 0) + { + number = number % 10; + number /= 10; + //print digit + sp1_PrintAtInv(0, pos, INK_CYAN | PAPER_BLACK, 48 + number); + --pos; + } +} \ No newline at end of file diff --git a/game_zx.h b/game_zx.h index 2fc5875..105f7ca 100644 --- a/game_zx.h +++ b/game_zx.h @@ -4,11 +4,6 @@ #include #include -#define zx_print_ink(a) (screen_ink = (a)) - - -extern void zx_print_chr(unsigned char ui_row, unsigned char ui_col, unsigned char val) __z88dk_callee; -extern void zx_print_int(unsigned char ui_row, unsigned char ui_col, unsigned int val) __z88dk_callee; -extern void zx_print_str(unsigned char ui_row, unsigned char ui_col, unsigned char *s) __z88dk_callee; +extern void print_points(uint16_t number); #endif diff --git a/globals.c b/globals.c new file mode 100644 index 0000000..d3023c7 --- /dev/null +++ b/globals.c @@ -0,0 +1,67 @@ +#include "globals.h" + +struct sp1_Rect full_screen = {0, 0, 32, 24}; + +uint8_t random_value; + +// or using UDG from just code +uint8_t map[25][32] = { +{3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,13,14,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4}, +{2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2}, +{2,9,9,9,9,9,9,9,9,9,9,9,9,9,0,8,12,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2}, +{2,9,0,3,1,4,9,0,3,1,1,1,4,9,0,8,12,9,0,3,1,1,1,4,9,0,3,1,4,9,0,2}, +{2,11,0,2,0,2,9,0,2,0,0,0,2,9,0,8,12,9,0,2,0,0,0,2,9,0,2,0,2,11,0,2}, +{2,9,0,5,1,6,9,0,5,1,1,1,6,9,0,8,12,9,0,5,1,1,1,6,9,0,5,1,6,9,0,2}, +{2,9,0,0,0,0,9,0,0,0,0,0,0,9,0,0,0,9,0,0,0,0,0,0,9,0,0,0,0,9,0,2}, +{2,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2}, +{2,9,0,1,1,1,9,0,2,9,0,1,1,1,1,13,14,1,1,1,1,9,0,2,9,0,1,1,1,9,0,2}, +{2,9,0,0,0,0,9,0,2,9,0,0,0,0,0,8,12,0,0,0,0,9,0,2,9,0,0,0,0,9,0,2}, +{2,9,9,9,9,9,9,0,2,9,9,9,9,9,0,8,12,9,9,9,9,9,0,2,9,9,9,9,9,9,0,2}, +{5,1,1,1,1,1,9,0,2,1,1,1,1,9,0,8,12,9,0,1,1,1,1,2,9,0,1,1,1,1,1,6}, +{0,0,0,0,0,0,9,0,2,0,0,0,0,9,0,0,0,9,0,0,0,0,0,2,9,0,0,0,0,0,0,0}, +{0,9,9,9,9,9,9,0,2,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2,9,9,9,9,9,9,0,0}, +{3,1,1,1,1,1,9,0,2,9,0,3,1,1,1,0,0,1,1,1,4,9,0,2,9,0,1,1,1,1,1,4}, +{2,0,0,0,0,0,9,0,2,9,0,2,0,0,0,0,0,0,0,0,2,9,0,2,9,0,0,0,0,0,0,2}, +{2,9,9,9,9,9,9,0,2,9,0,2,0,0,0,0,0,0,0,0,2,9,0,2,9,9,9,9,9,9,0,2}, +{2,9,0,3,1,4,9,0,2,9,0,5,1,1,1,1,1,1,1,1,6,9,0,2,9,0,3,1,4,9,0,2}, +{2,9,0,2,0,2,9,0,0,9,0,0,0,0,0,0,0,0,0,0,0,9,0,0,9,0,2,0,2,9,0,2}, +{2,11,0,2,0,2,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2,0,2,11,0,2}, +{2,9,0,5,1,6,9,0,1,1,1,1,9,0,1,1,1,1,9,0,1,1,1,1,9,0,5,1,6,9,0,2}, +{2,9,0,0,0,0,9,0,0,0,0,0,9,0,0,0,0,0,9,0,0,0,0,0,9,0,0,0,0,9,0,2}, +{2,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,2}, +{5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,6}, +}; + + +// 15 +uint8_t correspondence[] = {' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}; +uint8_t colors[] = {INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_BLUE, INK_WHITE, INK_BLUE, INK_MAGENTA, INK_BLUE, INK_BLUE, INK_BLUE}; + + + + +uint8_t pill_eaten = NONE; +struct sprite pacman; +struct sprite ghost_red; +struct sprite ghost_cyan; +struct sprite ghost_magenta; +struct sprite ghost_yellow; + +struct sprite * ghosts[4] = {&ghost_red, &ghost_cyan, &ghost_magenta, &ghost_yellow}; + +JOYFUNC joy; +// redefine this array to allow define keys +udk_t joy_keys = { IN_KEY_SCANCODE_SPACE, IN_KEY_SCANCODE_p, IN_KEY_SCANCODE_o, IN_KEY_SCANCODE_a, IN_KEY_SCANCODE_q }; +uint16_t in; +// reusable vars +uint8_t row; +uint8_t col; +uint8_t current; +uint16_t points = 0; + +uint8_t frame = 0; + +uint8_t lives = 0; +uint8_t repaint_lives = 1; +uint8_t idx; +struct sprite * collided_sprite; diff --git a/globals.h b/globals.h new file mode 100644 index 0000000..02d315f --- /dev/null +++ b/globals.h @@ -0,0 +1,112 @@ +#ifndef GLOBALS_H +#define GLOBALS_H + +#include +#include +#include +#include +#include + + +#define RIGHTC1 1 +#define RIGHTC2 33 +#define LEFTC1 65 +#define LEFTC2 97 +#define UP1 129 +#define UP2 161 +#define DOWN1 193 +#define DOWN2 225 +#define DECIDED_DIRECTION 1 +#define UNDECIDED 0 + +#define GHOST_RED 1 +#define GHOST_RED2 33 +#define GHOST_CYAN 65 +#define GHOST_CYAN2 97 +#define GHOST_YELLOW 129 +#define GHOST_YELLOW2 161 +#define GHOST_MAGENTA 193 +#define GHOST_MAGENTA2 225 + +#define DIR_UP 1 +#define DIR_DOWN 2 +#define DIR_LEFT 3 +#define DIR_RIGHT 4 +#define NONE 250 +#define JAILED 20 +#define JAILED_EXITING 1 +#define ACTIVE 0 + +#define AYCTRL 65533 +#define AYDATA 49149 + +// screen rectangle +extern struct sp1_Rect full_screen; + +// globals are supposed to generate less code and with 128k of memory it's important +struct sprite { + struct sp1_ss* sp; + uint8_t x; + uint8_t y; + uint8_t offset; + uint8_t currentoffset; + uint8_t active; + int8_t dx; + int8_t dy; + uint8_t default_x; + uint8_t default_y; + void *default_color; +}; + +// it comes from built binaries: +extern uint8_t sprite_protar1[]; +extern uint8_t sprite_protar2[]; +// red ghost +extern uint8_t red_ghost1[]; +extern uint8_t red_ghost2[]; +// using UDG from ASM +extern uint8_t horizontal[]; +extern uint8_t vertical[]; +extern uint8_t corner_left[]; +extern uint8_t corner_right[]; +extern uint8_t corner_bottom_right[]; +extern uint8_t corner_bottom_left[]; +extern uint8_t pill[]; +extern uint8_t vertileft[]; +extern uint8_t vertiright[]; +extern uint8_t topvertileft[]; +extern uint8_t topvertiright[]; +extern uint8_t ghostpill[]; +extern uint8_t cartoon0[]; + +extern uint8_t map[25][32]; +extern uint8_t random_value; +extern uint8_t correspondence[]; +extern uint8_t colors[]; + +extern uint8_t pill_eaten; +extern struct sprite pacman; +extern struct sprite ghost_red; +extern struct sprite ghost_cyan; +extern struct sprite ghost_magenta; +extern struct sprite ghost_yellow; +extern struct sprite * ghosts[4]; + +extern JOYFUNC joy; +extern udk_t joy_keys; +extern uint16_t in; + +extern uint8_t row; +extern uint8_t col; +extern uint8_t current; +extern uint16_t points; + +extern uint8_t frame; + +extern uint8_t lives; +extern uint8_t repaint_lives; +extern uint8_t idx; +extern struct sprite * collided_sprite; + +#endif + diff --git a/logic.c b/logic.c new file mode 100644 index 0000000..a3e6ac6 --- /dev/null +++ b/logic.c @@ -0,0 +1,320 @@ +#include "logic.h" + + + +void check_keys() +{ + // checks keys + // allow jump in directions + if ((in & IN_STICK_UP) && allow_next(map[row - 1][col])) { + pacman.dy = -1; + pacman.currentoffset = UP1; + + } else if((in & IN_STICK_DOWN) && allow_next(map[row + 1][col])) { + pacman.dy = 1; + pacman.currentoffset = DOWN1; + } + + if((in & IN_STICK_LEFT) && allow_next(map[row][col - 1])) { + pacman.dx = -1; + pacman.currentoffset = LEFTC1; + } else if((in & IN_STICK_RIGHT) && allow_next(map[row][col + 1])) { + pacman.dx = 1; + pacman.currentoffset = RIGHTC1; + } +} + + +void loose_a_live() { + repaint_lives = 1; + --lives; + set_eaten(&ghost_magenta); + set_eaten(&ghost_red); + set_eaten(&ghost_cyan); + set_eaten(&ghost_yellow); + + pacman.y = 21; + pacman.x = 14; + pacman.dx = 0; + pacman.dy = 0; +} + +uint8_t allow_next(uint8_t next) { + return next == 9 || next == 16 || next == 11 || next == 18; +} + + +void iteratecolours(void * func) { + sp1_IterateSprChar(ghost_red.sp, func); + sp1_IterateSprChar(ghost_cyan.sp, func); + sp1_IterateSprChar(ghost_magenta.sp, func); + sp1_IterateSprChar(ghost_yellow.sp, func); +} + +void set_eaten(struct sprite * for_who) { + for_who->x = for_who->default_x; + for_who->y = for_who->default_y; + for_who->active = JAILED; + for_who->dx = 0; + for_who->dy = 0; + sp1_IterateSprChar(for_who->sp, for_who->default_color); +} + + +uint8_t goto_xy(struct sprite * for_who, uint8_t x, uint8_t y) { + if(for_who->x != x) { + if(for_who->x > x) { + --for_who->x; + } else if(for_who->x < x) { + ++for_who->x; + } + } else { + if(for_who->y > y) { + --for_who->y; + } else if(for_who->y < y) { + ++for_who->y; + } else { + return ACTIVE; + } + } + return JAILED_EXITING; +} + +struct sprite * has_collision() { + for(idx = 0; idx != 4; ++idx) { + if(pacman.x == ghosts[idx]->x && pacman.y == ghosts[idx]->y) { + // eat + return ghosts[idx]; + } + } + return NULL; +} + +uint8_t allow_next_ghost_pos(int8_t dy, int8_t dx) { + row = ghosts[idx]->y + 1; + return allow_next(map[row + dy][ghosts[idx]->x + dx]); +} + +uint8_t could_go(uint8_t dir) { + switch(dir) { + case DIR_RIGHT: + return allow_next(map[row][ghosts[idx]->x + 1]) && ghosts[idx]->dx != -1; + break; + case DIR_LEFT: + return allow_next(map[row][ghosts[idx]->x - 1]) && ghosts[idx]->dx != 1; + break; + case DIR_DOWN: + return allow_next(map[row + 1][ghosts[idx]->x]) && ghosts[idx]->dy != -1; + break; + case DIR_UP: + return allow_next(map[row - 1][ghosts[idx]->x]) && ghosts[idx]->dy != 1; + break; + } + return 0; +} + +void remember_where_we_go(int8_t dy, int8_t dx) { + ghosts[idx]->dx = dx; + ghosts[idx]->dy = dy; +} + +void then_go(uint8_t dir) { + switch(dir) { + case DIR_RIGHT: + remember_where_we_go(0, 1); + ghosts[idx]->x += 1; + break; + case DIR_LEFT: + remember_where_we_go(0, -1); + ghosts[idx]->x -= 1; + break; + case DIR_DOWN: + remember_where_we_go(1, 0); + ghosts[idx]->y += 1; + break; + case DIR_UP: + remember_where_we_go(-1, 0); + ghosts[idx]->y -= 1; + break; + } +} + +void move_one_ghost(uint8_t t1, uint8_t t2, uint8_t t3, uint8_t t4) { + if((random_value < t1) && could_go(DIR_RIGHT)) { + then_go(DIR_RIGHT); + return; + } else if((random_value < t2) && could_go(DIR_LEFT)) { + then_go(DIR_LEFT); + return; + } + + if((random_value < t3) && could_go(DIR_DOWN)) { + then_go(DIR_DOWN); + return; + } else if((random_value < t4) && could_go(DIR_UP)) { + then_go(DIR_UP); + return; + } + if(pill_eaten != NONE) { + if(pacman.x < ghosts[idx]->x && could_go(DIR_RIGHT)) { + then_go(DIR_RIGHT); + } else if(pacman.x > ghosts[idx]->x && could_go(DIR_LEFT)) { + then_go(DIR_LEFT); + } else if(pacman.y < ghosts[idx]->y && could_go(DIR_DOWN)) { + then_go(DIR_DOWN); + } else if(pacman.y > ghosts[idx]->y && could_go(DIR_UP)) { + then_go(DIR_UP); + } else if(allow_next(map[row + ghosts[idx]->dy][ghosts[idx]->x + ghosts[idx]->dx])) { + ghosts[idx]->x += ghosts[idx]->dx; + ghosts[idx]->y += ghosts[idx]->dy; + } + } else { + if(pacman.x > ghosts[idx]->x && could_go(DIR_RIGHT)) { + then_go(DIR_RIGHT); + } else if(pacman.x < ghosts[idx]->x && could_go(DIR_LEFT)) { + then_go(DIR_LEFT); + } else if(pacman.y > ghosts[idx]->y && could_go(DIR_DOWN)) { + then_go(DIR_DOWN); + } else if(pacman.y < ghosts[idx]->y && could_go(DIR_UP)) { + then_go(DIR_UP); + } else if(allow_next(map[row + ghosts[idx]->dy][ghosts[idx]->x + ghosts[idx]->dx])) { + ghosts[idx]->x += ghosts[idx]->dx; + ghosts[idx]->y += ghosts[idx]->dy; + } + } +} + +void move_ghosts() { + // &ghost_red, &ghost_cyan, &ghost_magenta, &ghost_yellow + row = ghosts[idx]->y + 1; + + switch(idx) { + case 0: // Rojo: Intenta estár detrás de Pac-Man en modo "Acoso" + move_one_ghost(40, 80, 40, 100); + break; + case 1: + // hasta que Pac-Man captura al menos 30 pildoras + move_one_ghost(90, 120, 100, 160); + break; + case 2: + // su comportamiento siempre es llegar hacia el punto donde Pac-Man + move_one_ghost(10, 20, 10, 20); + break; + case 3: + // "a su bola" + move_one_ghost(125, 255, 125, 255); + } + + +} + +void check_fsm() { + random_value = rand(); + row = pacman.y + 1; + if(row > 22) { + row = 22; + } + col = pacman.x; + if(col > 31) { + col = 31; + } + // row and col must be set at this point + check_keys(); + + // pill eat + current = map[row][col]; + if(current != 16 && current != 18) { + map[row][col] = current + 7; // 9 + 7 = 16, 11 + 7 = 18 + sp1_PrintAtInv(row, col, INK_BLACK, ' '); + + if(current == 9) { + points += 10; // ten points each + } else if(current == 11) { + points += 50; // energizers - are worth 50 points each + pill_eaten = 125; + iteratecolours(initialiseColourBlue); + } + } + + + + // side change + if(pacman.y == 12) { + if(pacman.x < 2 && pacman.dx == -1) { + pacman.x = 29; + } else if(pacman.x > 28 && pacman.dx == 1) { + pacman.x = 1; + } + } + + if(ghosts[frame]->y == 12) { + if(ghosts[frame]->x < 2 && ghosts[frame]->dx == -1) { + ghosts[frame]->x = 29; + } else if(ghosts[frame]->x > 28 && ghosts[frame]->dx == 1) { + ghosts[frame]->x = 1; + } + } + + + if(allow_next(map[row + pacman.dy][col + pacman.dx])) { + pacman.y += pacman.dy; + pacman.x += pacman.dx; + } else if (pacman.dy != 0) { + pacman.dy = 0; + pacman.dx = 0; + } + + if((tick & 1) == 0) { + pacman.offset = pacman.currentoffset + 32; + ghosts[frame]->offset = ghosts[frame]->currentoffset + 32; + } else { + pacman.offset = pacman.currentoffset; + ghosts[frame]->offset = ghosts[frame]->currentoffset; + } + + // IA FOR GHOSTS + for(idx = 0; idx != 4; ++idx) { + if(ghosts[idx]->active == JAILED_EXITING) { + if(points > 300 || (points > 10 && idx != 1)) { + ghosts[idx]->active = goto_xy(ghosts[idx], 15, 12); + } + } else if(ghosts[idx]->active == ACTIVE) { + move_ghosts(); + } else { + --ghosts[idx]->active; + } + } + // while has eaten pill + if(pill_eaten != NONE) { + --pill_eaten; + // initialiseColourWhite, initialiseColourBlue + if(pill_eaten < 40) { + if((frame & 1) == 0) { + iteratecolours(initialiseColourBlue); + } else { + iteratecolours(initialiseColourWhite); + } + } + + collided_sprite = has_collision(); + if(collided_sprite != NULL) { + // eat + set_eaten(collided_sprite); + } + } + + if(pill_eaten == 0) { + pill_eaten = NONE; + sp1_IterateSprChar(ghost_red.sp, initialiseColourGhostRed); + sp1_IterateSprChar(ghost_cyan.sp, initialiseColourGhostCyan); + sp1_IterateSprChar(ghost_magenta.sp, initialiseColourGhostMagenta); + sp1_IterateSprChar(ghost_yellow.sp, initialiseColourYellow); + } + + if(pill_eaten == NONE) { + collided_sprite = has_collision(); + if(collided_sprite != NULL) { + loose_a_live(); + } + } +} diff --git a/logic.h b/logic.h new file mode 100644 index 0000000..35fb87d --- /dev/null +++ b/logic.h @@ -0,0 +1,18 @@ +#ifndef LOGIC_H +#define LOGIC_H + +#include "sprites.h" +#include "globals.h" +#include "int.h" + + +#include +#include +#include +#include + +extern void check_fsm(); +extern uint8_t allow_next(uint8_t next); +extern void set_eaten(struct sprite * for_who); + +#endif diff --git a/sprites.c b/sprites.c new file mode 100644 index 0000000..fa0c563 --- /dev/null +++ b/sprites.c @@ -0,0 +1,106 @@ +#include "sprites.h" + +void initialiseColourBlue(unsigned int count, struct sp1_cs *c) +{ + (void)count; /* Suppress compiler warning about unused parameter */ + + c->attr_mask = SP1_AMASK_INK; + c->attr = INK_BLUE; +} + +void initialiseColourWhite(unsigned int count, struct sp1_cs *c) +{ + (void)count; /* Suppress compiler warning about unused parameter */ + + c->attr_mask = SP1_AMASK_INK; + c->attr = INK_WHITE; +} + +void initialiseColourYellow(unsigned int count, struct sp1_cs *c) +{ + (void)count; /* Suppress compiler warning about unused parameter */ + + c->attr_mask = SP1_AMASK_INK; + c->attr = INK_YELLOW; +} + +void initialiseColourGhostRed(unsigned int count, struct sp1_cs *c) +{ + // count defines each 8x8 block in the sprite, and thus it is possible to have a + // multicolor sprite in 8x8 blocks + (void)count; /* Suppress compiler warning about unused parameter */ + + c->attr_mask = SP1_AMASK_INK; + + c->attr = INK_RED; +} + +void initialiseColourGhostCyan(unsigned int count, struct sp1_cs *c) +{ + // count defines each 8x8 block in the sprite, and thus it is possible to have a + // multicolor sprite in 8x8 blocks + (void)count; /* Suppress compiler warning about unused parameter */ + + c->attr_mask = SP1_AMASK_INK; + c->attr = INK_CYAN; +} + +void initialiseColourGhostMagenta(unsigned int count, struct sp1_cs *c) +{ + // count defines each 8x8 block in the sprite, and thus it is possible to have a + // multicolor sprite in 8x8 blocks + (void)count; /* Suppress compiler warning about unused parameter */ + + c->attr_mask = SP1_AMASK_INK; + c->attr = INK_MAGENTA; +} + +struct sp1_ss * add_sprite() { + struct sp1_ss * sp; + sp = sp1_CreateSpr(SP1_DRAW_XOR1LB, SP1_TYPE_1BYTE, 3, (int)sprite_protar1, 1); + sp1_AddColSpr(sp, SP1_DRAW_XOR1, SP1_TYPE_1BYTE, (int)sprite_protar2, 1); + + sp1_AddColSpr(sp, SP1_DRAW_XOR1RB, SP1_TYPE_1BYTE, 0, 0); + + sp1_IterateSprChar(sp, initialiseColourYellow); + + return sp; +} + +struct sp1_ss * add_ghost_sprite() { + struct sp1_ss * sp; + sp = sp1_CreateSpr(SP1_DRAW_LOAD1LB, SP1_TYPE_1BYTE, 3, (int)red_ghost1, 1); + sp1_AddColSpr(sp, SP1_DRAW_LOAD1, SP1_TYPE_1BYTE, (int)red_ghost2, 1); + + sp1_AddColSpr(sp, SP1_DRAW_LOAD1RB, SP1_TYPE_1BYTE, 0, 0); + + return sp; +} + +struct sp1_ss * add_ghost_red_sprite() { + struct sp1_ss * sp = add_ghost_sprite(); + + + return sp; +} + +struct sp1_ss * add_ghost_cyan_sprite() { + struct sp1_ss * sp = add_ghost_sprite(); + + + return sp; +} + +struct sp1_ss * add_ghost_magenta_sprite() { + struct sp1_ss * sp = add_ghost_sprite(); + + + return sp; +} + +struct sp1_ss * add_ghost_yellow_sprite() { + struct sp1_ss * sp = add_ghost_sprite(); + + + return sp; +} \ No newline at end of file diff --git a/sprites.h b/sprites.h new file mode 100644 index 0000000..0563c9e --- /dev/null +++ b/sprites.h @@ -0,0 +1,25 @@ +#ifndef SPRITES_H +#define SPRITES_H + +#include +#include +#include +#include +#include "globals.h" + + +extern struct sp1_ss * add_sprite(); +extern struct sp1_ss * add_ghost_sprite(); +extern struct sp1_ss * add_ghost_red_sprite(); +extern struct sp1_ss * add_ghost_cyan_sprite(); +extern struct sp1_ss * add_ghost_magenta_sprite(); +extern struct sp1_ss * add_ghost_yellow_sprite(); + +extern void initialiseColourBlue(unsigned int count, struct sp1_cs *c); +extern void initialiseColourWhite(unsigned int count, struct sp1_cs *c); +extern void initialiseColourYellow(unsigned int count, struct sp1_cs *c); +extern void initialiseColourGhostCyan(unsigned int count, struct sp1_cs *c); +extern void initialiseColourGhostMagenta(unsigned int count, struct sp1_cs *c); +extern void initialiseColourGhostRed(unsigned int count, struct sp1_cs *c); + +#endif diff --git a/zproject.lst b/zproject.lst index d703681..76f0742 100644 --- a/zproject.lst +++ b/zproject.lst @@ -1,5 +1,8 @@ @build/binaries.lst font -game_zx +game_zx.c +logic.c +sprites.c +globals.c alley.c int.c From 7cf437172b7f39aef0113224107fffd61626e593 Mon Sep 17 00:00:00 2001 From: jordism Date: Sun, 28 Apr 2019 19:18:18 +0200 Subject: [PATCH 3/3] points working --- asm_strlen.asm | 50 +++++++++++++++++++++++++++++++++++++++++++ game_zx.c | 28 ++++++++++++++++-------- game_zx.h | 2 +- alley.c => msnampac.c | 8 +++++++ zproject.lst | 3 ++- 5 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 asm_strlen.asm rename alley.c => msnampac.c (92%) diff --git a/asm_strlen.asm b/asm_strlen.asm new file mode 100644 index 0000000..5eb0a38 --- /dev/null +++ b/asm_strlen.asm @@ -0,0 +1,50 @@ +; =============================================================== +; Dec 2013 +; =============================================================== +; +; size_t strlen(const char *s) +; +; Return length of string s. +; +; =============================================================== + + +SECTION code_clib +SECTION code_string + +PUBLIC asm_strlen + +asm_strlen: + + ; enter: hl = char *s + ; + ; exit : hl = length + ; bc = -(length + 1) + ; a = 0 + ; z flag set if 0 length + ; carry reset + ; + ; uses : af, bc, hl + + xor a + ld c,a + ld b,a + + cpir + + ld hl,$ffff + sbc hl,bc + + ret + +PUBLIC _strlen + +_strlen: + + pop af + pop hl + + push hl + push af + + jp asm_strlen diff --git a/game_zx.c b/game_zx.c index fb6bbcc..a96b4b1 100644 --- a/game_zx.c +++ b/game_zx.c @@ -2,17 +2,27 @@ #include #include #include +#include "globals.h" + +extern uint8_t strlen(char * chars); + +// temporary buffer to print points (e.g. 65535) +char * chars = "0000000\0"; + // reversed order digit extract -void print_points(uint16_t number) { - uint8_t pos = 18; +void print_points() { + utoa(points, chars, 10); + col = 5 - strlen(chars); - while (number > 0) - { - number = number % 10; - number /= 10; - //print digit - sp1_PrintAtInv(0, pos, INK_CYAN | PAPER_BLACK, 48 + number); - --pos; + if(col != 0) { + for(idx = 0; idx != 5; ++idx) { + sp1_PrintAtInv(0, 26 + idx, INK_CYAN | PAPER_BLACK, '0'); + } + } + idx = 0; + while(chars[idx] != '\0') { + sp1_PrintAtInv(0, 26 + idx + col, INK_CYAN | PAPER_BLACK, chars[idx]); + ++idx; } } \ No newline at end of file diff --git a/game_zx.h b/game_zx.h index 105f7ca..cfc01ee 100644 --- a/game_zx.h +++ b/game_zx.h @@ -4,6 +4,6 @@ #include #include -extern void print_points(uint16_t number); +extern void print_points(); #endif diff --git a/alley.c b/msnampac.c similarity index 92% rename from alley.c rename to msnampac.c index fa12200..cce17c9 100644 --- a/alley.c +++ b/msnampac.c @@ -68,6 +68,13 @@ void all_lives_lost() { } + sp1_PrintAtInv(0, 19, INK_RED | PAPER_BLACK, 'P'); + sp1_PrintAtInv(0, 20, INK_RED | PAPER_BLACK, 'O'); + sp1_PrintAtInv(0, 21, INK_RED | PAPER_BLACK, 'I'); + sp1_PrintAtInv(0, 22, INK_RED | PAPER_BLACK, 'N'); + sp1_PrintAtInv(0, 23, INK_RED | PAPER_BLACK, 'T'); + sp1_PrintAtInv(0, 24, INK_RED | PAPER_BLACK, 'S'); + sp1_PrintAt(0, 2, INK_RED | PAPER_BLACK, 'L'); sp1_PrintAt(0, 3, INK_RED | PAPER_BLACK, 'I'); sp1_PrintAt(0, 4, INK_RED | PAPER_BLACK, 'V'); @@ -157,6 +164,7 @@ int main() if(frame == 5) { frame = 0; + print_points(); } wait(); diff --git a/zproject.lst b/zproject.lst index 76f0742..83dc8ad 100644 --- a/zproject.lst +++ b/zproject.lst @@ -4,5 +4,6 @@ game_zx.c logic.c sprites.c globals.c -alley.c int.c +msnampac.c +asm_strlen