mirror of
https://github.com/zenith391/OCEmu.git
synced 2025-09-28 07:24:22 -04:00
Various fixes
Unicode: Replace \0 with \xC0\x80 Limit max codepoint to 0xFFFF (Java chars are wonderful) Fix wtrunc and math.huge Fix wtrunc with a pos of 0 returning the entire string GPU (not screen): Simplify rdepthTbl Add depth names table return the old depth when changing depth limit the resolution change correctly allow gpu.get to work with a little over the max dimensions Screen: Don't modify characters if it's a wide character at the very edge of the screen Have getColor set the palette index instead Return true in cec.fill Floor the resolution when changing
This commit is contained in:
parent
618504f9cd
commit
95405445d9
@ -3,12 +3,20 @@ local env = ...
|
||||
local utf8 = require("utf8")
|
||||
|
||||
env.unicode = {
|
||||
char = utf8.char,
|
||||
len = utf8.len,
|
||||
reverse = utf8.reverse,
|
||||
sub = utf8.sub,
|
||||
}
|
||||
|
||||
function env.unicode.char(...)
|
||||
cprint("unicode.char", ...)
|
||||
local args = table.pack(...)
|
||||
for i = 1,args.n do
|
||||
checkArg(i,args[i],"number")
|
||||
args[i] = args[i]%0x10000
|
||||
end
|
||||
return utf8.char(table.unpack(args)):gsub("%z","\xC0\x80") .. ""
|
||||
end
|
||||
function env.unicode.lower(str)
|
||||
cprint("unicode.lower", str)
|
||||
if type(str) == "number" then str = tostring(str) end
|
||||
@ -52,6 +60,9 @@ function env.unicode.wtrunc(str, count)
|
||||
cprint("unicode.wtrunc", str, count)
|
||||
checkArg(1,str,"string")
|
||||
checkArg(2,count,"number")
|
||||
if count == math.huge then
|
||||
count = 0
|
||||
end
|
||||
local width = 0
|
||||
local pos = 0
|
||||
local len = utf8.len(str)
|
||||
@ -62,5 +73,5 @@ function env.unicode.wtrunc(str, count)
|
||||
end
|
||||
width = width + getCharWidth(utf8.byte(str,pos,pos))
|
||||
end
|
||||
return utf8.sub(str, 1, pos-1)
|
||||
return utf8.sub(str, 1, math.max(pos-1,0))
|
||||
end
|
||||
|
@ -7,7 +7,8 @@ local lua_utf8 = require("utf8")
|
||||
|
||||
local bindaddress
|
||||
local depthTbl = {1,4,8}
|
||||
local rdepthTbl = {1,nil,nil,2,nil,nil,nil,3}
|
||||
local rdepthTbl = {1,[4]=2,[8]=3}
|
||||
local depthNames = {"OneBit","FourBit","EightBit"}
|
||||
|
||||
-- gpu component
|
||||
local obj = {}
|
||||
@ -82,7 +83,9 @@ function obj.setDepth(depth) -- Set the color depth. Returns the previous value.
|
||||
if rdepthTbl[depth] == nil or rdepthTbl[depth] > math.max(scrmax, maxtier) then
|
||||
error("unsupported depth",3)
|
||||
end
|
||||
return component.cecinvoke(bindaddress, "setDepth", rdepthTbl[depth])
|
||||
local old = depthNames[component.cecinvoke(bindaddress, "getDepth")]
|
||||
component.cecinvoke(bindaddress, "setDepth", rdepthTbl[depth])
|
||||
return old
|
||||
end
|
||||
function obj.maxDepth() -- Get the maximum supported color depth.
|
||||
cprint("gpu.maxDepth")
|
||||
@ -121,6 +124,11 @@ function obj.setResolution(width, height) -- Set the screen resolution. Returns
|
||||
if bindaddress == nil then
|
||||
return nil, "no screen"
|
||||
end
|
||||
local smw,smh = component.cecinvoke(bindaddress, "maxResolution")
|
||||
smw,smh = math.min(smw,maxwidth),math.min(smh,maxheight)
|
||||
if width <= 0 or width >= smw + 1 or height <= 0 or height >= smh + 1 then
|
||||
error("unsupported resolution",3)
|
||||
end
|
||||
return component.cecinvoke(bindaddress, "setResolution", width, height)
|
||||
end
|
||||
function obj.maxResolution() -- Get the maximum screen resolution.
|
||||
@ -170,7 +178,7 @@ function obj.get(x, y) -- Get the value displayed on the screen at the specified
|
||||
return nil, "no screen"
|
||||
end
|
||||
local w,h = component.cecinvoke(bindaddress, "getResolution")
|
||||
if x < 1 or x > w or y < 1 or y > h then
|
||||
if x < 1 or x >= w+1 or y < 1 or y >= h+1 then
|
||||
error("index out of bounds",3)
|
||||
end
|
||||
return component.cecinvoke(bindaddress, "get", x, y)
|
||||
|
@ -172,20 +172,22 @@ end
|
||||
local function setPos(x,y,c,fg,bg)
|
||||
local renderchange = screen.txt[y][x] ~= utf8.char(c) or screen.bg[y][x] ~= scrbgc or (screen.txt[y][x] ~= " " and screen.fg[y][x] ~= scrfgc)
|
||||
local charWidth = getCharWidth(c)
|
||||
local renderafter = getCharWidth(utf8.byte(screen.txt[y][x])) > 1 and charWidth == 1 and x < width
|
||||
if x > 1 and getCharWidth(utf8.byte(screen.txt[y][x-1])) > 1 then
|
||||
renderchange = false
|
||||
else
|
||||
screenSet(x,y,c)
|
||||
end
|
||||
if renderchange then
|
||||
renderChar(c,(x-1)*8,(y-1)*16,fg,bg)
|
||||
if charWidth > 1 and x < width then
|
||||
screenSet(x+1,y,32)
|
||||
if charWidth == 1 or x < width then
|
||||
local renderafter = getCharWidth(utf8.byte(screen.txt[y][x])) > 1 and charWidth == 1 and x < width
|
||||
if x > 1 and getCharWidth(utf8.byte(screen.txt[y][x-1])) > 1 then
|
||||
renderchange = false
|
||||
else
|
||||
screenSet(x,y,c)
|
||||
end
|
||||
if renderchange then
|
||||
renderChar(c,(x-1)*8,(y-1)*16,fg,bg)
|
||||
if charWidth > 1 then
|
||||
screenSet(x+1,y,32)
|
||||
end
|
||||
end
|
||||
if renderafter then
|
||||
renderChar(32,x*8,(y-1)*16,screen.fg[y][x+1],screen.bg[y][x+1])
|
||||
end
|
||||
end
|
||||
if renderafter then
|
||||
renderChar(32,x*8,(y-1)*16,screen.fg[y][x+1],screen.bg[y][x+1])
|
||||
end
|
||||
end
|
||||
|
||||
@ -214,7 +216,12 @@ local function searchPalette(value)
|
||||
return index, score
|
||||
end
|
||||
|
||||
local function getColor(value)
|
||||
local function getColor(value, sel)
|
||||
if sel then
|
||||
scrfgp = nil
|
||||
else
|
||||
scrbgp = nil
|
||||
end
|
||||
if tier == 3 then
|
||||
local pi,ps = searchPalette(value)
|
||||
local r,g,b = extract(value)
|
||||
@ -226,10 +233,21 @@ local function getColor(value)
|
||||
if defs < ps then
|
||||
return defc
|
||||
else
|
||||
if sel then
|
||||
scrfgp = pi
|
||||
else
|
||||
scrbgp = pi
|
||||
end
|
||||
return palcol[pi]
|
||||
end
|
||||
elseif tier == 2 then
|
||||
return palcol[searchPalette(value)]
|
||||
local pi = searchPalette(value)
|
||||
if sel then
|
||||
scrfgp = pi
|
||||
else
|
||||
scrbgp = pi
|
||||
end
|
||||
return palcol[pi]
|
||||
else
|
||||
if value > 0 then
|
||||
return 0xFFFFFF -- TODO: Configuration color
|
||||
@ -303,8 +321,8 @@ function cec.setForeground(value, palette) -- Sets the foreground color to the s
|
||||
cprint("(cec) screen.setForeground", value, palette)
|
||||
local oldc, oldp = scrrfc, scrfgp
|
||||
scrrfc = palette and palcol[value] or value
|
||||
scrfgc = palette and scrrfc or getColor(scrrfc)
|
||||
scrfgp = palette and value
|
||||
scrfgc = palette and scrrfc or getColor(scrrfc,true)
|
||||
return oldc, oldp
|
||||
end
|
||||
function cec.getBackground() -- Get the current background color and whether it's from the palette or not.
|
||||
@ -315,8 +333,8 @@ function cec.setBackground(value, palette) -- Sets the background color to the s
|
||||
cprint("(cec) screen.setBackground", value, palette)
|
||||
local oldc, oldp = scrrbc, scrbgp
|
||||
scrrbc = palette and palcol[value] or value
|
||||
scrbgc = palette and scrrbc or getColor(scrrbc)
|
||||
scrbgp = palette and value
|
||||
scrbgc = palette and scrrbc or getColor(scrrbc,false)
|
||||
return oldc, oldp
|
||||
end
|
||||
function cec.getDepth() -- Returns the currently set color depth.
|
||||
@ -329,8 +347,8 @@ function cec.setDepth(depth) -- Set the color depth. Returns the previous value.
|
||||
if tier > 1 then
|
||||
loadPalette()
|
||||
end
|
||||
scrfgc = getColor(scrrfc)
|
||||
scrfbc = getColor(scrrbc)
|
||||
scrfgc = getColor(scrrfc,true)
|
||||
scrfbc = getColor(scrrbc,false)
|
||||
-- TODO: Lowering the depth recolors the entire screen
|
||||
end
|
||||
function cec.maxDepth() -- Get the maximum supported color depth.
|
||||
@ -355,6 +373,7 @@ function cec.fill(x1, y1, w, h, char) -- Fills a portion of the screen at the sp
|
||||
setPos(x,y,code,scrfgc,scrbgc)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
function cec.getResolution() -- Get the current screen resolution.
|
||||
cprint("(cec) screen.getResolution")
|
||||
@ -362,8 +381,9 @@ function cec.getResolution() -- Get the current screen resolution.
|
||||
end
|
||||
function cec.setResolution(newwidth, newheight) -- Set the screen resolution. Returns true if the resolution changed.
|
||||
cprint("(cec) screen.setResolution", newwidth, newheight)
|
||||
newwidth,newheight = math.floor(newwidth),math.floor(newheight)
|
||||
local oldwidth, oldheight = width, height
|
||||
width, height = math.min(newwidth, maxwidth), math.min(newheight, maxheight)
|
||||
width, height = newwidth, newheight
|
||||
return oldwidth ~= width or oldheight ~= height
|
||||
end
|
||||
function cec.maxResolution() -- Get the maximum screen resolution.
|
||||
@ -444,8 +464,10 @@ function cec.copy(x1, y1, w, h, tx, ty) -- Copies a portion of the screen from t
|
||||
copy.bgp[y-y1][x-x1] = screen.bgp[y][x]
|
||||
end
|
||||
end
|
||||
for y = math.max(math.min(y1+ty, height), 1), math.max(math.min(y2+ty, height), 1) do
|
||||
for x = math.max(math.min(x1+tx, width), 1), math.max(math.min(x2+tx, width), 1) do
|
||||
local my1,my2 = math.max(math.min(y1+ty, height), 1), math.max(math.min(y2+ty, height), 1)
|
||||
local mx1,mx2 = math.max(math.min(x1+tx, width), 1), math.max(math.min(x2+tx, width), 1)
|
||||
for y = my1,my2 do
|
||||
for x = mx1,mx2 do
|
||||
screen.txt[y][x] = copy.txt[y-y1-ty][x-x1-tx]
|
||||
screen.fg[y][x] = copy.fg[y-y1-ty][x-x1-tx]
|
||||
screen.bg[y][x] = copy.bg[y-y1-ty][x-x1-tx]
|
||||
|
Loading…
x
Reference in New Issue
Block a user