local disp_common = require("disp_common") -- a vlorb consists of six gromlings[A -- 1 2 -- 4 8 -- 16 Q -- these are characters 0x80 through 0x9f in the cc charset -- which is only 2^5 characters though. for the sixth bit you flip the colours -- of that vlorb. -- on colour, off colour, gromlings 1 through 6 (bools) -- returns text colour, bg color, and vlorbchar local function vlorb(onc,offc, g1,g2,g3,g4,g5,g6) local textc,bgc = onc,offc if g6 then textc,bgc=bgc,textc end local vlorbchar = 0x80 -- ~= on booleans is xor -- if g6 set then flip all the other bits if g1 ~= g6 then vlorbchar=vlorbchar+1 end if g2 ~= g6 then vlorbchar=vlorbchar+2 end if g3 ~= g6 then vlorbchar=vlorbchar+4 end if g4 ~= g6 then vlorbchar=vlorbchar+8 end if g5 ~= g6 then vlorbchar=vlorbchar+16 end return textc,bgc,string.char(vlorbchar) end local function all_palette_distances(R) local out = {} for a=0,15 do local ia=2^a out[ia] = {} for b = 0,15 do local ib=2^b local ca = {R.getPaletteColor(ia)} local cb = {R.getPaletteColor(ib)} local dist = disp_common.color_dist(ca,cb) out[ia][ib] = dist end end return out end local function list_contains(list,val) for _,v in ipairs(list) do if v == val then return true end end return false end -- R, lPx_gromlings, l_pdists -> lCx_gromlings local function adjust_to_2_colors(R,gromlings,pdists) -- gromlings goes 1 2 3 4 5 6 -- compress the 6 pixels to just 2 colors -- return the list of cidxs local gromling_colors = {} for i,c in ipairs(gromlings) do local cx = disp_common.closest_palette_color(R,c) gromling_colors[i] = cx end local all_current_colors = {} local ncolors = 0 for _,cidx in ipairs(gromling_colors) do if not all_current_colors[cidx] then ncolors = ncolors + 1 end all_current_colors[cidx] = true end while ncolors > 2 do -- print("- ncolors is "..ncolors) -- io.write("all_current_colors: ") -- for k in pairs(all_current_colors) do io.write(k," ") end -- io.write("\ngromling_colors: ") -- for k,v in pairs(gromling_colors) do print(k,v) end --print() -- merge closest two colors until there are only 2 distinct ones left local best_dist = 9999 local best_a = nil local best_b = nil for a in pairs(all_current_colors) do for b in pairs(all_current_colors) do if a ~= b then local dist = pdists[a][b] assert(dist) if dist < best_dist then best_dist = dist best_a = a best_b = b end end end end -- todo: be cleverer when deciding whether to merge a into b, or b into a -- currently just merge b into a assert(best_a,"no best_a") assert(best_b,"no best_b") assert(best_a ~= best_b,"best a and b are the same") --print("mergng "..best_b.." into "..best_a) all_current_colors[best_b] = nil ncolors=ncolors-1 for gidx,col in ipairs(gromling_colors) do if col == best_b then gromling_colors[gidx] = best_a end end end --print("-#-- ncolors is "..ncolors) --io.write("all_current_colors: ") --for k in pairs(all_current_colors) do io.write(k," ") end --io.write("\ngromling_colors: ") --for k,v in pairs(gromling_colors) do print(k,v) end --print() return gromling_colors end local function gromling_list_to_vlorb(gromling_colors) -- takes list of cidxs local ca = nil local cb = nil local gs = {} for i,col in ipairs(gromling_colors) do if col == ca then gs[i] = true elseif col == cb then gs[i] = false else if not ca then ca = col gs[i] = true elseif not cb then cb = col gs[i] = false else error("third gromling color in vlorb") end end end return ca,cb or colors.black,table.unpack(gs) end -- todo: refactor common stuff into a common file local function disp(R,img,scrx,scry,w,h,imgx,imgy) -- w and h are image coords scrx = scrx or 1 scry = scry or 1 w = w or img.width h = h or img.width imgx = imgx or 1 imgy = imgy or 1 disp_common.improve_palette(R,img,w,h,imgx,imgy) local pdists=all_palette_distances(R) local sw = math.ceil(w/2) local sh = math.ceil(h/3) for soffx=0,sw do for soffy=0,sh do local ioffx=soffx*2 local ioffy=soffy*3 R.setCursorPos(scrx+soffx,scry+soffy) local lPx_gromlings = {} for goffy=0,2 do for goffx=0,1 do local px = img[imgy+ioffy+goffy][imgx+ioffx+goffx] or {0,0,0} table.insert(lPx_gromlings,px) end end local lCx_gromlings = adjust_to_2_colors(R,lPx_gromlings,pdists) -- for k,v in ipairs(lCx_gromlings) do print("thethe",k,v) end local vlorbdf = {gromling_list_to_vlorb(lCx_gromlings)} -- for k,v in ipairs(vlorbdf) do print("ehteht",k,v) end local textc,bgc,vlorbchar = vlorb(table.unpack(vlorbdf)) R.setTextColor(textc) R.setBackgroundColor(bgc) R.write(vlorbchar) end end end return {vlorb=vlorb,disp=disp}