SOURCE : BREAKOUT.IVOS ." noPC Breakout Game Demo - Peter Jakacki " ; /* Demonstration program for noPC. Incomplete and mainly used for testing at present. The algorithm used is one of many tested and is by no means the most efficient but more of an experiment than anything else. The PS/2 keyboard's default auto-repeat rate is a little slow. Need to enable two-way coms to keyboard to set the repeat rate. */ : !AUDIO 3 PLAYR 6 VOL ; : MPLAY DUP LEN 7 - PLAY ; : BONK 6.402Eh MPLAY ; : TADA 6.002Eh MPLAY ; 40d CONSTANT YBRICK // Y offset of back-row of bricks 12d CONSTANT BRICK_XSZ 6d CONSTANT BRICK_YSZ 64 bytes bricks // byte array - 8-bits / brick : BRICKxy ( n -- ) DUP 0F AND BRICK_XSZ * SWAP 4 SHR BRICK_YSZ * YBRICK + BRICK_XSZ BRICK_YSZ ; : DRAW_BRICK ( on/off n -- ) VREP SWAP IF DUP 7 MOD 1+ FG! DUP BRICKxy RFILL BLACK FG! BRICKxy RECT ELSE BLACK FG! BRICKxy RFILL THEN ; : BRICKS 64d 0 DO ON I DRAW_BRICK LOOP ; : !BRICKS bricks 64d 7 FILL ; : FRAME 0 0 191d 159d WHITE FG! RECT 0 20d 191d HLINE 0 159d 191d RED FG! HLINE GREEN FG! 4 4 @XY VGA ." LEVEL 00" 56d 4 @XY VGA ." SCORE 000" CON ; : .SCORE YELLOW FG! 80d 4 @XY VGA DECIMAL 3 U.N CON ; : ?SCORE 0 64d 0 DO I bricks + C@ 0= IF 1+ THEN LOOP .SCORE ; variable ballx variable bally variable xspd variable yspd variable spd // ball sensor bits // 80 40 // 84 // 21 // 20 10 : SENSE ( -- sense ) // 50us 0 ballx @ 1- bally @ 1- PIXEL? IF 800h OR THEN ballx @ 2+ bally @ 1- PIXEL? IF 400h OR THEN ballx @ 1- bally @ 2+ PIXEL? IF 200h OR THEN ballx @ 2+ bally @ 2+ PIXEL? IF 100h OR THEN ballx @ bally @ 1- PIXEL? IF 80h OR THEN ballx @ 1+ bally @ 1- PIXEL? IF 40h OR THEN ballx @ bally @ 2+ PIXEL? IF 20h OR THEN ballx @ 1+ bally @ 2+ PIXEL? IF 10h OR THEN ballx @ 1- bally @ PIXEL? IF 8 OR THEN ballx @ 2+ bally @ PIXEL? IF 4 OR THEN ballx @ 1- bally @ 1+ PIXEL? IF 2 OR THEN ballx @ 2+ bally @ 1+ PIXEL? IF 1 OR THEN ; : YSLOW 1 yspd @ 0< IF NEGATE THEN yspd ! ; : XSLOW 1 xspd @ 0< IF NEGATE THEN xspd ! ; : YFAST 2 yspd @ 0< IF NEGATE THEN yspd ! ; : XFAST 2 xspd @ 0< IF NEGATE THEN xspd ! ; : XREV xspd @ NEGATE xspd ! XSLOW ; : YREV yspd @ NEGATE yspd ! YSLOW ; : ?BRICK ( -- ) bally @ YBRICK DUP 1- SWAP BRICK_YSZ 4 * + WITHIN IF ballx @ BRICK_XSZ / bally @ 1+ YBRICK - 2- BRICK_YSZ / 4 SHL + OFF OVER DRAW_BRICK 0 SWAP bricks + C! ?SCORE THEN ; : BOUNCE // 80us max 0 CASE ENDCASE BONK 0120h CASE YREV YFAST ENDCASE 0230h CASE YREV ENDCASE 0010h CASE YREV ENDCASE 0110h CASE YREV ENDCASE 0005h CASE XREV ENDCASE 0CCCh CASE YREV ENDCASE 020Ah CASE XREV ENDCASE 0105h CASE XREV ENDCASE 0222h CASE XREV XFAST ENDCASE 0232h CASE YREV YFAST ENDCASE 0B30h CASE XREV XFAST YREV ENDCASE 0404h CASE XREV XFAST ENDCASE 000Ah CASE XREV XFAST ENDCASE 0ECAh CASE YREV XREV YFAST ENDCASE 0440h CASE XFAST ENDCASE 080Ah CASE XREV ENDCASE 0900h CASE XFAST ENDCASE 0C40h CASE XREV XFAST YREV ENDCASE 0200h CASE YREV YFAST ENDCASE 0501h CASE XREV ENDCASE 0405h CASE XREV ENDCASE 0320h CASE YREV ENDCASE 0040h CASE YREV ENDCASE 0045h CASE XREV XFAST YREV ENDCASE 0800h CASE XREV XFAST ENDCASE 0A02h CASE XREV XSLOW ENDCASE 0100h CASE XREV XFAST ENDCASE 0130h CASE YREV YFAST ENDCASE 0CC0h CASE YREV ENDCASE 0A0Ah CASE XREV ENDCASE 0808h CASE XREV YFAST ENDCASE 0504h CASE XREV XFAST ENDCASE 0333h CASE XSLOW YSLOW YREV ENDCASE 0080h CASE XREV XFAST YREV ENDCASE 0555h CASE XREV YSLOW XSLOW ENDCASE 0330h CASE YREV ENDCASE 08C0h CASE YREV ENDCASE 0505h CASE XREV ENDCASE 0400h CASE XREV YREV YFAST ENDCASE 0220h CASE XREV XFAST ENDCASE 04C0h CASE YREV YSLOW ENDCASE 0C80h CASE YREV YFAST ENDCASE 0313h CASE YREV YSLOW ENDCASE 0282h CASE XREV YREV YFAST ENDCASE 0020h CASE XREV ENDCASE 0202h CASE XREV ENDCASE 0002h CASE XREV ENDCASE 0085h CASE YREV XREV YFAST ENDCASE 0880h CASE XREV ENDCASE 0008h CASE XREV ENDCASE 0888h CASE YREV ENDCASE 0C00h CASE YREV XFAST ENDCASE 08C8h CASE YREV ENDCASE 0030h CASE YREV ENDCASE 0303h CASE YREV ENDCASE 0111h CASE YREV ENDCASE 0004h CASE YREV ENDCASE 0101h CASE XREV XFAST ENDCASE 0480h CASE YREV YFAST ENDCASE 002Ah CASE XREV YREV YFAST ENDCASE 0B3Ah CASE XREV YREV YFAST ENDCASE 0CC4h CASE XREV YREV YFAST ENDCASE 0C4Ch CASE YREV XREV YFAST ENDCASE 0DC5h CASE XREV YREV YFAST ENDCASE /* CON CRLF .WORD SPACE ballx @ DECIMAL . bally @ . SPACE 60d 1 -MS */ DROP XREV YREV ; : DRAWBALL 2DUP 2 HLINE 1+ 2 HLINE ; : !BALL 96d 150d 2DUP ballx D! WHITE FG! DRAWBALL -1 xspd ! -1 yspd ! ; : START $" BREAKOUT" 4000.2E00h 1 RUN$ ; variable batx variable baty : DRAWBAT ( x y -- ) 8 2 RFILL ; : BAT ( x y -- ) BLACK FG! batx D@ DRAWBAT 2DUP batx D! WHITE FG! DRAWBAT ; : !BAT !KB 96d batx ! 156d baty ! batx D@ WHITE FG! DRAWBAT ; : BAT: 134h CASE batx @ 4 - baty @ BAT ENDCASE 136h CASE batx @ 4 + baty @ BAT ENDCASE 138h CASE batx @ baty @ 2- BAT ENDCASE 132h CASE batx @ baty @ 2+ BAT ENDCASE 139h CASE yspd @ 2* yspd ! ENDCASE 133h CASE xspd @ 2* xspd ! ENDCASE 137h CASE !BAT ENDCASE '=' CASE 8 VOL ENDCASE '-' CASE 6 VOL ENDCASE 20h CASE RESET ENDCASE DUP 30h 39h CASES 30h - spd ! ENDCASE 2DROP ; : BDLY BEGIN KEYBOARD KEY? ?DUP WHILE BAT: REPEAT spd @ 1 -MS ; : BALL ( x y -- ) BLACK FG! ballx D@ DRAWBALL 2DUP ballx D! WHITE FG! DRAWBALL BDLY ; variable xspd1 variable yspd1 : BALL.MOVE xspd D@ xspd1 D! ballx @ xspd @ + bally @ yspd @ + BEGIN SENSE ?DUP IF BOUNCE 2DROP ?BRICK xspd D@ xspd1 D! ballx @ xspd @ + bally @ yspd @ + THEN OVER ballx @ <> OVER bally @ <> OR WHILE OVER ballx @ <> IF ballx @ xspd1 @ 0< IF 1- ELSE 1+ THEN ELSE ballx @ THEN OVER bally @ <> IF bally @ yspd1 @ 0< IF 1- ELSE 1+ THEN ELSE bally @ THEN BALL REPEAT 2DROP ; // ***************************************************************************** variable clock : TITLE 24d 12d @XY 1 X* 2 Y* CYAN FG! VGA ." noPC BREAKOUT" CON ; : BREAKOUT OFF DISPLAY 1 spd ! !AUDIO VREP !BALL !BAT !BRICKS CS BRICKS FRAME // TITLE RED FG! 32d 100d @XY VGA ." + + + +" -1 DUP xspd D! TADA 1 X* 1 Y* MOUNT ON DISPLAY BEGIN !SP BALL.MOVE // CLOCK@ @ clock @ <> // IF CLOCK@ @ clock ! 15d 12d CXY BLUE FG! VGA .TIME THEN AGAIN ; : MAIN 3 MAMTIM ! ON VIDEO START 1 TIMING AUTOBAUD CR QUIT ; ' MAIN AUTO ! FINIS MAIN