LIBRARY 999 "PACMAN for HP48, by C.de DINECHIN" COMMANDS PAC AboutPAC ScoresPAC ResetPAC LOCAL AboutCode PacCode PacScreen PacSprites Table1 Table2 Table3 TableList CONFIG PROG :0:999 ATTACH CLLCD TEXT "PacMan for HP48 V2.0" 1 DISP "PacMan V2.0 autoboot OK. To launch PacMan, use LIBRARY menu. Press any key...." AboutCode DROP END MESSAGES [ "Unexpected screen addr" ] CONTENT @ ************************************************************************ @ The main program is not so small... @ ************************************************************************ PAC PROG @ Display the welcome Screen -40 CF PacScreen PICT STO { #0h #0h } PVIEW @ Initialize all global variables 0 1 3 #3456h Table1 NEWOB -> Score Level Lives Speed PacTab << DO @ Wait for a Key 0 WAIT DROP @ Execute the machine code part of PacMan Speed PacSprites PacTab "GROB 144 241" STR-> PacCode @ Get the score and Test it 5 ROLLD DROP2 DROP2 -> S << @ Test if Pac Man was killed. Aoh IF S #80000h AND #0h <> THEN Lives 1 - 'Lives' STO ELSE @ Increment lives and level Lives 1 + 'Lives' STO Level 1 + 'Level' STO IF Level TableList SIZE > THEN 1 'Level' STO END @ Get Table information in TableList TableList Level GET LIST-> DROP 'Speed' STO EVAL NEWOB 'PacTab' STO END @ Test if game was interrupted by user IF S #40000h AND #0h <> THEN 0 'Lives' STO END @ Compute score S #3FFFFh AND B->R 10 * Score + 'Score' STO @ Display Score PICT { #14d #18d } #103d #29d BLANK REPL PICT { #16d #19d } "Score: " Score + 2 ->GROB { #1d #0d } OVER GOR GOR PICT { #16d #35d } "Lives: " Lives + 2 ->GROB { #1d #0d } OVER GOR GOR >> UNTIL Lives 0 <= END 0 WAIT DROP IF PacManScores TYPE 5 <> THEN ResetPAC END @ Test if our score is in High Scores Table 1 7 FOR I IF PacManScores I GET 2 GET Score <= THEN "Bravo, vous avez un bon score! Votre nom?" { "" EXTERNAL #4358Ah } INPUT Score 2 ->LIST 1 ->LIST PacManScores 1 I OVER - SUB SWAP + PacManScores I 7 SUB + 'PacManScores' STO 8 'I' STO END NEXT ScoresPAC >> END @ *********************************************************************** @ Scores and High Scores Table @ *********************************************************************** ResetPAC PROG { { "" 0 } } DUP + DUP + DUP + 'PacManScores' STO END ScoresPAC PROG IF PacManScores TYPE 5 <> THEN ResetPAC END ERASE PICT { #16d #0d } "Meilleurs Scores" 2 ->GROB { #1d #0d } OVER GOR REPL { #0d #0d } PVIEW 1 7 FOR I PICT { #0d } I 8 * R->B + PacManScores I GET 1 GET 2 ->GROB REPL PICT PacManScores I GET 2 GET 2 ->GROB #131d OVER SIZE DROP - I 8 * R->B 2 ->LIST SWAP REPL NEXT 0 WAIT DROP END AboutPAC PROG CLLCD "PacMan V2.0 for HP48, written in November 1991 by C. de DINECHIN... Keys are... Left: 4 Right: 6 Up: 8 Down: 2 Exit: Backspace This program is absolutely FREE: you may give it to anybody, using the HP48 infrared link for example. No one may sell it nor distribute it without express written permission of the author. Tetris is also available in the same format. I also have other projects, such as Defender, Space Invaders, Arkanoid, and if I can find the time, something more difficult. What about a 'Prince of Persia'-like game ?... All these games were compiled using the HP48 Developpement System. This product is also FREE. It is written in C and is as portable as possible. Versions for Atari ST, Amiga, IBM PC, Unix and soon Mac are available. If you want to know more, please contact me: Christophe de DINECHIN, 4 rue A. Romain, 69140 Rillieux la Pape, FRANCE. " AboutCode DROP END @ **************************************************************************** @ Table descriptions @ **************************************************************************** Table1 GROB 136 17 E41414141407163610D616E614141414F424202020202020202020202020202020 242420E41444203444203444203414F42024242024302020202020202020203024202424206420 E41413F420E43314F4206420240720202024202064206420202420202007162054202420202020 2020202420542016362064206420E444F134F420642064203610202020202024F180F124202020 202010D62054205420C4138423D42054205420D61620642024202020642020202420642016E620 2020242054202020542024202020E624205420C414744420347414D42054202424202430202020 202020202020302420242420C41444203414031444203414D42024242020202020202020202020 2020202024C41414141407163610D616E614141414D4 Table2 GROB 168 21 E41414772796474756E684269714465617572614F4242020202020202020202420 2020202020202020242420E41414201414F4202420E41444203414F42024242024202020202024 20242024202020202024202424206420E41444206420642064203414F420642024242020202430 202020202020202020302420202024242054206420E414144420341414F4206420542024242024 2020202420202020202020242020202420242420C4134420C444202020202034D4203413D42024 242020202020202020542054202020202020202024941323334420341414A48094141444203433 2313A4242020202020202020C484D42020202020202020242420E4144420E444202024202034F4 203414F42024242024202020242020202420202024202020242024242064205420C41444206420 3414D420542064202424202020243020202020202020202030242020202424205420C414442054 20542054203414D4205420242420242020202020242024202420202020202420242420C4144420 3414D4202420C41444203414D42024242020202020202020202420202020202020202024C41414 1414031466F627746657E6140314141414D4 Table3 GROB 168 21 E414141414141414141484141414141414141414F4242020202020202020202420 2020202020202020242420E44420202034F4202420E44420202034F42024242064202026202064 2024206420202620206420242420202020F6202020206420202020F6202020202424202026F6E6 5737202020202026F6E65737202024242020202057202020202020202020572020202024242054 2020372020202020202020203720205420242420C4442020202020302030202020202034D42024 2420202020202020E444F134F420202020202020249414231344203414A4F180F1941444203413 2314A42420202020202020C4148414D420202020202020242420E4442020202020302430202020 202034F420242420642020262020202024202020202620206420242420202020F6202020206420 202020F6202020202424202026F6E65737202020202026F6E65737202024242020202057202020 2054202020205720202020242420542020372020542024205420203720205420242420C4442020 2034D4202420C44420202034D42024242020202020202020202420202020202020202024C41414 1414031414141474141414140314141414D4 TableList { { Table1 #5678h } { Table2 #5678h } { Table3 #5678h } { Table1 #9ABCh } { Table2 #9ABCh } { Table3 #9ABCh } { Table1 #CDEFh } { Table2 #CDEFh } { Table3 #CDEFh } { Table1 #FDECh } { Table2 #FDECh } { Table3 #FDECh } } PacSprites GROB 8 1024 000000000000000000000000000000000000008181000000008142A5A542810000 40404242C7020000C340C30202C30000C34040C342C30000E7040683020200FF999918999999FF 00C74444C704C70000C74444C744440000E322E72424E70044AAEEEE4400000044EE66EE440000 00227777552200000044EECCEE44000000C3E7FFFFFFFFE7C3247EFFFFFFFFE7C3C3EFF7F3F3F7 EFC7C3E7FFFFFFFF7624E3F7EFCFCFEFF7E3C76D6DEFEFEFEFAAC7EFEAEAEFEFEFAAC7EFEF6D6D EFEFAAE3F75757F7F7F755C7AAAA2828286DAAC7282D2D28286DAAC72828AAAA286DAAC7286969 28286DAA00000181018300000000810201830000E7181818181818E700004041C3010000000083 8083028300000083808382830000008704040404000000C342C342C30000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 00FF00FFFF10FF0000FF00FFFF30FF0000FF00FFFF70FF0000FF00FFFFF0FF0000FF00FFFFF1FF 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000FF00FFFF00FF00A5A5A5A5A5A5A5A5008F40AF AF408F0000F102F5F502F100008142A5A5A5A5A5A5A5A5A5A5428100A5BD81FFFF00FF0000FF00 FFFF81BDA5A5ADA1AFAFA1ADA5A5B585F5F585B5A5A5BD81FFFF81BDA5A5ADA1AF2F408F00A5B5 85F5F402F100008F402FAFA1ADA500F102F4F585B5A50C3FF3C00C3FF3C0000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 00008080C1C1E3E37700F3F7F7F3F7F7F300C3E7F3F1F3E7C300F3F7F7F7F7F7F300E7F3F3F7F3 F3E700E7F3F3F7F3F3F300C3E7F3F1F5E7C7006377F7F7F777630081C3C3C3C3C38100878787B7 F7E3C10073F3F1F0F1F3730060F0F0F3F7F7E300143677F7F777770066F7F7F7F7F73300E3F7F7 77F7F7E300E3F777F7F3F06000E3F7F777F7F7EF04E3F777F7F3F76600E7F7F1E3C7F7F300E3F7 E3C1C1C1800022777777F7F7E3007763E3C1C18080003677F7F77736140077F7F7E3F7F7770077 77F7F7E3C1C100F7F7F3C1E7F7F700000000000000000000000000000000000000000000000000 00000000000000000000000000000000 PacScreen GROB 131 64 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 70BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA607555FFFFFFFFFFFFFFFFFFFFFFFFF55570BAAE0000 000030000000000810000BAAE975530E700078000000000074F313045570BAA10940084C000000 00084C4A9208AA6075D00523684A8568D894D82A2592005570BAA00C9210A94950B49420E3EA81 00BA6075D0044A00A42940925220112E520055F9BAA0024D2014A6205A431011184200BA607551 07CA1C0C652836C41C0B38C1085570BAA20000000000080000000000000CAA60755D0000000000 08000000000000075570BAAAFFFFFFFFFFFFFFFFFFFFFFFFFAAAE9755555555555555555555555 5555555570BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA607555555555555555555555555555555570 BAAAFFFFFFFFFFFFFFFFFFFFFFFFFAAA6075551000000000000000000000008555F9BAAA100087 0090008813200000008AAA607555100080008000C4A430000000855578BAAA10008025D12384A4 249920008AAAE9755510008753905584A42C2A10008555FCBAAA1000801190758837242B00008A AA6C7555100080119015802424AA0000855571BAAA10008051905584A42CAA00008AAA60755510 00872191258813241B0000855572BAAA1000000000000000040000008AAA687555100000000000 000004000000855570BAAA1000000000000000000000008AAA6075551C90804004008087A8E931 5195557CBAAA12A0004004008088A92441539AAA6475551289ACE4AC80A488A9240153955570BA AA128A924A6551DA88AAE50F559AAA607555128A844A25D19E88AA240155955570BAAA128A884A 25509288AC2401599AAA60755512AA8A4A6551DA88AC244159955570BAAA1C9A84C4A490A487A8 E931519AAA607555100000002000000000000000855570BAAA1000000020000000000000008AAA 607555FFFFFFFFFFFFFFFFFFFFFFFFF55570BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6075555555 55555555555555555555555570BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA60755555555555555555 55555555555555F9BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA607555555555555555555555555555 555570BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA607555555555555555555555555555555570BAAA FFFFFFFFFFFFFFFFFFFFFFFFFBAA60755D010000000000000000000040065570BAA30100000000 0000000010004008BAE27551017E4A86E1E25945C0339CC1305579BAA082925A898012D84B2194 925A40AA6075D08392525F40625849E194924A706570BAA044925351208A58692094D25A00AA60 7551447E822EE1745059C123AC42705570BAA300120020000000000000000008BA60755D001200 100000000000000000065570BAAAFFFFFFFFFFFFFFFFFFFFFFFFFBAA6075555555555555555555 55555555555570FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FF70 PacCode ASM ************************************************************************* * PAC-MAN pour HP 48 SX * ************************************************************************* INCLUDE "HARD.48S" ; Registres Hard de la 48 INCLUDE "ROM.48S" ; Adresses ROM INCLUDE "RRAM.48S" ; Adresses RRAM ************************************************************************* * Variables globales * ************************************************************************* RSRESET MONS_PosX RS 3 ; Position MONS_PosY RS 3 MONS_Dir RS 1 ; Direction MONS_Kind RS 1 ; Type de Monstre MONS_Status RS 3 ; Etat actuel du monstre MONS_Speed RS 2 ; Compteur de vitesse MONS_Size RS 0 RSSET $70C00 ; Ecran texte jusqu'ˆ 16 librairies. VARS_Start RS 0 ; DŽbut des variables pacman PAC_ToEat RS 5 ; Nombre de pastilles ˆ manger. PAC_PosX RS 3 ; Position X du personnage PAC_PosY RS 3 ; Position Y du personnage PAC_Dir RS 1 ; Direction du personnage: PAC_NextDir RS 1 ; Direction demandŽe par les touches PAC_Eating RS 3 ; Temps pendant lequel on mange les fant™mes PAC_Speed RS 2 ; Compteur de vitesse PacMan PAC_DirUp equ 1 ; Directions autorisees pour le personnage PAC_DirRight equ 2 PAC_DirDown equ 3 PAC_DirLeft equ 4 PAC_DirStand equ 0 BACK_GroundPtr RS 5 ; Pointeur vers description tableau BACK_Columns RS 2 ; Nombre de colonnes du tableau BACK_Width RS 3 ; Taille du tableau en pixels BACK_Height RS 3 BACK_PacPtr RS 5 ; Pointeur sur l'objet o est le Pacman SCRN_LogBase RS 5 ; Adresses des ecrans logique ... SCRN_PhyBase RS 5 ; ... et physique SCRN_BckBase RS 5 ; Adresse du fond de l'Žcran SCRN_PosX RS 3 ; Position X de l'ecran. UtilisŽ pour l'offset SCRN_PosY RS 3 ; Position Y de l'ecran. UtilisŽ pour l'offset SCRN_RoundX RS 3 ; PosX & ~7 SCRN_RoundY RS 3 ; PosY & ~7 SCRN_LastX RS 3 ; Dernire position X de l'Žcran SCRN_LastY RS 3 ; Dernire position Y de l'Žcran SPRT_SpritesPtr RS 5 ; Adresse des dessins de sprites PAC_Score RS 5 ; Score fait dans ce tableau * UTILISES PAR LA ROUTINE DE SUIVI BEST_Dir1 RS 1 ; Meilleure direction pour un monstre BEST_Dir2 RS 1 BEST_Dir3 RS 1 BEST_Dir4 RS 1 TAR_PosX RS 3 ; Cible TAR_PosY RS 3 MONS_Info RS 5 ; Pointeur sur la description du monstre * VITESSE DES MONSTRES FOLLOW_Speed RS 2 FUGIT_Speed RS 2 PINKY_Speed RS 2 * POSITION DE RETOUR DES FANTOMES HOME_PosX RS 6 ; Position de retour des fantomes mangŽs HOME_Dir RS 1 ; Dummy (if not: Bug in initialisation) * DonnŽes concernant les monstres MONS_Number RS 1 MONS_Counter RS 1 MONS_Data RS MONS_Size*16 VARS_End RS 0 ; Utilise pour savoir la longueur des variables ************************************************************************* * Programme principal * ************************************************************************* * Initialisation GOSUBL PAC_Init MAIN_Loop: * DŽplacement utilisateur GOSUBL PAC_Key ; Teste les touches D0= PAC_PosX GOSUBL SPEED_Test GONC .pac GOSUBL PAC_Move ; DŽplace le PACMAN * Affichages .pac GOSUBL PAC_ScreenPos ; Met l'Žcran en place GOSUBL SCRN_PutBackGround ; Affiche le fond GOSUBL PAC_Display ; Affiche le Pacman LC MONS_Data ; Initialise MONS_Info sur dŽbut liste D0= MONS_Info DAT0=C D0= MONS_Number C=DAT0(P) D0=D0+1 ; MONS_Counter DAT0=C(P) .monst D0= MONS_Info A=DAT0 D0=A ; D0 Pointe sur les infos de monstre GOSUBL SPEED_Test ; Teste si monstre bouge GONC .disp GOSUBL GHOST_Move ; DŽplace le fant™me .disp GOSUBL GHOST_Display ; Affiche le fant™me GOSUBL GHOST_Hit ; Teste ce que touche le fant™me D0= MONS_Info ; Fait pointer MONS_Info sur le suivant A=DAT0 AD0EX D0=D0+ MONS_Size AD0EX DAT0=A D0= MONS_Counter A=DAT0(P) A=A-1(P) DAT0(P)=A ?A<>0(P) GOYES .monst D0= PAC_Eating C=0 DAT0=C(X) GOSUBL SCRN_SwapScreen ; Permutation des Žcrans D0= PAC_ToEat A=DAT0 ?A=0 GOYES .End GOTO MAIN_Loop * Fin du programme .End D0=PAC_Score C=DAT0 RSTK=C GOSUBL PAC_Exit C=RSTK A=C P=4 GOVLNG $0596D ; Met A comme binaire dans la pile ************************************************************************* * Routines Graphiques de base * ************************************************************************* SCRN_PutBackGround: * --------------------------------------------------------------------- * * Affichage du fond de l'ecran * * --------------------------------------------------------------------- * * On teste si le pacman a changŽ de case * Si oui, on scrolle le fond comme nŽcŽssaire, et on affiche la ligne * ou la colonne manquante. * On copie ensuite le fond obtenu dans l'Žcran actuel. * Calcule les valeurs SCRN_RoundX et SCRN_RoundY LC(6) $FF8FF8 ; Masque des positions D0=SCRN_PosX P=5 A=DAT0(WP) A=A&C(WP) D0=D0+6 ; SCRN_RoundX DAT0=A(WP) P=0 * TEST DU DEPLACEMENT VERS LA GAUCHE .left D0= SCRN_LastX ; VŽrifie si les coordonnŽes X ont changŽ A=DAT0(X) D0= D0-6 ; SCRN_RoundX C=DAT0(X) ?C>=A(X) ; Si on est allŽ ˆ gauche GOYES .right ; non * On est allŽ ˆ gauche. LC(3) 8 ; Indique un changement des coordonnŽes A=A-C(X) D0=D0+6 ; SCRN_LastX DAT0=A(X) D0= SCRN_BckBase ; Scrolle le fond vers la droite A=DAT0 LC 36*72 ; Pointe sur la fin de l'Žcran A=A+C D0=A D1=A D0=D0-2 GOSBVL ROM_MoveUp ; Und ya scroll. D0= SCRN_LastX GOSUBL OBJECT_Under ; RŽcupre la position de colonne gauche D0= SCRN_BckBase ; A mettre en colonne gauche C=DAT0 GOSUB SCRN_FillColumn ; et remplit une colonne. GOTO .left ; Recommence (si plusieur colonnes...) * TEST DU DEPLACEMENT VERS LA DROITE .right D0= SCRN_LastX ; VŽrifie si les coordonnŽes X ont changŽ A=DAT0(X) D0= D0-6 ; SCRN_RoundX C=DAT0(X) ?C<=A(X) ; Si on est allŽ ˆ droite GOYES .up ; non * On est allŽ ˆ droite. LC(3) 8 ; Indique un changement des coordonnŽes A=A+C(X) D0=D0+6 ; SCRN_LastX DAT0=A(X) D0= SCRN_BckBase ; Scrolle le fond vers la gauche A=DAT0 D0=A D1=A D0=D0+2 LC 36*72 ; Taille ˆ scroller GOSBVL ROM_MoveDn D0= SCRN_LastX GOSUBL OBJECT_Under ; RŽcupre la position de colonne droite LC 34 ; Pointe sur la colonne de droite D=C A=A+C D0= SCRN_BckBase ; A mettre en colonne droite C=DAT0 C=C+D GOSUB SCRN_FillColumn ; et remplit une colonne. GOTO .right ; Recommence. * TEST DU DEPLACEMENT VERS LE HAUT .up D0= SCRN_LastY ; VŽrifie si les coordonnŽes X ont changŽ A=DAT0(X) D0= D0-6 ; SCRN_RoundY C=DAT0(X) ?C>=A(X) ; Si on est allŽ en haut GOYES .down ; non * On est allŽ vers le haut LC(3) 8 ; Indique un changement des coordonnŽes A=A-C(X) D0=D0+6 ; SCRN_LastY DAT0=A(X) D0= SCRN_BckBase ; Scrolle le fond vers le bas A=DAT0 LC 36*64 ; Pointe sur la fin de l'Žcran A=A+C D0=A D=C LC 36*8 A=A+C D1=A C=D ; RŽcupre la longueur ˆ scroller GOSBVL ROM_MoveUp ; Und ya scroll. D0= SCRN_LastX GOSUBL OBJECT_Under ; RŽcupre la position de colonne gauche D0= SCRN_BckBase ; A mettre en premire ligne C=DAT0 GOSUB SCRN_FillLine ; et remplit une ligne GOTO .up ; Recommence (si plusieur lignes...) * TEST DU DEPLACEMENT VERS LE BAS .down D0= SCRN_LastY ; VŽrifie si les coordonnŽes X ont changŽ A=DAT0(X) D0= D0-6 ; SCRN_RoundY C=DAT0(X) ?C<=A(X) ; Si on est allŽ ˆ droite GOYES .copy ; non * On est allŽ vers le bas LC(3) 8 ; Indique un changement des coordonnŽes A=A+C(X) D0=D0+6 ; SCRN_LastY DAT0=A(X) D0= SCRN_BckBase ; Scrolle le fond vers le haut A=DAT0 D1=A LC 8*36 A=A+C D0=A LC 36*64 GOSBVL ROM_MoveDn D0= SCRN_LastY A=0 A=DAT0(X) LC(3) 64 A=A+C(X) GOSUBL OBJECT_Under_GiveY ; Position Line D0= SCRN_BckBase ; A mettre en colonne droite C=DAT0 D=C LC 64*36 ; Pointe sur le bas Žcran C=C+D GOSUB SCRN_FillLine ; et remplit une ligne GOTO .down ; Recommence. * FIN: Copie dans l'Žcran courant .copy D0= SCRN_LogBase A=DAT0 D0=D0+ SCRN_BckBase-SCRN_LogBase C=DAT0 D1=A D0=C LC 36*72 GOVLNG ROM_MoveDn SCRN_FillLine: * --------------------------------------------------------------------- * * Remplit une ligne du fond de l'Žcran * * --------------------------------------------------------------------- * * EntrŽe: * A= Pointeur sur les donnŽes du tableau * C= Pointeur sur l'Žcran R0=A R1=C LC 0- 36*8 + 2 R3=C ; Offset ˆ ajouter pour passer char suivant LC(2) 18 ; Nombre de colonnes ˆ remplir B=C(B) LC 2 ; Offset ŽlŽment suivant D=C GOTO SCRN_FillPatterns SCRN_FillColumn: * --------------------------------------------------------------------- * * Remplit une colonne du fond d'Žcran * * --------------------------------------------------------------------- * * EntrŽe: * A= Pointeur sur les donnŽes du tableau * C= Pointeur sur l'Žcran R0=A R1=C C=0 R3=C ; Offset ˆ ajouter pour passer char suivant LC(2) 9 ; Nombre de lignes ˆ remplir B=C(B) D0= BACK_Columns C=0 C=DAT0(B) C=C+C D=C SCRN_FillPatterns: * --------------------------------------------------------------------- * * Remplit une sŽrie de patterns * * --------------------------------------------------------------------- * * Registres: * R0= DonnŽes du tableau * R1= DonnŽes Žcran * R2= Sprites * R3= Offset / Ligne suivante * B = Nombre de patterns ˆ copier. * D = Offset / Tabelem suivant D0= SPRT_SpritesPtr A=DAT0 R2=A ; Pointeur sur les sprites .PatternLoop: A=R0 D0=A ; D0=pointeur donnees C=0 C=DAT0(B) ; C=Objet CD0EX C=C+D R0=C ; Stockage du nouveau pointeur objet CD0EX CSL ; Offset pour pointer sur le bon sprite A=R2 A=A+C D0=A ; D0 pointe sur la definition du sprite A=R1 D1=A ; D1 pointe sur l'ecran A=DAT0(W) P=15 LC(1) 8 ; C(S)=Compteur lignes P=0 LC 36 .ScreenCopy: DAT1(B)=A ASRC ASRC AD1EX A=A+C AD1EX C=C-1(S) ?C<>0(S) GOYES .ScreenCopy C=R3 ; Pointe sur la position ecran suivante AD1EX A=A+C R1=A B=B-1(B) ; Boucle sur les colonnes ?B<>0(B) GOYES .PatternLoop RTN SCRN_SwapScreen: * --------------------------------------------------------------------- * * Permutation des ecrans * * --------------------------------------------------------------------- * * La routine echange les variables SCRN_LogBase et SCRN_PhyBase. * Elle tient compte pour ecrire le pointeur ecran et les offsets des * variables de position SCRN_PosX et SCRN_PosY A=0 D0=SCRN_PosY ; Calcul de l'offset ecran A=DAT0(1) ; Lecture de la partie basse LC(2) 7 A=A&C(B) C=A ASL ; * 16 C=C+C A=A+C ; * 18 A=A+A ; * 36 B=A ; Mis en reserve D0=SCRN_LogBase ; Pointeur ecran logique A=DAT0 D0=D0+5 ; D0=SCRN_PhyBase C=DAT0 DAT0=A ; Permutation des ecrans D0=D0-5 DAT0=C D0=HARD_ScreenBase ; Pointeur physique ecran A=A+B ; Plus decalage vertical DAT0=A ; Stockage du pointeur ecran D0=SCRN_PosX ; Offset horizontal A=DAT0(1) LC(2) 7 A=A&C(B) ?ABIT(2)=0 GOYES .SmallPosX ; Quand le decalage ecran est > 4 LC(1) $C A=A|C ; Grand decalage Hard D0=HARD_ScreenShift ; Decalage hard D1=HARD_ScreenWidth C=0 DAT0=A(1) DAT1=C(3) ; Largeur = 0 RTN ; Quand le decalage ecran est < 4 .SmallPosX: LC(1) 3 A=A&C(B) LC(1) $8 A=A|C D0=HARD_ScreenShift D1=HARD_ScreenWidth LC(3) $002 DAT1=C(3) ; Largeur=2 DAT0=A(1) RTN GHOST_Display: * --------------------------------------------------------------------- * * Affichage d'un des fantomes * * --------------------------------------------------------------------- * * EntrŽe: * MONS_Info pointe sur les informations de description de sprite D0= MONS_Info A=DAT0 D0=A LC 20 ; NumŽro de sprite D=C D0=D0+ MONS_Dir C=DAT0(1) D=D+C(P) D0=D0+ MONS_Status-MONS_Dir C=DAT0(X) ?C=0(X) GOYES .std ; Si zŽro: fant™me standard C=C+1(X) ; Si -1, Yeux ?C=0(X) GOYES .eyes A=C(X) LC(3) 100 ACEX ?C>A(X) ; Teste si reste seulement 100 pour manger GOYES .noblnk ?CBIT(3)=0 ; Si oui, clignote GOYES .std .noblnk LC(1) 4 ; Sinon, fant™me blanc D=D+C(P) GOTO .std .eyes LC(2) 21-12 ; Fant™me "Yeux" D=D-C(B) .std A=0 ; Lecture des coordonnŽes dans A-B D0=D0- MONS_Status-MONS_PosY A=DAT0(X) B=A D0=D0- MONS_PosY-MONS_PosX A=DAT0(X) GOTO SPRT_Display PAC_Display: * --------------------------------------------------------------------- * * Affichage du personnage "Pacman" * * --------------------------------------------------------------------- * D0= PAC_Dir C=0 C=DAT0(1) D=C LC(2) 16 D=D+C(B) A=0 D0=PAC_PosY A=DAT0(X) B=A D0=D0-3 A=DAT0(X) C=A C=C|B ?CBIT(2)=0 GOYES SPRT_Display LC(3) 16 D=C SPRT_Display: * --------------------------------------------------------------------- * * Affichage d'un sprite * * --------------------------------------------------------------------- * * Entree= * A=Coordonnee X * B=Coordonnee Y * D=Numero du sprite C=D ; Sauvegarde numŽro de sprite R0=C LC ~7 ; Charge le masque de dŽcalages Žcrans D=C D0=SCRN_PosX ; Calcule le decalage par rapport a l'ecran C=0 C=DAT0(X) ; Position X de l'ecran C=C&D A=A-C D0=D0+3 C=DAT0(X) ; Position =Y de l'ecran C=C&D B=B-C C=R0 ; RŽcupre numŽro de sprite D=C C=0 LC(1) 8 ; Decalage pour les tests de clipping A=A+C B=B+C LC(2) 131+15 ; Si coordonnees hors ecran ?A>=C RTNYES ; on ne trace rien LC(2) 64+15 ?B>=C RTNYES R0=A ; Reserve la position X C=B ; Calcule l'addresse de debut de ligne Y*36+X/4 BSL ; Y * 16 C=C+C B=B+C ; * 18 B=B+B ; * 36 A=A/2 A=A/2 ; / 4 B=B+A D0=SCRN_LogBase A=DAT0 LC 8*36+2 ; Enleve le clipping en haut et a gauche A=A-C A=A+B ; Ajoute l'offset ecran D0=A ; D0=Addresse ecran DSL ; Numero de sprite => Offset de sprite D1=SPRT_SpritesPtr A=DAT1 C=D A=A+C D1=A ; D1=definition du sprite A=R0 LC(1) 3 A=A&C(P) B=A(P) ; B=Compteur de decalages droit P=15 LC(1) 8 ; D(S)=Nombre de lignes D=C(S) P=0 LC 36 ; D(A)=Offset ligne D=C .SpriteLine: A=0(X) A=DAT1(B) C=B(P) .SpriteShift: ; Decalage du motif vers la droite ?C=0(P) GOYES .SpriteShifted A=A+A(X) C=C-1(P) GOTO .SpriteShift .SpriteShifted: C=DAT0(X) ; Surimpression sur l'ecran A=A|C(X) DAT0=A(X) CD0EX ; DŽcalage des pointeurs C=C+D CD0EX D1=D1+2 D=D-1(S) ?D<>0(S) GOYES .SpriteLine RTN ************************************************************************* * Routines Specifiques a PAC * ************************************************************************* PAC_Key: * --------------------------------------------------------------------- * * Deplacement du personnage * * --------------------------------------------------------------------- * LC(4) 16 ; Teste la touche BACK pour quitter OUT=CS GOSBVL ROM_InputA ?ABIT(0)=0 GOYES .Cont D0= PAC_ToEat ; Indique "Plus de pastilles ˆ manger". A=0 DAT0=A D0= PAC_Score ; Indique "QuittŽ ˆ la main" LC $40000 A=DAT0 A=A|C DAT0=A RTNSC .Cont LC(1) 4 OUT=CS GOSBVL ROM_InputA D0= PAC_NextDir C=DAT0(P) ?ABIT(1)=0 ; Teste la touche de droite GOYES .KeyRt LC(1) PAC_DirRight .KeyRt ?ABIT(3)=0 ; Teste la touche de gauche GOYES .KeyLf LC(1) PAC_DirLeft .KeyLf R0=C ; Sauvegarde la touche pressŽe LC(1) 2 OUT=CS GOSBVL ROM_InputA ; Teste la touche du bas C=R0 ?ABIT(2)=0 GOYES .KeyDn LC(1) PAC_DirDown .KeyDn R0=C LC(1) 8 OUT=CS GOSBVL ROM_InputA ; Teste la touche du haut C=R0 ?ABIT(2)=0 GOYES .KeyUp LC(1) PAC_DirUp .KeyUp D0= PAC_NextDir DAT0(1)=C C=0 OUT=CS RTNCC PAC_ScreenPos: * --------------------------------------------------------------------- * * Positionnement de l'Žcran * * --------------------------------------------------------------------- * A=0 D0= BACK_Width ; Lecture de la largeur d'Žcran A=DAT0(X) LC(3) 131 A=A-C(X) B=A(X) D0= BACK_Height A=DAT0(X) LC(3) 64 A=A-C(X) C=A(X) D=C(X) D0= PAC_PosX ; Stockage des offsets Žcran D1= SCRN_PosX A=0 A=DAT0(X) LC(3) 64 ?A>C(X) GOYES .KeepX1 A=C(X) .KeepX1 A=A-C(X) ?A<=B(X) GOYES .KeepX2 A=B(X) .KeepX2 DAT1(X)=A B=A ; Offset BACK en quartets B=B/2(A) B=B/2(A) B=B/2(A) D1=D1+3 ; Idem pour offset Y D0=D0+3 A=DAT0(X) LC(3) 28 ?A>C(X) GOYES .KeepY1 A=C(X) .KeepY1 A=A-C(X) C=A ?C<=D(X) GOYES .KeepY2 C=D(X) A=C(X) .KeepY2 DAT1(X)=C RTNCC PAC_Move: * --------------------------------------------------------------------- * * Gestion des dŽplacements du personnage * * --------------------------------------------------------------------- * D0= PAC_PosX ; Teste si changement de direction autorisŽ A=DAT0(P) D0=D0+3 C=DAT0(P) A=A|C(P) LC(1) 7 C=C&A(P) ?C(P)=0 GOYES .Bound GOTO .Cont * PACMAN POSITIONNE SUR UNE CASE * Calcule la position "sous" le pacman. .Bound D0= PAC_PosX GOSUB OBJECT_Under D0= BACK_PacPtr DAT0=A * Avale les pastilles le cas ŽchŽant GOSUB PAC_Eat * Recherche de la direction D0= PAC_NextDir ; Copie de la direction si possible C=DAT0(1) R0=C D=C(P) GOSUB PAC_DirOk LC(2) 30 C=C-A(B) GOC .NoNext C=R0 D0=PAC_Dir ; Direction OK: on copie DAT0=C(P) GOTO .Cont .NoNext D0= PAC_Dir C=DAT0(1) D=C(P) GOSUB PAC_DirOk LC(2) 30 C=C-A(B) GONC .Cont D0= PAC_Dir C=0 DAT0(1)=C .Cont D0=PAC_Dir ; DŽplacement proprement dit C=DAT0(P) D=C(P) D0=PAC_PosX ; Lecture des coordonnŽes OBJECT_Move: * --------------------------------------------------------------------- * * DŽplacement d'un objet quelconque * * --------------------------------------------------------------------- * * D: Direction * D0: Pointeur sur les coordonnŽe: * PosX[3] PosY[3] Dir[1] D1= BACK_Width ; CoordonnŽes limites du terrain A=DAT0(X) ; Effectue le dŽplacement D0=D0+3 C=DAT0(X) D=D-1(P) ; Teste les quatre directions avec dŽplacement ?D(P)<>0 GOYES .Up C=C-1(X) .Up D=D-1(P) ?D(P)<>0 GOYES .Right A=A+1(X) .Right D=D-1(P) ?D(P)<>0 GOYES .Down C=C+1(X) .Down D=D-1(P) ?D(P)<>0 GOYES .Left A=A-1(X) .Left DAT0(X)=C ; Stocke les nouvelles coordonnŽes D0=D0-3 D1= BACK_Width ; Teste les dŽpassements hors jeu C=DAT1(X) C=C-9(X) ?A0(X) GOYES .ok_lf A=C(X) .ok_lf DAT0(X)=A D0=D0+3 D1=D1+3 A=DAT0(X) C=DAT1(X) C=C-9(X) ?A0(X) GOYES .ok_up A=C(X) .ok_up DAT0(X)=A RTN PAC_DirOk: * --------------------------------------------------------------------- * * Teste si la case pointŽe par la direction D est vide * * --------------------------------------------------------------------- * D0= BACK_PacPtr A=DAT0 OBJECT_DirOk: * --------------------------------------------------------------------- * * Teste si la case pointŽe par la direction D est vide * * --------------------------------------------------------------------- * * EntrŽe: * R4 pointe sur ce qui est sous l'objet * D0 pointe sur la direction ˆ tester * Sortie: * Carry set si contact dans la direction indiquŽe. D0= BACK_Columns C=0 C=DAT0(B) B=C B=B+B D=D-1(P) D=D-1(P) ; Fait pointer A sur la bonne case. GONC .Up A=A-B .Up D=D-1(P) GONC .Right A=A+1 A=A+1 .Right D=D-1(P) GONC .Down A=A+B .Down D=D-1(P) GONC .Left A=A-1 A=A-1 .Left D0=A A=DAT0(B) LC(2) 32 C=C-A(B) RTN ; Retourne C si valeur pointŽe sup ˆ 32 PAC_Eat: * --------------------------------------------------------------------- * * Mange les pastilles le cas ŽchŽant * * --------------------------------------------------------------------- * D0= BACK_PacPtr A=DAT0 D0=A A=DAT0(B) LC(2) 4 ; Limite des pastilles que l'on mange ?A>=C(B) GOYES .eaten LC(2) 2 A=A-C(B) ; Mange la pastille. GOC .eaten ; Si dŽjˆ mangŽe DAT0(B)=A ; Sinon, stocke .eaten ?A<>0(B) ; Teste si on fait du score GOYES .Score D1= PAC_Score C=DAT1 C=C+1 DAT1=C D1= PAC_ToEat ; Nombre de pastilles ˆ manger C=DAT1 C=C-1 DAT1=C .Score D0= PAC_Eating A=A-1(B) ; Teste si une pastille spŽciale ?A<>0(B) GOYES .NoMiam LC 400 ; Si pastille spŽciale, compteur "Miam" DAT0(X)=C D1= PAC_Score A=DAT1 A=A+C DAT1=A D1= PAC_ToEat C=DAT1 C=C-1 DAT1=C .NoMiam C=DAT0(X) ; DŽcrŽmente le compteur "Miam" si nŽcŽssaire C=C-1(X) GOC .Danger DAT0(X)=C * RŽaffiche le fond. .Danger D0= PAC_PosY A=0 A=DAT0(X) B=A(X) D0=D0-3 A=DAT0(X) D0= BACK_PacPtr C=DAT0 D0=C C=DAT0(B) D=0 D=C(B) SPRT_BackUpdate: * --------------------------------------------------------------------- * * Affiche un ŽlŽment dans le fond * * --------------------------------------------------------------------- * * A= CoordonnŽe X (Arrondie au multiple de 8) * B= CoordonnŽe Y (Arrondie au multiple de 8) * D= NumŽro de sprite. C=D ; Sauvegarde numŽro de sprite R0=C LC ~7 ; Charge le masque de dŽcalages Žcrans A=A&C(X) B=B&C(X) D=C D0=SCRN_PosX ; Calcule le decalage par rapport a l'ecran C=0 C=DAT0(X) ; Position X de l'ecran C=C&D A=A-C D0=D0+3 C=DAT0(X) ; Position =Y de l'ecran C=C&D B=B-C C=R0 ; RŽcupre numŽro de sprite D=C C=0 LC(2) 131+8 ; Si coordonnees hors ecran ?A>=C RTNYES ; on ne trace rien LC(2) 64+8 ?B>=C RTNYES R0=A ; Reserve la position X C=B ; Calcule l'addresse de debut de ligne Y*36+X/4 BSL ; Y * 16 C=C+C B=B+C ; * 18 B=B+B ; * 36 A=A/2 A=A/2 ; / 4 B=B+A D0=SCRN_BckBase A=DAT0 A=A+B ; Ajoute l'offset ecran D0=A ; D0=Addresse ecran DSL ; Numero de sprite => Offset de sprite D1=SPRT_SpritesPtr A=DAT1 C=D A=A+C D1=A ; D1=definition du sprite LC 36 ; Offset ligne B=C LC(1) 8 ; C=Compteur de lignes D=C(P) .SpriteLine: A=DAT1(B) DAT0=A(B) AD0EX A=A+B AD0EX D1=D1+2 D=D-1(P) ?D<>0(P) GOYES .SpriteLine RTN ************************************************************************* * DŽplacement des monstres * ************************************************************************* OBJECT_Under: * --------------------------------------------------------------------- * * Rend un pointeur sur ce qui est sous un objet * * --------------------------------------------------------------------- * * EntrŽe: * D0 pointe sur les coordonnŽes de l'objet (2x3) * Sortie: * A pointe sur l'octet sur lequel est l'objet D0=D0+3 ; Pointe sur Y A=0 A=DAT0(X) .GiveY A=A/2(A) A=A/2(A) D1= BACK_Columns ; Largeur du tableau C=0 C=DAT1(B) GOSBVL ROM_B_is_AxC D0=D0-3 A=0 A=DAT0(X) A=A/2(A) A=A/2(A) B=B+A D1= BACK_GroundPtr A=DAT1 A=A+B RTN DIR_Choose: * --------------------------------------------------------------------- * * Choix de direction pour atteindre une cible * * --------------------------------------------------------------------- * * EntrŽe: * MONS_Info pointe sur MONS_PosX, MONS_PosY, MONS_Dir * TAR_PosX, TAR_PosY : Cible ˆ atteindre * Sortie: * BEST_Dir1: Meilleure direction possible * BEST_Dir2: Seconde meilleure direction. * BEST_Dir3: Troisime meilleure direction * BEST_Dir4: Plus mauvaise direction D0= MONS_Info ; Lecture de la direction A=DAT0 D0=A D0=D0+6 ; Pointe sur la direction C=DAT0(P) D=C(P) ?CBIT(0)=1 ; Teste si direction est horizontale GOYES .vert GOTO .horiz * CAS OU LA DIRECTION ACTUELLE EST VERTICALE .vert D0=D0-6 A=DAT0(X) ; A=MONS_PosX D1= TAR_PosX C=DAT1(X) ; C=TAR_PosX ?A=C(X) ; Cas particulier pour l'ŽgalitŽ. GOYES .equal B=C(X) C=D(P) ; RŽcupre la direction D1= BEST_Dir2 ; La seconde meilleure direction est l'actuelle DAT1(P)=C LC(1) PAC_DirRight ?A0(P) GOYES .no1 LC $04321 .no1 A=A-1(P) ?A<>0(P) GOYES .no2 LC $04123 .no2 A=A-1(P) ?A<>0(P) GOYES .no3 LC $04231 .no3 D1=D1+ MONS_Status-MONS_Kind ; VŽrifie si peut tre mangŽ A=DAT1(X) ?A=0(X) GOYES .nosup A=A+1(X) ?A=0(X) GOYES .eyes LC $4123 ; Si poursuivi, s'enfuit... GOTO .nosup .eyes D1= HOME_PosX ; Si les yeux, utilise la maison comme cible P=5 A=DAT1(WP) D1= TAR_PosX DAT1(WP)=A P=0 LC $04321 ; Et devient "poursuivant" .nosup: MONS_Move: * --------------------------------------------------------------------- * * DŽplacement pour un fant™me * * --------------------------------------------------------------------- * * Deplacement direct (sans tenir compte du pacman) * D0 pointe sur MONS_PosX, MONS_PosY, MONS_Dir (stockŽ dans MONS_Info) * TAR_PosX, TAR_PosY indiquent le point ˆ atteindre. * C indique le type de suivi demandŽ (ordre de test des directions) R3=C ; RŽcupre l'ordre de test. AD0EX ; Stocke MONS_Info D0= MONS_Info ; Pointeur sur les infos de monstre DAT0=A D0=A A=DAT0(P) D0=D0+3 C=DAT0(P) A=A|C(P) LC(1) 7 C=C&A(P) ?C=0(P) GOYES .case D0=D0+3 ; pointe sur la direction GOTO .suite * Ici, on est sur une case "vraie". Teste le dŽplacement .case D0= MONS_Info A= DAT0 D0=A GOSUB OBJECT_Under R4=A GOSUB DIR_Choose ; Initialise les directions ˆ prendre. .loop C=R3 ?C=0(P) GOYES .closed ; Fant™me bloquŽ B=0 B=C(P) CSR ; Lit la direction suivante R3=C LC BEST_Dir1-1 ; Teste la direction stockŽe dans R3 C=C+B ; C pointe sur la direction ˆ tester D0=C C=DAT0(P) D=C(P) A=R4 GOSUB OBJECT_DirOk ; Teste si la direction est bonne GOC .loop ; Si oui, la choisit .choose LC(1) 5 C=C+D(P) .closed D0= MONS_Info ; Stocke l'information A=DAT0 D0=A D0=D0+6 DAT0(P)=C * DEPLACEMENT DU SPRITE .suite C=DAT0(P) D=C(P) D0=D0-6 GOLONG OBJECT_Move ************************************************************************* * Test de la vitesse * ************************************************************************* SPEED_Test: AD0EX D1=A AD0EX D1=D1+ MONS_Speed A=DAT1(P) ; Lit la vitesse A=A+1(P) ; Si vitesse = 15, dŽplacement automatique RTNC D1=D1+1 C=DAT1(P) C=C+A(P) ; Fait un dŽbordement de capacitŽ. DAT1(P)=C RTN ************************************************************************* * Teste le comportement du fant™me (attaque, fuite,... * ************************************************************************* GHOST_Hit: D0= MONS_Info A=DAT0 D0=A D0=D0+ MONS_Status D1= PAC_Eating A=DAT1(X) ?A=0(X) GOYES .no_pac C=DAT0(X) ; Teste si le monstre est en Žtat "Yeux" C=C+1(X) GOC .no_pac ; Si oui: ne change pas son Žtat DAT0=A(X) ; Indique que le monstre peut se faire manger D0=D0-2 ; Direction du monstre A=DAT0(P) ; Le monstre prend la direction opposŽe A=A+1(P) LC(1) 3 A=A&C(P) A=A+1(P) DAT0=A(P) D0=D0+2 .no_pac A=DAT0(X) ?A=0(X) GOYES .attq A=A+1(X) ?A<>0(X) GOYES .noeyes GOTO .eyes .noeyes A=A-1(X) ; Si poursuivi, dŽcrŽmente compteur A=A-1(X) DAT0(X)=A .attq D0=D0- MONS_Status D1= PAC_PosX A=DAT0(X) ; Teste si coordonnŽe X OK C=DAT1(X) A=A-C(X) LC(3) 4 A=A+C(X) LC(2) 8 A=A-C(X) RTNNC ; Si pas touchŽ, exit D0=D0+ MONS_PosY ; Teste coordonnŽe Y D1=D1+ MONS_PosY A=DAT0(X) C=DAT1(X) A=A-C(X) LC(3) 4 A=A+C(X) LC(2) 8 A=A-C(X) RTNNC D0=D0+ MONS_Status-MONS_PosY ; teste si mangŽ ou non C=DAT0(X) ?C=0(X) GOYES .dead LC(3) $FFF ; Si mangŽ, indique "EYES" DAT0(X)=C D1= PAC_Score ; et ajoute 100 au score A=DAT1 LC 100 A=A+C DAT1=A RTN .dead D0= PAC_ToEat ; Indique "Fin de partie" C=0 DAT0=C D0= PAC_Score ; Indique "MangŽ par un fant™me" A=DAT0 LC $80000 A=A|C DAT0=A RTN .eyes D0=D0- MONS_Status ; Pointe sur coordonnŽe P=5 A=DAT0(WP) D1= HOME_PosX C=DAT1(WP) ?A=C(WP) ; Si de retour ˆ la maison GOYES .home P=0 RTN .home P=0 D0=D0+ MONS_Status C=0(X) DAT0=C(X) RTN FATAL_ERROR C=RSTK ; Si impossible de jouer... GOSBVL ROM_LoadRegs LC $3E701 A=C GOVLNG ROM_Error ; Affiche l'erreur PAC_Init: ************************************************************************* * Initialisation du Jeu * ************************************************************************* GOSBVL ROM_SaveRegs ; Sauvegarde les registres D0=RRAM_GROBStack ; Teste si l'Žcran peut accueillir A=DAT0 ; les variables du programme LC VARS_Start ?CA(A) GOYES FATAL_ERROR * COUPURE DES INTERRUPTIONS CLAVIER ST(15)=0 * INITIALISATION DE L'ECRAN * Trois Žcrans de 64 lignes, sŽparŽs par 8 lignes (clipping), avec 8 lignes * au dessus et 8 lignes au dessous. Largeur = 36 quartets. * StockŽs dans un GROB au premier niveau de la pile LC(3) 63 D0= HARD_ScreenHeight ; Passe en "Full Screen" DAT0=C(X) A=DAT1 ; Lit le GROB dans la pile LC 8*36+20+2 ; Pointe sur le dŽbut de l'Žcran 1 A=A+C ABIT(0)=0 ; S'assure que dŽbute sur octet D0= SCRN_LogBase ; Initialise Logbase DAT0=A D0=D0+5 LC 80*36 ; Pointe sur le deuxime Žcran. A=A+C DAT0=A ; Initialise PhyBase D0=D0+5 A=A+C ; Pointe sur l'Žcran de fond DAT0=A * INITIALISATION DU FOND D1=D1+5 ; Ancien niveau 1: Description du fond A=DAT1 LC 20 ; RŽcupŽration d'un objet graphique A=A+C D0=BACK_GroundPtr DAT0=A ; BACK_GroundPtr AD0EX D0=D0-5 ; Largeur du graphique C=DAT0 D0=D0-5 A=DAT0 ; Hauteur du graphique A=A+A A=A+A A=A+A D0=BACK_Height DAT0(X)=A D0=D0- BACK_Height-BACK_Width DAT0(X)=C C=C/2 C=C/2 C=C/2 D0=D0- BACK_Width-BACK_Columns DAT0(B)=C * INITIALISATION DE LA LISTE DES SPRITES D1=D1+5 ; Niveau 2: Liste des sprites A=DAT1 LC 20 A=A+C D0= SPRT_SpritesPtr DAT0=A ; SPRT_SritesPtr * INITIALISATION DES VITESSES D1=D1+5 A=DAT1 D0=A D0=D0+10 A=DAT0 D0= PAC_Speed DAT0=A(P) ASR D0= FOLLOW_Speed ; D0= FOLLOW_Speed DAT0=A(P) ASR D0=D0+2 ; D0= FUGIT_Speed DAT0=A(P) ASR D0=D0+2 ; D0= PINKY_Speed DAT0=A(P) * INITIALISATION PACMAN D0= PAC_Eating ; Le pacman ne mange rien C=0 DAT0=C(X) D0= PAC_Score DAT0=C ; Score = 0 D0= PAC_Dir ; Direction = "Standing" DAT0=C(B) * INITIALISATION DU TABLEAU D0= MONS_Info LC MONS_Data DAT0=C C=0(P) D0= MONS_Number DAT0=C(P) D0= BACK_GroundPtr ; Pointeur vers le tableau A=DAT0 D0=A A=0 ; Nombre de pastilles ˆ manger InitialisŽ ˆ 0 R0=A R1=A ; CoordonnŽe X R2=A ; CoordonnŽe Y D1= BACK_Height ; Nombre de lignes dans D(X) C=DAT1(X) C=C/2(X) C=C/2(X) C=C/2(X) D=C(X) .line D1= BACK_Columns ; A=DAT1(B) ; Nombre de colonnes dans B(B) B=A(B) .column A=DAT0(B) ; Lecture du tableau et comptage de ce qui LC(2) 2 ; reste ˆ manger ?A=C(B) GOYES .nopast C=R0 ; Ajoute une pastille au dŽcompte C=C+1 R0=C .nopast LC(2) $08 ; Teste si position de "retour" D1= HOME_PosX ?A=C(B) GOYES .newpos LC(2) $30 ; Si "position de dŽpart PAC MAN", stocke D1= PAC_PosX ; Initialisation position de dŽpart ?A<>C(B) GOYES .nopac .newpos C=R1 DAT1=C(X) D1=D1+3 ; MONS_PosX C=R2 DAT1=C(X) D1=D1+3 LC(1) 1 ; MONS_Dir DAT1(P)=C .no_pos GOTO .next .nopac ?AC(B) GOYES .no_pos D1= MONS_Info C=DAT1 D1=C ; D1 Pointe sur le bon monstre D1=D1+ MONS_Kind A=A-1(P) DAT1=A(P) ; Type de monstre (0-2) D1=D1+ MONS_Status-MONS_Kind ; MONS_Stat = 0 C=0 DAT1=C(X) C=A(P) ; Type *2 pour pointer sur la vitesse C=C+C A=C LC FOLLOW_Speed A=A+C AD1EX ; D1= Vitesse de ce monstre C=DAT1(P) AD1EX D1=D1+ MONS_Speed-MONS_Status DAT1=C(P) ; StockŽe dans MONS_Speed D1=D1- MONS_Speed-MONS_PosX C=R1 DAT1=C(X) D1=D1+ MONS_PosY-MONS_PosX C=R2 DAT1=C(X) D1=D1+ MONS_Dir-MONS_PosY LC(1) 1 ; Direction DAT1(P)=C D1= MONS_Info ; Monstre suivant A=DAT1 LC MONS_Size A=A+C DAT1=A D1= MONS_Number ; IncrŽmente MONS_Number A=DAT1(P) A=A+1(P) DAT1=A(P) .next D0=D0+2 ; ElŽment suivant du tableau LC(2) 8 A=R1 A=A+C(B) R1=A B=B-1(B) ?B=0(B) GOYES .col GOTO .column .col A=0 R1=A A=R2 A=A+C(B) R2=A D=D-1(X) ?D=0(X) GOYES .lin GOTO .line .lin A=R0 D1=PAC_ToEat DAT1=A * INITIALISATIONS DES POSITIONS ECRAN * Pour que l'affichage soit bon, ces positions doivent provoquer un scrolling * la premire fois que le tableau est affichŽ D0= PAC_PosX D1= SCRN_LastX LC 128 A=DAT0(X) A=A+C(X) DAT1(X)=A D0=D0+3 ; PAC_PosY D1=D1+3 ; SCRN_LastY A=DAT0(X) A=A+C(X) DAT1(X)=A RTN PAC_Exit: ************************************************************************* * Fin du jeu * ************************************************************************* * GOSBVL ROM_LoadRegs * C=DAT1 ; RŽcupre la sauvegarde dans la pile * D0=C * * D0=D0+10 ; Copie D0=sauvegarde ... * D1= VARS_Start ; ... dans D1=Variables ... * LC VARS_End - VARS_Start ; ... longueur des variables. * * GOSBVL ROM_MoveDn * Restauration de l'Žcran D0= RRAM_ScreenBase A=DAT0 D0= HARD_ScreenBase DAT0=A D0= RRAM_ScreenMenuBase A=DAT0 D0= HARD_ScreenMenuBase DAT0=A D0= HARD_ScreenShift LC(1) 8 DAT0=C(1) D0= HARD_ScreenWidth C(X)=0 DAT0=C(X) * Restaure le contenu des registres sauvegardŽs GOSBVL ROM_LoadRegs * Restaure les interruptions et retourne ST(15)=1 RTN ; GOVLNG $10E5 ; Restaure les interruptions WAIT5: RSTK=C .1 LC(4) 4 OUT=CS GOSBVL ROM_InputC ?CBIT(2)=0 GOYES .1 .2 LC(4) 4 OUT=CS GOSBVL ROM_InputC ?CBIT(2)=1 GOYES .2 C=0 OUT=CS C=RSTK RTN END @ *********************************************************************** @ Code for the About Command and init @ *********************************************************************** AboutCode INCLUDE "ABOUT.48S" END