Hi again,
A new version is on-line:
1) little modification of MLC with a code to kill labels (for re-use) that I needed for my new pseudo-instructions
2) in PreCompiler, new pseudo-instructions:
a) REPEAT...UNTIL
b) DO...WHILE...LOOP
c) IF...(ELSE)...ENDIF
d) and always the NDO...NLOOP and FOR...NEXT
3) A "silent" mode added, so the compiler is loaded without any message displayed
(use $MLS NS or $MLC FS, "S" stands for silent)
Everything on my page:
http://gtello.pagesp...precompiler.htm
With those new features, the PONG game looks really clearer and I use almost no Label (they are internally managed)
Guillaume.
Have a loo at it
; PONG game using XB and MLC with Precompiler
; 2011 guillaume.tello@orange.fr
100 CALL INIT::CALL CLEAR::DIM A$(40),S$(3)
; load compiler and compiles game and sounds
110 GOSUB 1000
; ball, paddle, net and field definitions
140 CALL CHAR(96,"60F0F0F0F0F0F060")::CALL CHAR(100,"60F0F06000000000")
150 CALL CHAR(97,"8855225588552255")::CALL CHAR(98,"FFFFFFFFFFFFFFFF")::CALL CHAR(99,"0000000000000000")
; prepares screen
160 CALL CLEAR::CALL SCREEN(1)::CALL COLOR(9,16,10)
170 FOR I=1 TO 8::CALL COLOR(I,4,1)::NEXT I
180 RESTORE 900::READ M$,N$,P$::READ SP(1),SP(2),SP(3),SP(4)
190 DISPLAY AT(1,13):"PONG"
200 DISPLAY AT(2,1):M$
210 FOR I=3 TO 19::DISPLAY AT(I,1):N$::NEXT I
220 DISPLAY AT(11,1):P$::DISPLAY AT(20,1):M$
230 DISPLAY AT(21,2):"LEFT (X-E) RIGHT (I-M)"
240 SC(1)=0::SC(2)=0::START=1::SPEED=2::CALL MAGNIFY(2)
; display little menu and wait for SPACE to start
250 DISPLAY AT(24,1):"SPACE=START S=SPEED Q=QUIT"
260 DISPLAY AT(22,7):SC(1)::DISPLAY AT(22,21):SC(2)::GOSUB 400::IF K$<>" " THEN 250
; sprites 2 and 3 are the paddles, sprite 1 the ball
270 CALL SPRITE(#2,96,5,16,24)::CALL SPRITE(#3,96,14,136,224)
280 CALL SPRITE(#1,100,13,120*START-102,184*START-152)
; call assembly routine to play
290 CALL LINK("PLAY",S$(),START,SP(SPEED),WIN)
; upon return, WIN is the winner!
300 SC(WIN)=SC(WIN)+1:: START=3-START::GOTO 260
; quit game, the assembly routine is deleted from ram
310 CALL LINK("POP",A)::PRINT A
320 END
; menu key
400 CALL KEY(0,K,S)::K$=CHR$(ABS(K))::IF K$=" " THEN RETURN
410 IF K$="S" OR K$="s" THEN 420
415 IF K$="Q" OR K$="q" THEN 310 ELSE 400
420 DISPLAY AT(24,1):"SELECT SPEED FROM 1 TO 4:";SPEED
430 ACCEPT AT(24,27)SIZE(-1)BEEP:SPEED
440 RETURN
; field definition
900 DATA bbbbbbbbbbbbbaabbbbbbbbbbbbb
910 DATA bccccccbcccccaacccccbccccccb
920 DATA bccccccbbbbbbaabbbbbbccccccb
; speed table 1 to 4
930 DATA 10,20,35,50
; includes here the loader from line 1000 and DATA from line 2000
; --> to load the compiler (normal mode) use $MLC N ...
; --> to use the Fast Loader use $MLC F ...
; --> If compiler in memory and you don't want it to be loaded, remove CALL INIT and use $MLC D ...
$MLC F 1000 10 2000
1900 RETURN
; sound definitions
$SND 1 ; ball touches paddle 1
FA440VA0VN15D2 VA2D3 VA4D4 VA6D5 VA8D6,VA12D7 VA14D8 VA15D0
$$
$SND 2 ; ball touches paddle 2
FA220VA0VN15D2 VA2D3 VA4D4 VA6D5 VA8D6,VA12D7 VA14D8 VA15D0
$$
$SND 3 ; ball touches border
FN5VN8VA15D1 VN6D1 VN4D1 VN6D1 VN8D2,VN12D2 VN15D0
$$
; game routine
$PLAY
GETPARAM 2 S ; S=start player (1/2)
GETPARAM 3 H ; horizontal speed
RND ; random number in Z
DIV Z H ; reminder (so Z<H)
LET G Z ; vertical speed!
LET M 1 ; default player 1
COMPARE S 1
IF<> ; if start player is not 1
NEG G ; modifies motion and M=2
NEG H
INC M
ENDIF
SMAX 1 ; one sprite with auto motion
SMOTION 1 G H ; ball starts !
SOUND M ; with a paddle sound
SPOSITION 2 A B ; get positions of both paddles
SPOSITION 3 C D
DO
INTERRUPT ; enables interrupt for auto motion
; here player ONE
KEY 1 ; read keyboard left, key in K and COMPARE K 0 performed
IF>= ; a key pressed!
IF= ; if equal 0, it is X
INC A ; here "X"=down, A=A+1
ELSE
COMPARE K 5 ; is it "E"?
IF=
DEC A ; here "E"=up, A=A-1
ENDIF
ENDIF
LIMIT 16 136 A ; ensure A is in the range
SLOCATE 2 A B ; and set new paddle position
ENDIF
COMPARE K 18 ; is it "Q"
WHILE<> ; if so QUIT !
GOSUB b ; manages ball movement
; here player TWO
KEY 2 ; read keyboard right, key in K and COMPARE K 0 performed
IF>= ; a key pressed!
IF= ; if 0, it is "M"
INC C ; if "M"=down, C=C+1
ELSE
COMPARE K 5 ; is it "I"?
IF=
DEC C ; if "I"=up, C=C+1
ENDIF
ENDIF
LIMIT 16 136 C ; ensure C is in the range
SLOCATE 3 C D ; new position
ENDIF
GOSUB b ; manages ball movement
LOOP ; and back to paddle one !!!
GOTO x ; here if K=18, "Q" key, QUIT
; Subroutine for ball movement
SLABEL b
SPOSITION 1 E F ; get ball position
LIMIT 16 144 E ; is the vertical position in the field?
IF<> ; no,so modifications!
NEG G ; reverse motion
SMOTION 1 G H ; reflexion
SLOCATE 1 E F ; new location
SOUND 3 ; and border sound
ENDIF
LIMIT 24 224 F ; is the horizontal potition in the field?
IF<>THEN x ; if not, game has ended!
LIMIT 32 216 F ; else, are we far from the paddles?
IF<> ; not so far, verify contact
IF< ; if under 32 then work with paddle 1
LET G A ; take vertical position of...
LET M 1 ; ...paddle 1
ELSE
LET G C ; else take vertical position of...
LEt M 2 ; ...paddle 2
ENDIF
SUB G E ; vertical distance G-E
LIMIT -16 8 G ; is it in -16,8 ?
IF= ; yes so, contact!
ADD G 4 ; ball touches the paddle M
ADD G G ; G=2*(vertical distance+4) new vertical speed
NEG G ; reflexion
NEG H ; idem
SMOTION 1 G H ; new ball motion
SLOCATE 1 E F ; new location
SOUND M ; and sound for paddle contact
ENDIF
ENDIF
RETURN ; back to players keys
; end of game
LABEL x
SMAX 0 ; end of game, stop every sprite
LET R 1 ; default winner
COMPARE F 124
IF< ; if position under 124, winner is 2
INC R ; R=2
ENDIF
PUTPARAM 4 R ; return winner
$$
$END