Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
PSprites — Gideros Forum

PSprites

This is a couple of classes to add Palettes and Palette Sprites to Gideros.
--!NEEDS:luashader/luashader.lua
 
Palettes=Core.class()
function Palettes:init(d)
	self.texture=RenderTarget.new(256,256)	-- 256 palettes of 256 colours
	if d then stage:addChild(Bitmap.new(self.texture)) end
end
 
function Palettes:exit()
	self.texture=nil
end
 
function Palettes:getBase()
	return self.texture
end
 
function Palettes:setColor(p,c,rgb,a)
	if self.texture then
		local alpha=a or 1
		if type(rgb)=="table" then
			local t=self.texture
			for loop=1,#rgb do
				t:clear(rgb[loop],alpha,c&0xff,p&0xff,1,1)
				c+=1
			end
		else
			self.texture:clear(rgb,alpha,c&0xff,p&0xff,1,1)
		end
	end
end
 
function Palettes:getColor(p,c,l)
	if self.texture then
		if l==nil then
			return self.texture:getPixel(c&0xff,p&0xff)
		else
			local t=self.texture
			local rgb,a=t:getPixel(c&0xff,p&0xff)
			l-=1
			c+=1
			local p={rgb}
			for loop=1,l do
				p[#p+1]=t:getPixel(c&0xff,p&0xff)
				c+=1
			end
			return p,a
		end	
	end
end
 
function Palettes:setColors(p,c,rgb)
	if self.texture then
		local t=self.texture
		for loop=1,#rgb do
			self.texture:clear(rgb[loop,1],rgb[loop,2],c&0xff,p&0xff,1,1)
			c+=1
		end
	end
end
 
function Palettes:getColors(p,c,l)
	local p={}
	if self.texture then
		local t=self.texture
 
		for loop=1,l do
			p[loop]={t:getPixel(c&0xff,p&0xff)}
			c+=1
		end
	end
	return p	
end
 
local function vertex(vVertex,vColor,vTexCoord)
	local vertex = hF4(vVertex,0.0,1.0)
	fTexCoord=vTexCoord
	return vMatrix*vertex
end
 
local function fragment()
	local colour8=texture2D(fTexture,fTexCoord)
	local index=lF2(colour8.r,fPalette)
	local frag=texture2D(fPalettes,index)
	if (frag.a==0.0) then discard() end
	return frag
end
 
local shader=Shader.lua(vertex,fragment,0,{
			{name="vMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WVP,vertex=true},
			{name="fColor",type=Shader.CFLOAT4,sys=Shader.SYS_COLOR,vertex=false},
			{name="fTexture",type=Shader.CTEXTURE,vertex=false},
			{name="fPalettes",type=Shader.CTEXTURE,vertex=false},
			{name="fPalette",type=Shader.CFLOAT2,vertex=false},
			},
			{
			{name="vVertex",type=Shader.DFLOAT,mult=2,slot=0,offset=0},
			{name="vColor",type=Shader.DUBYTE,mult=0,slot=1,offset=0},
			{name="vTexCoord",type=Shader.DFLOAT,mult=2,slot=2,offset=0},
			},
			{
			{name="fTexCoord",type=Shader.CFLOAT2},
			}
			)
 
PSprite=Core.class(Sprite)
function PSprite:init(b,w,h,f,r)
	self.w=w
	self.h=h
	self.base=b:getBase()
	self.palette=0
	local texture=RenderTarget.new(w,h,f,r,false,false,TextureBase.Y8)
	self.texture=texture
	texture:clear(0x800000,1)
	local pixel=Pixel.new(texture)
	self.pixel=pixel
	pixel:setTexture(self.base,1)
	pixel:setShader(shader)
	self.pixel:setShaderConstant("fPalette",Shader.CFLOAT,1,0)
	self:addChild(pixel)
end
 
function PSprite:exit()
	self.pixel=nil
	self.texture=nil
end
 
function PSprite:setBase(b)
	if self.base~=b then
		self.base=b
		self.pixel:setTexture(self.base,1)
	end
end
 
function PSprite:getBase()
	return self.base
end
 
function PSprite:setPalette(p)
	if self.palette~=p then
		self.palette=p
		self.pixel:setShaderConstant("fPalette",Shader.CFLOAT,1,p&0xff)
	end
end
 
function PSprite:getPalette()
	return self.palette
end
 
function PSprite:clear(c)
	self.texture:clear(((c or 0)&0xff)<<16,1)
end
 
function PSprite:setPixel(x,y,c)
	self.texture:clear(((c or 0)&0xff)<<16,1,x,y,1,1)
end
 
application:setBackgroundColor(0x000000)
application:setKeepAwake(true)
 
palettes=Palettes.new(true)
local p={}
for loop=0,255 do
	p[#p+1]=math.random(0xffffff)
end
 
palettes:setColor(0,0,p)
 
pSprite=PSprite.new(palettes,256,256)
 
stage:addChild(pSprite)
for y=0,255 do
	for x=0,255 do
		pSprite:setPixel(x,y,x)  -- set the palette colour to the same value as x
	end
end</pre>
The sprites are up to 256 colours each. You can set the pixels for the sprites using setPixel(x,y,c)

c is a colour index into a palette.

These are the type of sprites on classic arcade machines, consoles, etc - such as the NES, SNES, Megadrive, etc...

You can do things like have the same graphic object, but display it in different palettes. eg red jewels, green jewels, etc...

eg, for a fighting game, you can have one graphic and use palettes to recolour it.


Likes: MoKaLux, E1e5en

Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
https://deluxepixel.com
+1 -1 (+2 / -0 )Share on Facebook

Comments

Sign In or Register to comment.