-
Notifications
You must be signed in to change notification settings - Fork 3
/
pico8.lua
449 lines (393 loc) · 7.57 KB
/
pico8.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
--PICO-8 Wrapper for the TIC-80 Computer
--by @musurca
----------------------------------------
-- Wraps the PICO-8 API for ease of porting games
-- to the TIC-80. Favors compatibility over performance.
----------------------------------------
--known issues:
-- * swapping elements in the screen palette--e.g. pal(a,b,1)--doesn't work properly yet. However, pal(a,b) does work
-- * flip_x and flip_y are currently ignored in spr() and sspr()
-- * music() and flip() do nothing. sfx() does not take into account offset
-- * stat(1) always returns "0.5"
--set palette
PAL_PICO8="0000001D2B537E2553008751AB52365F574FC2C3C7FFF1E8FF004DFFA300FFEC2700E43629ADFF83769CFF77A8FFCCAA"
function PICO8_PALETTE()
for i=0,15 do
local r=tonumber(string.sub(PAL_PICO8,i*6+1,i*6+2),16)
local g=tonumber(string.sub(PAL_PICO8,i*6+3,i*6+4),16)
local b=tonumber(string.sub(PAL_PICO8,i*6+5,i*6+6),16)
poke(0x3FC0+(i*3)+0,r)
poke(0x3FC0+(i*3)+1,g)
poke(0x3FC0+(i*3)+2,b)
end
end
--sound
__sfx=sfx
function sfx(n,channel,offset)
--does not support offset as of 0.18.0
if n<0 then
__sfx(0,28,channel,0)
else
__sfx(0,28,channel)
end
end
function music(n,fadems,channelmask)
--do nothing as of 0.18.0
end
--utility
function stat(i)
if i==0 then
return collectgarbage("count")
end
return 0.5
end
--strings
function sub(str,i,j)
return str:sub(i,j)
end
--permanent cart mem
function cartdata(id)
--do nothing
end
function dget(i)
return pmem(i)
end
function dset(i,val)
pmem(i,val)
end
--tables
add=table.insert
function all(list)
local i = 0
return function() i = i + 1; return list[i] end
end
count=table.getn
function del(t,a)
for i,v in ipairs(t) do
if v==a then
t[i]=t[#t]
t[#t]=nil
return
end
end
end
function foreach(t, f)
for v in all(t) do
f(v)
end
end
if mt ~= nil then
mt = {}
end
--math
srand=math.randomseed
sqrt=math.sqrt
abs=math.abs
min=math.min
max=math.max
flr=math.floor
pi=math.pi
function rnd(a)
a=a or 1
return math.random()*a
end
function sgn(a)
if a>=0 then return 1 end
return -1
end
function cos(a)
return math.cos(2*pi*a)
end
function sin(a)
return -math.sin(2*pi*a)
end
function atan2(a,b)
b=b or 1
return math.atan(a,b)/(2*pi)
end
function mid(a,b,c)
if a<=b and a<=c then return max(a,min(b,c))
elseif b<=a and b<=c then return max(b,min(a,c)) end
return max(c,min(a,b))
end
function band(a,b)
return flr(a)&flr(b)
end
function bor(a,b)
return flr(a)|flr(b)
end
function bxor(a,b)
return flr(a)^flr(b)
end
function bnot(a,b)
return flr(a)~flr(b)
end
function shl(a,b)
return a<<b
end
function shr(a,b)
return a>>b
end
--graphics
__p8_color=7
__p8_ctrans={true,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false}
__p8_camera_x=0
__p8_camera_y=0
__p8_cursor_x=0
__p8_cursor_y=0
__p8_sflags={}
for i=1,256 do
__p8_sflags[i]=0
end
function camera(cx,cy)
cx=cx or 0
cy=cy or 0
__p8_camera_x=-flr(cx)
__p8_camera_y=-flr(cy)
end
function cursor(cx,cy)
cx=cx or 0
cy=cy or 0
__p8_cursor_x=flr(cx)
__p8_cursor_y=flr(cy)
end
function __p8_coord(x,y)
return flr(x+__p8_camera_x),
flr(y+__p8_camera_y)
end
__print=print
function print(str,x,y,c)
x=x or __p8_cursor_x
y=y or __p8_cursor_y
c=c or __p8_color
c=peek4(0x7FE0+c)
__print(str,x,y,c)
__p8_cursor_y=y+8
end
function color(c)
c=c or 7
__p8_color=flr(c%16)
end
function pal(c0,c1,type)
c0=c0 or -1
c1=c1 or -1
type=type or 0
if c0<0 and c1<0 then
if type==0 then
for i=0,15 do
poke4(0x7FE0+i,i)
end
else
PICO8_PALETTE()
end
else
c0=flr(c0%16)
if c1<0 then
c1=c0
end
c1=flr(c1%16)
if type==0 then
poke4(0x7FE0+c0,c1)
else
local stri
for i=0,5 do
stri=#__p8_pal-(c1+1)*6+i
poke4(0x3FC0*2+#__p8_pal-(c0+1)*6+i,tonumber(__p8_pal:sub(stri,stri),16))
end
end
end
end
function palt(c,trans)
c=c or -1
if c<0 then -- reset
__p8_ctrans[1]=true
for i=2,16 do
__p8_ctrans[i]=false
end
else
__p8_ctrans[flr(c%16)+1]=trans
end
end
function pset(x,y,c)
c=c or __p8_color
c=peek4(0x7FE0+c)
x,y=__p8_coord(x,y)
poke4(y*240+x,c)
end
function pget(x,y)
x,y=__p8_coord(x,y)
return peek4(y*240+x)
end
__rect=rect
function rectfill(x0,y0,x1,y1,c)
c=c or __p8_color
c=peek4(0x7FE0+c)
x0,y0=__p8_coord(x0,y0)
x1,y1=__p8_coord(x1,y1)
local w,h=x1-x0,y1-y0
__rect(x0,y0,w+sgn(w),h+sgn(h),c)
end
function rect(x0,y0,x1,y1,c)
c=c or __p8_color
c=peek4(0x7FE0+c)
x0,y0=__p8_coord(x0,y0)
x1,y1=__p8_coord(x1,y1)
local w,h=x1-x0,y1-y0
rectb(x0,y0,w+sgn(w),h+sgn(h),c)
end
__circ=circ
function circfill(x,y,r,c)
c=c or __p8_color
c=peek4(0x7FE0+c)
x,y=__p8_coord(x,y)
__circ(x,y,r,c)
end
function circ(x,y,r,c)
c=c or __p8_color
c=peek4(0x7FE0+c)
x,y=__p8_coord(x,y)
circb(x,y,r,c)
end
__line=line
function line(x0,y0,x1,y1,c)
c=c or __p8_color
c=peek4(0x7FE0+c)
x0,y0=__p8_coord(x0,y0)
x1,y1=__p8_coord(x1,y1)
__line(x0,y0,x1,y1,c)
end
function sspr(sx,sy,sw,sh,dx,dy,dw,dh) -- todo
dw=dw or sw
dh=dh or sh
dx,dy=__p8_coord(dx,dy)
if dx>240 or dy>136 then return end
local xscale,yscale=dw/sw,dh/sh
local startx,starty,c=0,0
if dx<0 then startx=-dx end
if dy<0 then starty=-dy end
if dx+dw>240 then dw=240-dx end
if dy+dh>136 then dh=136-dy end
for x=startx,dw-1 do
for y=starty,dh-1 do
c=sget(sx+x/xscale,sy+y/yscale)
c=peek4(0x7FE0+c)
if not __p8_ctrans[c+1] then
poke4((dy+y)*240+dx+x,c)
end
end
end
end
__spr=spr
function spr(n,x,y,w,h) --todo flip_x,y
w=w or 1
h=h or 1
local sx,sy,xoff,yoff=n%16*8,flr(n/16)*8,0,0
for j=0,h-1 do
for i=0,w-1 do
sspr(sx+xoff,sy+yoff,8,8,x+xoff,y+yoff)
--__spr(n+j*16+i,x+i*8,y+j*8,__p8_ctrans)
xoff=xoff+8
end
yoff=yoff+8
xoff=0
end
end
__map=map
function map(cel_x,cel_y,sx,sy,cel_w,cel_h)
sx,sy=__p8_coord(sx,sy)
local cel
for cy=0,cel_h-1 do
for cx=0,cel_w-1 do
cel=mget(cx+cel_x,cy+cel_y)
spr(cel,sx+cx*8,sy+cy*8)
end
end
--__map(cel_x,cel_y,cel_w,cel_h,sx,sy,__p8_ctrans)
end
mapdraw=map
function sset(x,y,c)
x,y=flr(x),flr(y)
local addr=0x8000+64*(flr(x/8)+flr(y/8)*16)
poke4(addr+(y%8)*8+x%8,c)
end
function sget(x,y)
x,y=flr(x),flr(y)
local addr=0x8000+64*(flr(x/8)+flr(y/8)*16)
return peek4(addr+(y%8)*8+x%8)
end
function flip()
--do nothing
end
--sprite flags
function fset(n,f,v)
if f>7 then
__p8_sflags[n+1]=f
else
local flags=__p8_sflags[n+1]
if v then
flags=flags|(1<<f)
else
flags=flags&~(1<<f)
end
__p8_sflags[n+1]=flags
end
end
function fget(n,f)
f=f or -1
if f<0 then
return __p8_sflags[n+1]
end
local flags=__p8_sflags[n+1]
if flags&(1<<f)>0 then return true end
return false
end
--input
pico8ButtonMap = {}
pico8ButtonMap[1] = 2 -- 0 left
pico8ButtonMap[2] = 3 -- 1 right
pico8ButtonMap[3] = 0 -- 2 up
pico8ButtonMap[4] = 1 -- 3 down
pico8ButtonMap[5] = 4 -- 4 o
pico8ButtonMap[6] = 5 -- 5 x
pico8ButtonMap[7] = 6 -- 6 start
pico8ButtonMap[8] = 7 -- 7 Doesn't exist
function pico8ButtonToTic80(i, p)
if p == nil then
p = 0
end
return p * 8 + pico8ButtonMap[i + 1]
end
__btn = btn
function btn(i, p)
return __btn(pico8ButtonToTic80(i, p))
end
__btnp = btnp
function btnp(i, p)
return __btnp(pico8ButtonToTic80(i, p))
end
-- TIC function to call pico-8 callbacks.
__updateTick = true
__initalized = false
function TIC()
-- Initialize
if __initalized == false then
PICO8_PALETTE()
if _init ~= nil then
_init()
end
__initalized = true
end
-- Update and Draw
if _update60 ~= nil then -- 60 FPS
_update60()
if _draw ~= nil then _draw() end
elseif _update ~= nil then -- 30 FPS
if __updateTick then
_update()
if _draw ~= nil then _draw() end
end
__updateTick = not __updateTick
end
end
-- Add pico-8 cart below!