9 Commits

Author SHA1 Message Date
5634fcf4a4 recolor!
this looks terrible
2023-10-01 16:00:00 -07:00
447a1bedd0 set up candidate "tyrian" palette 2023-10-01 15:47:01 -07:00
0f7c7a810b remove gradients from meters, make vertmeter segmented 2023-10-01 15:41:58 -07:00
a5ce0fd020 update todo list 2023-10-01 14:39:34 -07:00
dae108c231 move spark_particle's mknew call to the right spot 2023-10-01 00:46:32 -07:00
2e46d87a84 refactor spark logic. this loses tokens; may need to revisit 2023-09-30 20:10:42 -07:00
a4590821be pre-initialize palettes for blip. costs tokens, saves time 2023-09-30 19:45:07 -07:00
cf1e1153a3 lframe increment is now 0x0.0001
avoids time rollover! not doing this for `distance` because I don't intend any level script to exceed five minutes, but freeze time could be much longer
2023-09-30 19:30:21 -07:00
f3ac1f492c Dithering-style fade
Higher performance, allows free use of other palettes, frees up compressed space.
2023-09-30 19:15:22 -07:00
2 changed files with 113 additions and 132 deletions

View File

@ -1,8 +1,8 @@
## 1. refine existing engine (knowing what I know now)
- [ ] rewrite event queue as a linked list
- [ ] rewrite animator stacks as linked lists
- [ ] rewrite ship/bullet collections as linked lists
- [x] rewrite event queue as a linked list
- [x] rewrite animator stacks as linked lists
- [x] rewrite ship/bullet collections as linked lists
- [ ] update/draw mode switching system (high-efficiency version)
- [ ] render ship shields (even for large ships)
- [ ] duplicate file -- about to split away from Tyrian features

View File

@ -118,12 +118,12 @@ function linked_list:pop_front()
end
function _init()
init_blip_pals()
wipe_level()
primary_ship.main_gun = zap_gun.new()
load_level(example_level)
state = game
pal(2,129)
pal()
pal(0)
end
function once_next_frame(f)
@ -135,23 +135,8 @@ function once_next_frame(f)
}
end
-- health gradients for 1..5 hp
-- exactly, then all "more".
hpcols_lut = csv[[36
34, 136
34, 130, 136
34, 34, 130, 136
34, 34, 130, 130, 136]]
-- call after any change to maxhp
-- configures health gradient
function init_hpcols()
hpcols = hpcols_lut[min(primary_ship.maxhp,6)]
end
function wipe_level()
primary_ship = player.new()
init_hpcols()
pships = linked_list.new()
pships:push_back(primary_ship)
eships = linked_list.new()
@ -246,7 +231,19 @@ function updategame()
if (not pships.next) state = lose
end
function parse_pal(str)
local ret = split(str)
for i=0,15 do
ret[i]=ret[i+1]
end
ret[16] = nil
return ret
end
mainpal = parse_pal"0,134,141,138,4,5,6,7,8,9,10,11,12,13,8,12"
function _draw()
fillp(0)
drawgame()
if (state == game) fadelvl = -45
if (state == win) dropshadow("win",50,61,11)
@ -254,37 +251,14 @@ function _draw()
fadescreen()
end
fadetable=csv[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1,1,129,129,129,129,129,129,129,129,0,0,0,0,0
2,2,2,130,130,130,130,130,128,128,128,128,128,0,0
3,3,3,131,131,131,131,129,129,129,129,129,0,0,0
4,4,132,132,132,132,132,132,130,128,128,128,128,0,0
5,5,133,133,133,133,130,130,128,128,128,128,128,0,0
6,6,134,13,13,13,141,5,5,5,133,130,128,128,0
7,6,6,6,134,134,134,134,5,5,5,133,130,128,0
8,8,136,136,136,136,132,132,132,130,128,128,128,128,0
9,9,9,4,4,4,4,132,132,132,128,128,128,128,0
10,10,138,138,138,4,4,4,132,132,133,128,128,128,0
11,139,139,139,139,3,3,3,3,129,129,129,0,0,0
12,12,12,140,140,140,140,131,131,131,1,129,129,129,0
13,13,141,141,5,5,5,133,133,130,129,129,128,128,0
14,14,14,134,134,141,141,2,2,133,130,130,128,128,0
15,143,143,134,134,134,134,5,5,5,133,133,128,128,0]]
fadetable = split"0,1.5,1025.5,1029.5,1285.5,1413.5,9605.5,9637.5,-23130.5,-23066.5,-18970.5,-18954.5,-2570.5,-2568.5,-520.5,-8.5,-0.5"
function fadescreen()
fadelvl += 0.25
if fadelvl < 0 then
pal()
return
end
local i = flr(fadelvl)
for c=0,15 do
if i+1>=16 then
pal(c,0,1)
else
pal(c,fadetable[c+1][i+1],1)
end
end
if (fadelvl < 1) return
local i = min(flr(fadelvl), #fadetable)
fillp(fadetable[#fadetable+1-i])
rectfill(0,0,128,128,0)
end
-- puke emits a verbose string
@ -333,8 +307,10 @@ function pukeboard(item)
end
function drawgame()
cls()
pal(0)
pal(mainpal, 1)
clip(0,0,112,128)
rectfill(0,0,112,128,0)
for slist in all{intangibles_bg, pbullets, pships, eships, ebullets, intangibles_fg} do
slist:draw()
end
@ -342,7 +318,6 @@ function drawgame()
drawhud()
end
powcols=split"170,154,153,148,68"
function drawhud()
-- 112-and-right is hud zone
rectfill(112, 0, 127, 127,0x56)
@ -355,17 +330,15 @@ function drawhud()
dropshadow("pwr",114,59,1)
inset(114,66,125,92)
fillp(0x5a5a)
vertmeter(115,67,124,91,primary_ship.power, primary_ship.max_power, powcols)
vertmeter(115,67,124,91,primary_ship.power, primary_ship.max_power, 9,8)
dropshadow("h s",114,97,1)
inset(114,104,125,125)
line(119,105,119,124,119)
line(120,105,120,125,85)
vertmeter(115,105,118,124,primary_ship.hp, primary_ship.maxhp, hpcols)
vertmeter(121,105,124,124,primary_ship.shield, primary_ship.maxshield,{204,220,221})
fillp(0)
vertmeter(115,105,118,124,primary_ship.hp, primary_ship.maxhp, 8,3)
vertmeter(121,105,124,124,primary_ship.shield, primary_ship.maxshield,12,3)
end
function draw_gun_info(lbl,fgc,x,y,gun)
@ -390,20 +363,17 @@ function draw_gun_info(lbl,fgc,x,y,gun)
end
end
function vertmeter(x0,y0,x1,y1,val,maxval,cols)
function vertmeter(x0,y0,x1,y1,val,maxval,col,seg)
if (val <= 0) return
local h = y1-y0
local px = -flr(-(h*val)\maxval)
local ncols = #cols
local firstcol = ((h-px)*ncols\h)+1
local lastbottom = y0+(h*firstcol\ncols)
rectfill(x0, y1-px, x1, lastbottom, cols[firstcol])
for i=firstcol+1,ncols do
local bottom = y0+h*i\ncols
rectfill(x0,lastbottom,x1,bottom,cols[i])
lastbottom = bottom
end
local h = y1-y0+1
local per_seg = ceil((h+1)/seg) - 1
local px = (h-seg+1)*val\maxval
while px > 0 do
rectfill (x0, y1-min(px, per_seg)+1, x1, y1, col)
px -= per_seg
y1 -= per_seg+1
end
end
function inset(x0,y0,x1,y1)
rectfill(x0,y0,x1,y1,0)
@ -448,15 +418,13 @@ ship_m = {
shield = 0,
maxshield = 0,
shieldcost = 32767.9,
shieldcooldown = 180,
shieldcooldown = 0x0.00a0,
-- default generator behavior:
-- 10 seconds for a full charge
max_power = 600,
power = 600,
generator = 1, -- power gen per frame
invincible_until = -32768,
slip = true, -- most enemies slide
@ -509,7 +477,7 @@ end
function ship_m:draw()
if(self.fx_pal) pal(self.fx_pal)
spr(self.sprite, self.x, self.y, self.size, self.size)
pal()
pal(0)
end
function hurtbox(ship)
@ -539,7 +507,6 @@ end
function ship_m:hitsomething(dmg)
if (dmg <= 0) return false
if (lframe < self.invincible_until) return false
self.shield_refresh_ready = lframe + self.shieldcooldown
if self.shield >= dmg then
self.shield -= dmg
@ -795,7 +762,7 @@ function spawn_xl_chasey_at(x, y)
draw = function(self)
if(self.fx_pal) pal(self.fx_pal)
sspr(40, 0, 8, 8, self.x, self.y, 16, 16)
pal()
pal(0)
end,
}
eships:push_back(c)
@ -886,7 +853,7 @@ end
-- effective frame
distance = 0
-- actual frame count since
-- start of level
-- start of level times 0x0.0001
lframe = 0
-- do not advance distance when
@ -910,7 +877,7 @@ function load_level(lvltbl)
end
function level_frame()
lframe += 1
lframe += 0x0.0001
if (current_level == nil) return true
if freeze == 0 then
distance += 1
@ -1030,11 +997,11 @@ function spawn_blocking_boss_chasey()
chasey.die(self)
end
local nextspawn = lframe + 120
local nextspawn = lframe + 0x0.0080
events:push_back{move=function()
if lframe >= nextspawn then
helpers[flr(rnd(#helpers))+1]()
nextspawn += 60
nextspawn += 0x0.0040
end
return c.dead
end}
@ -1077,7 +1044,7 @@ example_level = {
events:push_back{move=function()
if (lframe < tnext) return false
spawn_blocking_blocky()
tnext = lframe + 12
tnext = lframe + 0x0.000c
remain -= 1
return (remain <= 0)
end}
@ -1198,7 +1165,7 @@ mknew(zap)
zap_gun = gun_base.new{
enemy = false,
power = 20, -- power consumed per shot
cooldown = 10, -- frames between shots
cooldown = 0x0.000a, -- frames between shots
ammo = nil, -- unlimited ammo - main gun
t = zap -- metatable of bullet to fire
}
@ -1255,7 +1222,7 @@ blast_gun = gun_base.new{
icon = 13,
enemy = false,
power = 0, -- ammo, not power
cooldown = 30, -- frames between shots
cooldown = 0x0.0020, -- frames between shots
ammo = 5,
maxammo = 5,
t = blast -- type of bullet to fire
@ -1288,7 +1255,7 @@ protron_gun = gun_base.new{
icon = 25,
enemy = false,
power = 35,
cooldown = 15, -- frames between shots
cooldown = 0x0.000f, -- frames between shots
ammo = nil,
maxammo = nil,
actually_shoot = function(self, x, y)
@ -1346,7 +1313,7 @@ vulcan_gun = gun_base.new{
icon = 37,
enemy = false,
power = 8,
cooldown = 2, -- frames between shots
cooldown = 0x0.0002, -- frames between shots
ammo = nil,
maxammo = nil,
dxs = {0.35, -0.35, -0.7, 0.7, 0.35, -0.35},
@ -1595,21 +1562,22 @@ it sets lframe ("level frame")
and distance to 0.
every frame, level_frame
increments lframe. then if the
level is not frozen (more on
that later), it increments
distance and runs the function
in the level table for exactly
that frame number (if any).
distance is therefore "nonfrozen
frames", and is used to trigger
level progress. lframe always
increments lframe by 0x0.0001.
then if the level is not frozen,
it increments distance by 1.0
and runs the function in the
level table for exactly that
frame number (if any). distance
is therefore "nonfrozen frames",
and is used to trigger level
progress. lframe always
increments. ships are encouraged
to use lframe to control
animation and movement, and may
use distance to react to level
progress separately from overall
time.
time. remember to multiply
lframe-related stuff by 0x0001.
a special sentinel value, eol,
marks the end of the level.
@ -1776,10 +1744,19 @@ end
mknew(blip_fx)
blip_pals = {}
function init_blip_pals()
for i=0,15 do
local pp = {[0]=0}
for j=1,15 do
pp[j] = i
end
blip_pals[i]=pp
end
end
function blip(obj, col, frames)
local p = {[0]=0}
obj.fx_pal = p
for i=1,15 do p[i]=col end
obj.fx_pal = blip_pals[col]
if (obj.___fx_pal_event) obj.___fx_pal_event:abort()
events:push_back(blip_fx.new{frames=frames, obj=obj})
end
@ -1803,29 +1780,33 @@ function boom(x,y,boominess,is_boss)
return
end
spark_particle={}
mknew(spark_particle)
function spark_particle:move()
if (rnd(4) < 1) self.sidx += 1
if (self.sidx > #self.sprs) return true
self.x += self.dx
self.y += self.dy
self.dx -= mid(0.05,-0.05, self.dx)
self.dy -= mid(0.05,-0.05, self.dy)
end
function spark_particle:draw()
pset(self.x,self.y,self.sprs[self.sidx])
end
function spark(sprs, x, y, butts, thrust, odds, fg)
if (sprs==nil or flr(rnd(odds)) ~= 0) return
thrust *= 2.5
local target = fg and intangibles_fg or intangibles_bg
target:push_back{
target:push_back(spark_particle.new{
x = x + rnd(4) - 2,
y = y + rnd(4) - 2,
sprs = sprs,
sidx = 1,
dx = (butts[0] - butts[1]) * thrust + rnd(2) - 1,
dy = (butts[2] - butts[3]) * thrust + rnd(2) - 1,
draw = function(self)
pset(self.x, self.y, self.sprs[self.sidx])
end,
move = function(self)
if (rnd(4) < 1) self.sidx += 1
if (self.sidx > #self.sprs) return true
self.x += self.dx
self.y += self.dy
self.dx -= mid(0.05,-0.05, self.dx)
self.dy -= mid(0.05,-0.05, self.dy)
end
}
})
end
-->8
-- powerups
@ -1864,7 +1845,7 @@ sheen8x8 = split"2,54,55,56,57,58,59,60,61"
function powerup:draw()
spr(self.sprites[max(1,
(lframe\self.anim_speed)
((lframe<<16)\self.anim_speed)
%(#self.sprites+self.loop_pause)
-self.loop_pause
+1)],
@ -1949,29 +1930,29 @@ function spawn_spec_gun_at(x, y, gunt)
draw = function(self)
pal(spec_gun_pl)
powerup.draw(self)
pal()
pal(0)
spr(self.gun.icon, self.x+2, self.y+2, 1, 1)
end
}
gun_p:spawn_at(x, y)
end
__gfx__
00000000000650000000000000000000bb0b50b59909209200cc0c00000000003b00000082000000e00e8002e00e800200333300002222000000000000000000
00000000006765000000000000cccc00b50b3055920940220c0000c000bbbb0037000000a2000000e0e8880240e8480403bbbb30028888200000000000000000
00700700006d6500000000000cddddd00b33335009444420c00c000c0b333330b7000000a8000000e88e2882e48e24823bbaabb3288aa8820000000000000000
00077000067c665000000000cdd10cd10b3dd350094dd42000c0000cb3350b35b7000000a8000000e88e2882484e24423ba77ab328a77a820000000000000000
00077000067d665000000000cd10cdd100b3350000944200c0000000b350b335b7000000a8000000e88e2882e84e28823ba77ab328a77a820000000000000000
0070070065666765000000000ddddd100b33355009444220c000000c03333350b7000000a800000008888820048488203bbaabb3288aa8820000000000000000
000000006506506500000000001111000b0b5050090920200c0000c00055550037000000a2000000008882000048420003bbbb30028888200000000000000000
00000000650000650000000000000000000b50000009200000c0cc00000000003b00000082000000000820000008200000333300002222000000000000000000
00000000000650000006500000000000b000000b80000000700000000bb0000008800000000000000009200000000000cccccccd000650000000000000000000
0000000000675000000765000000000000bbbb0080000000b0000000b76300008a920000000000009009200200000000c111111d006765000000000000000000
00000000006d6500006d6500000000000b0000b09000000030000000b663000089920000000550009994444200000000c111111d006d65000000000000000000
00000000067c6650067c6650000000000b0bb0b0a000000030000000033000000220000000576d009446544200000000c111111d067c66500000000000000000
00000000067d6650067d6650000000000b0bb0b00000000000000000000000000000000000566d009244442200000000c111111d067d66500000000000000000
000000005666657576667650000000000b0000b000000000000000000000000000000000000dd0009092220200000000c111111d656667650000000000000000
0000000056565066665656500000000000bbbb0000000000000000000000000000000000000000000090020000000000c111111d650650650000000000000000
00000000565000566500065000000000b000000b000000000000000000000000000000000000000000a00a0000000000cddddddd650000650000000000000000
00000000000650000000000000000000d20d20d2d20d20d200cc0c00000000004b00000098000000600661011006610100444400002222000000000000000000
00000000006765000000000000777700d20dd022d20dd0220c0000c000cccc0043000000a8000000606666016066160104bbbb40028888200000000000000000
00700700006565000000000007ddddd00dd2dd200dd2dd20c00c000c0cddddd0b3000000a900000061671611616716114bb33bb4288aa8820000000000000000
00077000067f6650000000007dd207d20d2cc2200d27722000c0000ccdd20cd2b3000000a900000061671611116116114b3333b428aaaa820000000000000000
0007700006756650000000007d207dd200dd220000dd2200c0000000cd20cdd2b3000000a900000066671611666711114b3333b428aaaa820000000000000000
0070070065666765000000000ddddd200d2d22200d2d2220c000000c0ddddd20b3000000a900000006666610061666104bb33bb4288aa8820000000000000000
000000006506506500000000002222000d0d20200d0d20200c0000c00022220043000000a8000000006611000066110004bbbb40028888200000000000000000
00000000650000650000000000000000000d2000000d200000c0cc00000000004b00000098000000000610000006100000444400002222000000000000000000
00000000000650000006500000000000b000000b80000000300000000660000008800000000000000009900000000000cccccccd000650000000000000000000
0000000000675000000765000000000000bbbb0080000000b0000000633500008aa20000000000009009900400000000c000000d006765000000000000000000
000000000065650000656500000000000b0000b09000000040000000633500008aa20000000550009499994400000000c000000d006565000000000000000000
00000000067f6650067f6650000000000b0bb0b0a000000040000000055000000220000000576d009497744400000000c000000d067f66500000000000000000
000000000675665006756650000000000b0bb0b00000000000000000000000000000000000566d009994444400000000c000000d067566500000000000000000
000000005666657576667650000000000b0000b000000000000000000000000000000000000dd0009099440400000000c000000d656667650000000000000000
0000000056565066665656500000000000bbbb0000000000000000000000000000000000000000000090040000000000c000000d650650650000000000000000
00000000565000566500065000000000b000000b00000000000000000000000000000000000000000090040000000000cddddddd650000650000000000000000
000000000000000000000000000000000000000000a0008000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000090008000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000800a0000000000000000000000000000000000000000000000000000000000000000000000000000000000
@ -1981,12 +1962,12 @@ __gfx__
00000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000cccccccc77000000007700000000770000000077000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000c11ee11d70000000077000000007700000000770000000070000000000000000000000000000000000000000
0000000000000000000000000000000000000000c11ee11d00000000770000000077000000007700000000770000000700000000000000000000000000000000
0000000000000000000000000000000000000000ceeeeeed00000000700000000770000000077000000007700000007700000000000000000000000000000000
0000000000000000000000000000000000000000ceeeeeed00000000000000007700000000770000000077000000077000000007000000000000000000000000
0000000000000000000000000000000000000000c11ee11d00000000000000007000000007700000000770000000770000000077000000000000000000000000
0000000000000000000000000000000000000000c11ee11d00000000000000000000000077000000007700000007700000000770000000070000000000000000
0000000000000000000000000000000000000000c007700d70000000077000000007700000000770000000070000000000000000000000000000000000000000
0000000000000000000000000000000000000000c007800d00000000770000000077000000007700000000770000000700000000000000000000000000000000
0000000000000000000000000000000000000000c777888d00000000700000000770000000077000000007700000007700000000000000000000000000000000
0000000000000000000000000000000000000000c777888d00000000000000007700000000770000000077000000077000000007000000000000000000000000
0000000000000000000000000000000000000000c007800d00000000000000007000000007700000000770000000770000000077000000000000000000000000
0000000000000000000000000000000000000000c008800d00000000000000000000000077000000007700000007700000000770000000070000000000000000
0000000000000000000000000000000000000000cddddddd00000000000000000000000070000000077000000077000000007700000000770000000000000000
cccccccccccc0000cccccccccccc0000cccccccccccc0000cccccccccccc0000cccccccccccc0000cccccccccccc0000cccccccccccc0000cccccccccccc0000
c1111111111d0000c1111111111d0000c1111111111d0000c1111111111d0000c1111111111d0000c111eeee111d0000ceee2222eeed0000c2221111222d0000