Reflection

15th October 2021

Link (seems better for mobile)

A simple demo of a reflection.

  • Press X to enable/disable the reflection effect.
  • Press Z to enable/disable the ripple effect.
  • Use up/down to move the view up and down i.e. change the amount of reflection on the screen.

Uses the extra palette to dim the portion of the screen where the reflection will be.

Draws everything else like normal above the reflection surface. 'memcopy's to the lines below the reflection surface, starting with the line immediately above it.

Adding an offset with some sin() calls moves each line a bit to allow the ripple effect. Downside is a little bit of mess at the edges.

[edit] Minor bug fix to make ripple effect constant with distance from the shore.

-- db_reflection
-- by drakeblue

function _init()
	
	-- set up extended palette for water reflection
	--map each colour to one darker
	pl={[0]=0,0,130,131,132,1,5,6,2,4,9,3,140,5,2,4}
	pal(pl,2)
	poke(0x5f5f,0x10)
	
	reflect=true
	ripple=false
	reflect_depth=32
	pulse=0
	fr=0
	
	set_reflection(reflect_depth)
end

function set_reflection(depth)
	local surface=15-depth\8
	
	memset(0x5f70,0x00,surface)
	
	poke(0x5f70+surface,(0xff<<(8-(depth&0x7))))
	
	memset(0x5f71+surface,0xff,16-surface)
end

function _update60()
	pulse=(pulse+1)%256
	if pulse%8==0 then fr=(fr+1)%3 end
	if btnp(⬆️) then reflect_depth=min(64,reflect_depth+1) set_reflection(reflect_depth) end
	if btnp(⬇️) then reflect_depth=max(reflect_depth-1,1) set_reflection(reflect_depth) end
	
	if btnp(❎) then reflect=not reflect end
	if btnp(🅾️) then ripple=not ripple end
end

function _draw()
	cls(12)
	-- draw background
	map(0,0,-pulse\2,81-reflect_depth,16,4)
	map(0,0,127-pulse\2,81-reflect_depth,16,4)
	for i=0,8 do
		spr(224,i*16-pulse%16,113-reflect_depth,2,2)
	end
	
	-- draw kitten
	spr(fr*3,52,99-reflect_depth,3,2,1)
	
	-- copy lines from just above surface to below surface
	if reflect then
		for i=1,reflect_depth do
			-- sin adds a wiggle to simulate ripples
			local offset=ripple and sin(pulse/50+i/5)*(30+reflect_depth-i)/30+0.5 or 0
			memcpy(0x8000-i*64,0x8000-reflect_depth*128+i*64+offset,64)
		end
	end
	
	print('ripple '..(ripple and 'on' or 'off').." cpu "..stat(1)*100,0,0,7)
end