added batari basic preprocessor, more examples

This commit is contained in:
Steven Hugg 2018-11-20 14:10:04 -05:00
parent f337b52be3
commit 3018f27576
8 changed files with 699 additions and 3 deletions

36
presets/vcs/bb/draw.bas Executable file
View File

@ -0,0 +1,36 @@
include div_mul.asm
set kernel_options no_blank_lines
set romsize 8kSC
set smartbranching on
const pfres=32
pfclear
player0x=10:player0y=7
player0:
%11000000
%01100000
%00110001
%00011011
%00001111
%00011111
%00111111
end
gameloop
COLUP0=15
COLUPF=203
if joy0left then player0x=player0x-1:if player0x<10 then player0x=10
if joy0right then player0x=player0x+1:if player0x>137 then player0x=137
if joy0up then player0y=player0y-1:if player0y<7 then player0y=7
if joy0down then player0y=player0y+1:if player0y>99 then player0y=99
skipjoy
if joy0fire then gosub plot
drawscreen
goto gameloop
plot
rem convert player position to playfield pixel
rem divide by 3 vertically
g=(player0y-7)/3
h=(player0x-10)/4
if g=i && j=h then return
i=g:j=h
pfpixel h g flip
return

View File

@ -0,0 +1,546 @@
include fixed_point_math.asm
rem Zombie Chase
rem A fun game that may help you learn batari Basic!
rem
rem timed game, 16 levels
rem Each level lasts about one minute
rem you must score 1000 points to move on
rem COLOR/BW switch selects joystick or DC
rem left difficulty A=stop on collision; B=slow down on collision
rem right difficulty A=L/R border; B=no border
set kernel_options no_blank_lines player1colors
playfieldpos=4
set smartbranching on
dim carpos=a
dim turndelay=b
dim collcount=b
dim carframe=c
dim gamebits=e
dim velocity=f.f
dim xvelocity=g.g
dim yvelocity=h.h
dim tempvel=i.i
dim finalxvelocity=l.l
dim finalyvelocity=m.m
dim p0x=player0x.j
dim p0y=player0y.k
dim last=n
dim scadd=o
dim timer1=p
dim timer2=q
dim level=q
rem level bits
rem bit 0: zombie speed (slow/fast)
rem bit 1: zombie movement (random/run away)
rem bit 2: car speed (slow/fast)
rem bit 3: road surface (pavement/ice)
dim tempvel8=temp1.temp2
dim zombievel=temp5.temp6
dim zombiexvel=r
dim zombieyvel=s
dim zombiefinalxvel=t
dim zombiefinalyvel=u
dim zombiexpos=player1x.v
dim zombieypos=player1y.w
dim sc1=score
dim sc2=score+1
rem
rem velocity doesn't change when direction changes
rem xvelocity and yvelocity change
rem they change instantly when velocity <= 0.5 max
rem they change gradually when velocity > 0.5 max
carpos = 4
rem turndelay = 0
player0x = 40 : player0y = 40
startLoop
if turndelay{1} then player1:
%00100010
%00010100
%00111110
%00111111
%00011011
%11111001
%00101000
%00010000
end
if !turndelay{1} then player1:
%00010100
%00100010
%00111110
%00111111
%00011011
%11111010
%00101000
%00010000
end
player1color:
$38;
$3A;
$F4;
$F6;
$0C;
$1A;
$D8;
$D2;
end
scorecolor=30
if switchreset then reboot
if switchrightb then PF0=0 else PF0=63
COLUPF=(level * 16)^244
if gamebits{7} then gamerunning
if !joy0fire then timer1=timer1+1
if timer1=0 then nostartgame
if joy0fire then score=0:timer1=0:timer2=0:gamebits{7}=1:pfclear
nostartgame
AUDV0=0:AUDV1=0:goto hitwall
gamerunning
timer1=timer1+1:if timer1=0 then timer2=timer2+$10
if timer2<$C0 then notendlevel
temp1=level & $0F
temp2=sc1*16+sc2/16
temp1=level & $0F
if temp2<gonextlevel[temp1] && timer1{5} then scorecolor=64
if timer2<$F0 then notendlevel
if temp2>=gonextlevel[temp1] then level=level+$11:pfclear else gamebits{7}=0
notendlevel
gosub movezombie
if collcount<16 then skipcrashsound
collcount=collcount-16
AUDV0=collcount/16
AUDC0=8
if collcount{3} then AUDF0=(collcount&rand)/8 else AUDF0=17
goto skipenginesound
skipcrashsound
collcount{3}=0
AUDV0=10:AUDC0=2
AUDF0=18-f/4:if f>67 then AUDF0=1
skipenginesound
if joy0fire then velocity=velocity+0.0625:goto nomove1
gamebits=gamebits^%00000100
if gamebits{2} then nomove1
velocity=velocity-0.0625
nomove1
if level{2} then temp1=96 else temp1=64
if gamebits{4} then temp1=16
if velocity > temp1 && velocity < 192 then velocity=velocity-0.0625
if velocity>240 then velocity=0
if !level{3} then COLUBK=0 else COLUBK=154
on carpos goto a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
a0 rem 0 (due north, or up)
xvelocity=0:yvelocity=0-velocity
goto skipskid
a1 rem 22.5
tempvel=velocity/8
xvelocity=tempvel:yvelocity=tempvel-velocity
tempvel=velocity/4
xvelocity=xvelocity+tempvel
goto skipskid
a2 rem 45
tempvel=velocity/4
xvelocity=velocity/2
if xvelocity{7} then xvelocity=xvelocity | %10000000
xvelocity=xvelocity+tempvel:yvelocity=0-xvelocity
goto skipskid
a3 rem 67.5
tempvel=velocity/8
xvelocity=velocity-tempvel:yvelocity=0-tempvel
tempvel=velocity/4
yvelocity=yvelocity-tempvel
goto skipskid
a4 rem 90
xvelocity=velocity:yvelocity=0
goto skipskid
a5 rem 112.5
tempvel=velocity/8
xvelocity=velocity-tempvel:yvelocity=tempvel
tempvel=velocity/4
yvelocity=yvelocity+tempvel
goto skipskid
a6 rem 135
tempvel=velocity/4
xvelocity=velocity/2
if xvelocity{7} then xvelocity=xvelocity | %10000000
xvelocity=xvelocity+tempvel:yvelocity=xvelocity
goto skipskid
a7 rem 157.5
tempvel=velocity/8
xvelocity=tempvel:yvelocity=velocity-tempvel
tempvel=velocity/4
xvelocity=xvelocity+tempvel
goto skipskid
a8 rem 180
xvelocity=0:yvelocity=velocity
goto skipskid
a9 rem 202.5
tempvel=velocity/8
xvelocity=0-tempvel:yvelocity=velocity-tempvel
tempvel=velocity/4
xvelocity=xvelocity-tempvel
goto skipskid
a10 rem 225
tempvel=velocity/4
xvelocity=velocity/2
yvelocity=tempvel+xvelocity:xvelocity=0-xvelocity
goto skipskid
a11 rem 247.5
tempvel=velocity/8
xvelocity=tempvel-velocity:yvelocity=tempvel
tempvel=velocity/4
yvelocity=yvelocity+tempvel
goto skipskid
a12 rem 270
xvelocity=0-velocity:yvelocity=0
goto skipskid
a13 rem 292.5
tempvel=velocity/8
xvelocity=tempvel-velocity:yvelocity=0-tempvel
tempvel=velocity/4
yvelocity=yvelocity-tempvel
goto skipskid
a14 rem 315
tempvel=velocity/4
xvelocity=velocity/2
xvelocity=tempvel+xvelocity:xvelocity=0-xvelocity:yvelocity=xvelocity
goto skipskid
a15 rem 337.5
tempvel=velocity/8
xvelocity=0-tempvel:yvelocity=tempvel-velocity
tempvel=velocity/4
xvelocity=xvelocity-tempvel
skipskid
if velocity{7} then reboot
if !gamebits{0} then finalxvelocity=xvelocity:finalyvelocity=yvelocity:AUDV1=0:goto noskid else skid
if velocity<32 then finalxvelocity=xvelocity:finalyvelocity=yvelocity:AUDV1=0:goto noskid
if finalxvelocity = xvelocity && finalyvelocity = yvelocity then AUDV1=0:goto noskid
skid
rem lost traction...skid
gamebits{5}=0
gamebits{6}=0
if xvelocity>127 && finalxvelocity>127 then bothxneg
if xvelocity<128 && finalxvelocity<128 then bothxpos
if xvelocity>127 then subx else addx
bothxneg
temp1=(finalxvelocity ^ xvelocity) & %11111100
if temp1=0 then finalxvelocity=xvelocity:gamebits{5}=1:goto checky
if finalxvelocity<xvelocity then addx
subx
if level{3} then finalxvelocity=finalxvelocity-0.0625 else finalxvelocity=finalxvelocity-0.3
goto checky
bothxpos
temp1=(finalxvelocity ^ xvelocity) & %11111100
if temp1=0 then finalxvelocity=xvelocity:gamebits{5}=1:goto checky
if finalxvelocity>xvelocity then subx
addx
if level{3} then finalxvelocity=finalxvelocity+0.0625 else finalxvelocity=finalxvelocity+0.3
checky
if yvelocity>127 && finalyvelocity>127 then bothyneg
if yvelocity<128 && finalyvelocity<128 then bothypos
if yvelocity>127 then suby else addy
bothyneg
temp1=(finalyvelocity ^ yvelocity) & %11111100
if temp1=0 then finalyvelocity=yvelocity:gamebits{6}=1:goto doneskid
if finalyvelocity<yvelocity then addy
suby
if level{3} then finalyvelocity=finalyvelocity-0.0625 else finalyvelocity=finalyvelocity-0.3
goto doneskid
bothypos
temp1=(finalyvelocity ^ yvelocity) & %11111100
if temp1=0 then finalyvelocity=yvelocity:gamebits{6}=1:goto doneskid
if finalyvelocity>yvelocity then suby
addy
if level{3} then finalyvelocity=finalyvelocity+0.0625 else finalyvelocity=finalyvelocity+0.3
doneskid
if gamebits{5} && gamebits{6} then gamebits{0}=0:AUDV1=0:goto noskid
rem skid sound
temp6=rand
if temp1{6} then AUDV1=9
rem if temp6{0} then AUDC1=3:AUDF1=0 else AUDC1=3:AUDF1=1
rem AUDV1=temp6&3
if level{3} then temp1=8 else temp1=20
AUDC1=temp1
if temp6{0} then AUDF1=temp1+4 else AUDF1=temp1+5
noskid
rem gamebits=gamebits^%00000010
rem if gamebits{1} then donotadd
tempvel8=finalxvelocity
asm
lda temp1
asl
ror temp1
ror temp2
end
p0x=p0x+tempvel8
tempvel8=finalyvelocity
asm
lda temp1
asl
ror temp1
ror temp2
end
p0y=p0y+tempvel8
donotadd
if player0x>200 then player0x=159:goto wrap
if player0x>159 then player0x=0
wrap
if player0y>200 then player0y=96
if player0y>96 then player0y=0
if switchbw then driving
turndelay = turndelay + 1
turndelay = turndelay & %11111011
temp1=turndelay&3
if temp1 <> 0 goto SameFrame
if joy0left then carpos=carpos-1:gamebits{0}=1
if joy0right then carpos=carpos+1:gamebits{0}=1
goto nodriving
driving rem read driving controller
temp1=SWCHA & %00110000
temp1=temp1/16
on last goto d00 d01 d10 d11
d00 on temp1 goto nomove left right nomove
d01 on temp1 goto right nomove nomove left
d11 on temp1 goto nomove right left nomove
d10 on temp1 goto left nomove nomove right
rem done with reading code
left carpos=carpos-1:gamebits{0}=1
goto nomove
right carpos=carpos+1:gamebits{0}=1
nomove
last=temp1
nodriving
carpos=carpos & 15
gosub carFrame
SameFrame
COLUP0 = 14
REFP0=gamebits
if scadd>0 then scadd=scadd-1:score=score+1
if !collision(player0,player1) then nohitzombie
scadd=scadd+f
collcount=collcount|$F8
if player1x<16 || player1x>143 then notombstone
temp1=(player1x-16)/4:temp2=(player1y-4)/8
pfpixel temp1 temp2 on
notombstone
player1x=rand&63+48:if player1x{0} then player1y=0 else player1y=90
nohitzombie
if gamebits{4} then insidewall
if collcount>16 then hitwall
if !collision(player0,playfield) then insidewall
if !switchleftb then velocity=0
gamebits{4}=1:collcount=collcount | $F0:collcount{3}=0:goto hitwall
insidewall
if !collision(player0,playfield) then gamebits{4}=0:goto hitwall
if velocity>16 then velocity=velocity-0.1875
hitwall
drawscreen
goto startLoop
carFrame
carframe = 0
if carpos < 9 then carframe = carpos : gamebits{3}= 0
if carpos >= 9 then carframe = 16 - carpos : gamebits{3} = 1
on carframe goto 5 10 20 30 40 50 60 70 80
5 player0:
%11000011
%11111111
%11011011
%00011000
%11011011
%11111111
%11011011
%00011000
end
goto doneSetFrame
10 player0:
%00000110
%00111110
%11110000
%11011011
%00011111
%11111000
%11001100
%00000100
end
goto doneSetFrame
20 player0:
%00001100
%00001100
%00110011
%00111011
%11011100
%11001100
%00110010
%00110000
end
goto doneSetFrame
30 player0:
%00110110
%00110110
%01100100
%01111110
%01011110
%11001011
%11011000
%00011000
end
goto doneSetFrame
40 player0:
%11101110
%11101110
%01000100
%01111111
%01111111
%01000100
%11101110
%11101110
end
goto doneSetFrame
50 player0:
%00011000
%11011000
%11001011
%01011110
%01111110
%01100100
%00110110
%00110110
end
goto doneSetFrame
60 player0:
%00110000
%00110010
%11001100
%11011100
%00111011
%00110011
%00001100
%00001100
end
goto doneSetFrame
70 player0:
%00000100
%11001100
%11111000
%00011111
%11011011
%11110000
%00111110
%00000110
end
goto doneSetFrame
80 player0:
%00011000
%11011011
%11111111
%11011011
%00011000
%11011011
%11111111
%11000011
end
doneSetFrame
return
movezombie
temp1=zombiexvel&252:temp2=zombieyvel&252:temp3=zombiefinalxvel&252:temp4=zombiefinalyvel&252
if temp1<>temp3 then check24
zombiefinalxvel=rand
if level{1} then temp1=player1x-player0x:zombiefinalxvel{7}=temp1{7}
check24
if temp2<>temp4 then donecheck24
zombiefinalyvel=rand
if level{1} then temp1=player1y-player0y:zombiefinalyvel{7}=temp1{7}
donecheck24
if zombiexvel{7} && !zombiefinalxvel{7} then zombiexvel=zombiexvel+1:goto donex
if !zombiexvel{7} && zombiefinalxvel{7} then zombiexvel=zombiexvel-1:goto donex
if zombiexvel>zombiefinalxvel then zombiexvel=zombiexvel-1 else zombiexvel=zombiexvel+1
donex
if zombieyvel{7} && !zombiefinalyvel{7} then zombieyvel=zombieyvel+1:goto doney
if !zombieyvel{7} && zombiefinalyvel{7} then zombieyvel=zombieyvel-1:goto doney
if zombieyvel>zombiefinalyvel then zombieyvel=zombieyvel-1 else zombieyvel=zombieyvel+1
doney
temp5=0
if zombiexvel{7} then temp5=255
temp3=0
if zombieyvel{7} then temp3=255
temp6=zombiexvel:temp4=zombieyvel
zombiexpos=zombiexpos+zombievel
temp6=temp4:temp5=temp3
zombieypos=zombieypos+zombievel
if player1y>100 then player1y=0
if player1y>$50 then zombiefinalyvel=(zombiefinalyvel^127)|128:zombieyvel=(zombieyvel^127)|128
if player1y<10 then zombiefinalyvel=(zombiefinalyvel^127)&127:zombieyvel=(zombieyvel^127)&127
if player1x>200 then player1x=player1x+160
if player1x>160 then player1x=player1x-160
REFP1=zombiexvel/16
return
data gonextlevel
1,2,3,4,5,6,7,8,9,$10,$11,$12,$13,$14,$15,$99
end
vblank
if gamebits{7} && level{0} then gosub movezombie
return

View File

@ -1,4 +1,4 @@
 rem Hello World
rem Hello World
playfield:
................................

45
presets/vcs/bb/sample.bas Executable file
View File

@ -0,0 +1,45 @@
set smartbranching on
10 player1x = 40 : player1y = 40:player0x = 50 : player0y = 50
20 COLUPF = 90:missile0height=4:missile0y=255
25 score=10000
30 COLUP0 = 120
35 COLUP1 = 14
40 scorecolor = 10:NUSIZ0=16
45 player0:
%01000010
%11111111
%11111111
%01111110
%00111100
%00011000
%00011000
%00011000
end
46 player1:
%00111100
%00011000
%00011000
%00011000
%11100111
%10100101
%10011001
%00100100
end
47 a = a + 1 : if a < 3 then 55
49 a = 0
50 if player1y < player0y then player1y = player1y + 1
51 if player1y > player0y then player1y = player1y - 1
52 if player1x < player0x then player1x = player1x + 1
53 if player1x > player0x then player1x = player1x - 1
54 player1x = player1x : player1y = player1y
55 if missile0y>240 then 58
57 missile0y=missile0y-2:goto 59
58 if joy0fire then missile0y=player0y-2:missile0x=player0x+4
59 drawscreen
60 if collision(missile0,player1) then score=score+1:player1x=rand/2:player1y=0:missile0y=255
65 if collision(player0,player1) then score=score-1
70 if joy0up then player0y = player0y - 1
80 if joy0down then player0y = player0y + 1
100 if joy0left then player0x = player0x - 1
120 if joy0right then player0x = player0x + 1
140 goto 30

View File

@ -42,6 +42,9 @@ const VCS_PRESETS = [
// {id:'examples/music2', name:'Pitch-Accurate Music'},
// {id:'examples/fullgame', name:'Thru Hike: The Game', title:'Thru Hike'},
{id:'bb/helloworld.bas', name:'Hello World (batariBASIC)'},
{id:'bb/draw.bas', name:'Playfield Draw (batariBASIC)'},
{id:'bb/sample.bas', name:'Sprite Test (batariBASIC)'},
{id:'bb/duck_chase.bas', name:'Duck Chase (batariBASIC)'},
];
Javatari.AUTO_START = false;

View File

@ -152,6 +152,7 @@ function refreshWindowList() {
if (listings) {
for (var lstfn in listings) {
var lst = listings[lstfn];
// TODO: add assembly listings? (lines, macrolines, sourcefile)
if (lst.assemblyfile) {
addWindowItem(lstfn, getFilenameForPath(lstfn), function(path) {
return new Views.ListingView(lstfn);

File diff suppressed because one or more lines are too long

View File

@ -1487,6 +1487,27 @@ error1.asm(11): warning: 'foobar' treated as label (instruction typo?)
}
}
function preprocessBatariBasic(code:string) : string {
load("bbpreprocess");
var bbout = "";
function addbbout_fn(s) {
bbout += s;
bbout += "\n";
}
var BBPRE = emglobal.preprocess({
noInitialRun:true,
//logReadFiles:true,
print:addbbout_fn,
printErr:print_fn,
noFSInit:true,
});
var FS = BBPRE['FS'];
setupStdin(FS, code);
BBPRE.callMain([]);
console.log("preprocess " + code.length + " -> " + bbout.length + " bytes");
return bbout;
}
function compileBatariBasic(step:BuildStep) {
load("bb2600basic");
var params = step.params;
@ -1523,8 +1544,9 @@ function compileBatariBasic(step:BuildStep) {
});
var FS = BB['FS'];
populateFiles(step, FS);
// pipe file to stdin
// preprocess, pipe file to stdin
var code = workfs[step.path].data as string; // TODO
code = preprocessBatariBasic(code);
setupStdin(FS, code);
setupFS(FS, '2600basic');
execMain(step, BB, ["-i", "/share", step.path]);
@ -1535,8 +1557,15 @@ function compileBatariBasic(step:BuildStep) {
var redefsout = FS.readFile("2600basic_variable_redefs.h", {encoding:'utf8'});
var includes = includesout.trim().split("\n");
var combinedasm = "";
var splitasm = asmout.split("bB.asm file is split here");
for (var incfile of includes) {
var inctext = (incfile=="bB.asm") ? asmout : FS.readFile("/share/includes/"+incfile, {encoding:'utf8'});
var inctext;
if (incfile=="bB.asm")
inctext = splitasm[0];
else if (incfile=="bB2.asm")
inctext = splitasm[1];
else
inctext = FS.readFile("/share/includes/"+incfile, {encoding:'utf8'});
console.log(incfile, inctext.length);
combinedasm += "\n\n;;;" + incfile + "\n\n";
combinedasm += inctext;