initial commit.
This commit is contained in:
		
							
								
								
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | # Kistaro's tic-80 compositor | ||||||
|  |  | ||||||
|  | TIC-80 port of my Pico-8 compositor, including a lot of Pico-8 camera and clip behaviors that aren't available in TIC-80.  | ||||||
							
								
								
									
										255
									
								
								kistaro-compositor.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								kistaro-compositor.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,255 @@ | |||||||
|  | -- title:   kistaro-compositor | ||||||
|  | -- author:  Kistaro Windrider (kistaro@gmail.com) | ||||||
|  | -- desc:    Rendering compositor library. Includes Pico-8 camera features. | ||||||
|  | -- site:    https://dragon.style/@kistaro | ||||||
|  | -- license: MIT License | ||||||
|  | -- version: 0.1 | ||||||
|  | -- script:  lua | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function BOOT() | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function TIC() | ||||||
|  | end | ||||||
|  |  | ||||||
|  | --stdlib-- | ||||||
|  |  | ||||||
|  | -- generate standard "overlay" | ||||||
|  | -- constructor for type tt. | ||||||
|  | -- if more is defined, generated | ||||||
|  | -- new calls more(ret) after ret is | ||||||
|  | -- definitely not nil, before calling | ||||||
|  | -- setmetatable. Use to initialize | ||||||
|  | -- mutable items. | ||||||
|  | function MkNew(tt, more) | ||||||
|  | 	local mt = {__index=tt} | ||||||
|  | 	-- check "more" only once ever | ||||||
|  | 	if more then | ||||||
|  | 	 tt.new = function(ret) | ||||||
|  | 		 ret = ret or {} | ||||||
|  | 			more(ret) | ||||||
|  | 			setmetatable(ret, mt) | ||||||
|  | 			return ret | ||||||
|  | 		end | ||||||
|  | 	else | ||||||
|  | 	 tt.new = function(ret) | ||||||
|  | 	 	ret = ret or {} | ||||||
|  | 	 	setmetatable(ret, mt) | ||||||
|  | 	  return ret | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | --Window compositor-- | ||||||
|  |  | ||||||
|  | CamCtl = { | ||||||
|  |  XOff = 0, | ||||||
|  |  YOff = 0, | ||||||
|  |  XAbsClip = 0, | ||||||
|  |  YAbsClip = 0, | ||||||
|  |  W = 240, | ||||||
|  |  H = 136, | ||||||
|  |  OriginStack = {}, | ||||||
|  |  ClipStack = {}, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | -- Overwrite current camera origin. | ||||||
|  | -- (0, 0) is now this pixel coordinate. | ||||||
|  | function CamCtl:SetAbsOrigin(x, y) | ||||||
|  |  self.XOff, self.YOff = x, y | ||||||
|  | end | ||||||
|  |  | ||||||
|  | -- Push current camera origin onto | ||||||
|  | -- the history stack and set the | ||||||
|  | -- new origin. | ||||||
|  | function CamCtl:PushAbsOrigin(x, y) | ||||||
|  |  table.insert(self.OriginStack, {self.XOff, self.YOff}) | ||||||
|  |  self.XOff, self.YOff = x, y | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:SetRelOrigin(x, y) | ||||||
|  |  self.XOff = self.XOff + x | ||||||
|  |  self.YOff = self.Yoff + y | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:PushRelOrigin(x, y) | ||||||
|  |  table.insert(self.OriginStack, {self.XOff, self.YOff}) | ||||||
|  |  self.XOff = self.XOff + x | ||||||
|  |  self.YOff = self.YOff + Y | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:SetAbsCam(x, y) | ||||||
|  |  self.XOff, self.YOff = -x, -y | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:PushAbsCam(x, y) | ||||||
|  |  table.insert(self.OriginStack, {self.XOff, self.YOff}) | ||||||
|  |  self.XOff, self.YOff = -x, -y | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:SetRelCam(x, y) | ||||||
|  |  self.XOff = self.XOff - x | ||||||
|  |  self.YOff = self.YOff - y | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:PushRelCam(x, y) | ||||||
|  |  table.insert(self.OriginStack, {self.XOff, self.YOff}) | ||||||
|  |  self.XOff = self.XOff - x | ||||||
|  |  self.YOff = self.YOff - y | ||||||
|  | end  | ||||||
|  |  | ||||||
|  | function CamCtl:PopOrigin() | ||||||
|  |  if #self.OriginStack == 0 then | ||||||
|  |   self.XOff, self.YOff = 0, 0 | ||||||
|  |   return | ||||||
|  |  end | ||||||
|  |  self.XOff, self.YOff = unpack(table.Remove(self.OriginStack)) | ||||||
|  | end | ||||||
|  | CamCtl.PopCam = CamCtl.PopOrigin | ||||||
|  |  | ||||||
|  | function CamCtl:SetNewClip(x, y, w, h) | ||||||
|  |  if x then | ||||||
|  |   self.XAbsClip = self.XOff + x | ||||||
|  |   self.YAbsClip = self.YOff + y | ||||||
|  |   self.W, self.H = w, h | ||||||
|  |   clip(self.XAbsClip, self.YAbsClip, self.W, self.H) | ||||||
|  |   return | ||||||
|  |  end | ||||||
|  |  self.XAbsClip, self.YAbsClip, self.W, self.H = 0,0,240,136 | ||||||
|  |  clip() | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:PushNewClip(x, y, w, h) | ||||||
|  |  table.insert(self.ClipStack, {self.XAbsClip, self.YAbsClip, self.W, self.H} | ||||||
|  |  self:SetNewClip(x, y, w, h) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:SetReClip(x,y,w,h) | ||||||
|  |  if not x then | ||||||
|  |   return | ||||||
|  |  end | ||||||
|  |   | ||||||
|  |  x = x + self.XOff | ||||||
|  |  local x2 = math.min(x + w, self.XAbsClip + self.W) | ||||||
|  |  self.XAbsClip = math.max(x, self.XAbsClip) | ||||||
|  |  self.W = max(0, x2 - self.XAbsClip) | ||||||
|  |   | ||||||
|  |  y = y + self.YOff | ||||||
|  |  local y2 = math.min(y+h, self.YAbsClip + self.H) | ||||||
|  |  self.YAbsClip = math.max(y, self.YAbsClip) | ||||||
|  |  self.H = max(0, y2 - self.YAbsClip) | ||||||
|  |  | ||||||
|  |  clip(self.XAbsClip, self.YAbsClip, self.W, self.H) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:PushReClip(x,y,w,h) | ||||||
|  |  table.insert(self.ClipStack, {self.XAbsClip, self.YAbsClip, self.W, self.H} | ||||||
|  |  self.SetReClip(x,y,w,h) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function CamCtl:PopClip() | ||||||
|  |  if #self.ClipStack == 0 then | ||||||
|  |   self.XAbsClip, self.YAbsClip, self.W, self.H = 0,0,240,136 | ||||||
|  |   clip() | ||||||
|  |   return | ||||||
|  |  end | ||||||
|  |  local x,y,w,h = unpack(table.remove(self.ClipStack))) | ||||||
|  |  self.XAbsClip, self.YAbsClip, self.W, self.H = x,y,w,h | ||||||
|  |  clip(x,y,w,h) | ||||||
|  | end | ||||||
|  | -- Install | ||||||
|  | -- (swizzle all drawing functions!) | ||||||
|  |  | ||||||
|  | function CamCtl:Install() | ||||||
|  |  local adjust_leading_2 = { | ||||||
|  |   "circ", "circb", | ||||||
|  |   "elli", "ellib", | ||||||
|  |   "pix", | ||||||
|  |   "rect", "rectb", | ||||||
|  |  } | ||||||
|  |  for _, fn in ipairs(adjust_leading_2) do | ||||||
|  |   local f_orig = _G[fn] | ||||||
|  |   _G[fn] = function(x, y, ...) | ||||||
|  |    return f_orig(x + self.XOff, y + self.YOff, ...) | ||||||
|  |   end | ||||||
|  |  end | ||||||
|  |   | ||||||
|  |  local keep_first_adjust_2_opt = { | ||||||
|  |   "spr", "font", "print" | ||||||
|  |  } | ||||||
|  |  for _, fn in ipairs(keep_first_adjust_2_opt) do | ||||||
|  |   local f_orig = _G[fn] | ||||||
|  |   _G[fn] = function(v, x, y, ...) | ||||||
|  |    if x then | ||||||
|  |     x = x + self.XOff | ||||||
|  |    end | ||||||
|  |    if y then | ||||||
|  |     y = y + self.YOff | ||||||
|  |    end | ||||||
|  |    return f_orig(v, x, y, ...) | ||||||
|  |   end | ||||||
|  |  end | ||||||
|  |  | ||||||
|  |  local tri_family = {"tri", "trib", "textri"} | ||||||
|  |   | ||||||
|  |  for _, fn in ipairs(tri_family) do | ||||||
|  |   local f_orig = _G[fn] | ||||||
|  |   _G[fn] = function(x1, y1, x2, y2, x3, y3, ...) | ||||||
|  |    return f_orig( | ||||||
|  |     x1 + self.XOff, y1 + self.YOff, | ||||||
|  |     x2 + self.XOff, y2 + self.YOff, | ||||||
|  |     x3 + self.XOff, y3 + self.YOff, | ||||||
|  |     ... | ||||||
|  |    ) | ||||||
|  |   end | ||||||
|  |  end | ||||||
|  |   | ||||||
|  |  local map_orig = map | ||||||
|  |  map = function(mx, my, w, h, sx, sy, ...) | ||||||
|  |   XXX(kistaro): implement! | ||||||
|  |   -- if called with no args, calculate new map | ||||||
|  |   -- coordinates, clipping at 0, to respect | ||||||
|  |   -- camera movement! this will require full tile | ||||||
|  |   -- movement to be reflected in mx/my, w and h to | ||||||
|  |   -- stay 30 x 17 unless they go to 31 x 18 for | ||||||
|  |   -- partial tiles at edges, and sx and sy to become | ||||||
|  |   -- offsets. If sx and sy are provided, do the | ||||||
|  |   -- obvious thing instead, which is much easier. | ||||||
|  |  end | ||||||
|  |   | ||||||
|  |  local line_orig = line | ||||||
|  |  line = function(x0, y0, x1, y1, color) | ||||||
|  |   return line_orig( | ||||||
|  |    x0 + self.XOff, y0 + self.YOff, | ||||||
|  |    x1 + self.XOff, y1 + self.YOff, | ||||||
|  |    color | ||||||
|  |   ) | ||||||
|  |  end | ||||||
|  | end | ||||||
|  | -- <SPRITES> | ||||||
|  | -- 000:0222220021111110212121102122211021121110211111100111110000000000 | ||||||
|  | -- 001:0bbbbb00b9999980b999b980b99bb980b9bbb980b99999800888880000000000 | ||||||
|  | -- 002:0555550056666670565566705655567056655670566666700777770000000000 | ||||||
|  | -- 003:0444440043333320433433204344432043434320433333200222220000000000 | ||||||
|  | -- 004:0ddddd00deeeeef0dededef0deedeef0dededef0deeeeef00fffff0000000000 | ||||||
|  | -- </SPRITES> | ||||||
|  |  | ||||||
|  | -- <WAVES> | ||||||
|  | -- 000:00000000ffffffff00000000ffffffff | ||||||
|  | -- 001:0123456789abcdeffedcba9876543210 | ||||||
|  | -- 002:0123456789abcdef0123456789abcdef | ||||||
|  | -- </WAVES> | ||||||
|  |  | ||||||
|  | -- <SFX> | ||||||
|  | -- 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000 | ||||||
|  | -- </SFX> | ||||||
|  |  | ||||||
|  | -- <TRACKS> | ||||||
|  | -- 000:100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||||
|  | -- </TRACKS> | ||||||
|  |  | ||||||
|  | -- <PALETTE> | ||||||
|  | -- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f4be69ce61309940205d | ||||||
|  | -- </PALETTE> | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								kistaro-compositor.tic
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kistaro-compositor.tic
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user