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")
|
local utf8 = require("utf8")
|
||||||
|
|
||||||
env.unicode = {
|
env.unicode = {
|
||||||
char = utf8.char,
|
|
||||||
len = utf8.len,
|
len = utf8.len,
|
||||||
reverse = utf8.reverse,
|
reverse = utf8.reverse,
|
||||||
sub = utf8.sub,
|
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)
|
function env.unicode.lower(str)
|
||||||
cprint("unicode.lower", str)
|
cprint("unicode.lower", str)
|
||||||
if type(str) == "number" then str = tostring(str) end
|
if type(str) == "number" then str = tostring(str) end
|
||||||
@ -52,6 +60,9 @@ function env.unicode.wtrunc(str, count)
|
|||||||
cprint("unicode.wtrunc", str, count)
|
cprint("unicode.wtrunc", str, count)
|
||||||
checkArg(1,str,"string")
|
checkArg(1,str,"string")
|
||||||
checkArg(2,count,"number")
|
checkArg(2,count,"number")
|
||||||
|
if count == math.huge then
|
||||||
|
count = 0
|
||||||
|
end
|
||||||
local width = 0
|
local width = 0
|
||||||
local pos = 0
|
local pos = 0
|
||||||
local len = utf8.len(str)
|
local len = utf8.len(str)
|
||||||
@ -62,5 +73,5 @@ function env.unicode.wtrunc(str, count)
|
|||||||
end
|
end
|
||||||
width = width + getCharWidth(utf8.byte(str,pos,pos))
|
width = width + getCharWidth(utf8.byte(str,pos,pos))
|
||||||
end
|
end
|
||||||
return utf8.sub(str, 1, pos-1)
|
return utf8.sub(str, 1, math.max(pos-1,0))
|
||||||
end
|
end
|
||||||
|
@ -7,7 +7,8 @@ local lua_utf8 = require("utf8")
|
|||||||
|
|
||||||
local bindaddress
|
local bindaddress
|
||||||
local depthTbl = {1,4,8}
|
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
|
-- gpu component
|
||||||
local obj = {}
|
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
|
if rdepthTbl[depth] == nil or rdepthTbl[depth] > math.max(scrmax, maxtier) then
|
||||||
error("unsupported depth",3)
|
error("unsupported depth",3)
|
||||||
end
|
end
|
||||||
return component.cecinvoke(bindaddress, "setDepth", rdepthTbl[depth])
|
local old = depthNames[component.cecinvoke(bindaddress, "getDepth")]
|
||||||
|
component.cecinvoke(bindaddress, "setDepth", rdepthTbl[depth])
|
||||||
|
return old
|
||||||
end
|
end
|
||||||
function obj.maxDepth() -- Get the maximum supported color depth.
|
function obj.maxDepth() -- Get the maximum supported color depth.
|
||||||
cprint("gpu.maxDepth")
|
cprint("gpu.maxDepth")
|
||||||
@ -121,6 +124,11 @@ function obj.setResolution(width, height) -- Set the screen resolution. Returns
|
|||||||
if bindaddress == nil then
|
if bindaddress == nil then
|
||||||
return nil, "no screen"
|
return nil, "no screen"
|
||||||
end
|
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)
|
return component.cecinvoke(bindaddress, "setResolution", width, height)
|
||||||
end
|
end
|
||||||
function obj.maxResolution() -- Get the maximum screen resolution.
|
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"
|
return nil, "no screen"
|
||||||
end
|
end
|
||||||
local w,h = component.cecinvoke(bindaddress, "getResolution")
|
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)
|
error("index out of bounds",3)
|
||||||
end
|
end
|
||||||
return component.cecinvoke(bindaddress, "get", x, y)
|
return component.cecinvoke(bindaddress, "get", x, y)
|
||||||
|
@ -172,20 +172,22 @@ end
|
|||||||
local function setPos(x,y,c,fg,bg)
|
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 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 charWidth = getCharWidth(c)
|
||||||
local renderafter = getCharWidth(utf8.byte(screen.txt[y][x])) > 1 and charWidth == 1 and x < width
|
if charWidth == 1 or x < width then
|
||||||
if x > 1 and getCharWidth(utf8.byte(screen.txt[y][x-1])) > 1 then
|
local renderafter = getCharWidth(utf8.byte(screen.txt[y][x])) > 1 and charWidth == 1 and x < width
|
||||||
renderchange = false
|
if x > 1 and getCharWidth(utf8.byte(screen.txt[y][x-1])) > 1 then
|
||||||
else
|
renderchange = false
|
||||||
screenSet(x,y,c)
|
else
|
||||||
end
|
screenSet(x,y,c)
|
||||||
if renderchange then
|
end
|
||||||
renderChar(c,(x-1)*8,(y-1)*16,fg,bg)
|
if renderchange then
|
||||||
if charWidth > 1 and x < width then
|
renderChar(c,(x-1)*8,(y-1)*16,fg,bg)
|
||||||
screenSet(x+1,y,32)
|
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
|
||||||
end
|
|
||||||
if renderafter then
|
|
||||||
renderChar(32,x*8,(y-1)*16,screen.fg[y][x+1],screen.bg[y][x+1])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -214,7 +216,12 @@ local function searchPalette(value)
|
|||||||
return index, score
|
return index, score
|
||||||
end
|
end
|
||||||
|
|
||||||
local function getColor(value)
|
local function getColor(value, sel)
|
||||||
|
if sel then
|
||||||
|
scrfgp = nil
|
||||||
|
else
|
||||||
|
scrbgp = nil
|
||||||
|
end
|
||||||
if tier == 3 then
|
if tier == 3 then
|
||||||
local pi,ps = searchPalette(value)
|
local pi,ps = searchPalette(value)
|
||||||
local r,g,b = extract(value)
|
local r,g,b = extract(value)
|
||||||
@ -226,10 +233,21 @@ local function getColor(value)
|
|||||||
if defs < ps then
|
if defs < ps then
|
||||||
return defc
|
return defc
|
||||||
else
|
else
|
||||||
|
if sel then
|
||||||
|
scrfgp = pi
|
||||||
|
else
|
||||||
|
scrbgp = pi
|
||||||
|
end
|
||||||
return palcol[pi]
|
return palcol[pi]
|
||||||
end
|
end
|
||||||
elseif tier == 2 then
|
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
|
else
|
||||||
if value > 0 then
|
if value > 0 then
|
||||||
return 0xFFFFFF -- TODO: Configuration color
|
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)
|
cprint("(cec) screen.setForeground", value, palette)
|
||||||
local oldc, oldp = scrrfc, scrfgp
|
local oldc, oldp = scrrfc, scrfgp
|
||||||
scrrfc = palette and palcol[value] or value
|
scrrfc = palette and palcol[value] or value
|
||||||
scrfgc = palette and scrrfc or getColor(scrrfc)
|
|
||||||
scrfgp = palette and value
|
scrfgp = palette and value
|
||||||
|
scrfgc = palette and scrrfc or getColor(scrrfc,true)
|
||||||
return oldc, oldp
|
return oldc, oldp
|
||||||
end
|
end
|
||||||
function cec.getBackground() -- Get the current background color and whether it's from the palette or not.
|
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)
|
cprint("(cec) screen.setBackground", value, palette)
|
||||||
local oldc, oldp = scrrbc, scrbgp
|
local oldc, oldp = scrrbc, scrbgp
|
||||||
scrrbc = palette and palcol[value] or value
|
scrrbc = palette and palcol[value] or value
|
||||||
scrbgc = palette and scrrbc or getColor(scrrbc)
|
|
||||||
scrbgp = palette and value
|
scrbgp = palette and value
|
||||||
|
scrbgc = palette and scrrbc or getColor(scrrbc,false)
|
||||||
return oldc, oldp
|
return oldc, oldp
|
||||||
end
|
end
|
||||||
function cec.getDepth() -- Returns the currently set color depth.
|
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
|
if tier > 1 then
|
||||||
loadPalette()
|
loadPalette()
|
||||||
end
|
end
|
||||||
scrfgc = getColor(scrrfc)
|
scrfgc = getColor(scrrfc,true)
|
||||||
scrfbc = getColor(scrrbc)
|
scrfbc = getColor(scrrbc,false)
|
||||||
-- TODO: Lowering the depth recolors the entire screen
|
-- TODO: Lowering the depth recolors the entire screen
|
||||||
end
|
end
|
||||||
function cec.maxDepth() -- Get the maximum supported color depth.
|
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)
|
setPos(x,y,code,scrfgc,scrbgc)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
function cec.getResolution() -- Get the current screen resolution.
|
function cec.getResolution() -- Get the current screen resolution.
|
||||||
cprint("(cec) screen.getResolution")
|
cprint("(cec) screen.getResolution")
|
||||||
@ -362,8 +381,9 @@ function cec.getResolution() -- Get the current screen resolution.
|
|||||||
end
|
end
|
||||||
function cec.setResolution(newwidth, newheight) -- Set the screen resolution. Returns true if the resolution changed.
|
function cec.setResolution(newwidth, newheight) -- Set the screen resolution. Returns true if the resolution changed.
|
||||||
cprint("(cec) screen.setResolution", newwidth, newheight)
|
cprint("(cec) screen.setResolution", newwidth, newheight)
|
||||||
|
newwidth,newheight = math.floor(newwidth),math.floor(newheight)
|
||||||
local oldwidth, oldheight = width, height
|
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
|
return oldwidth ~= width or oldheight ~= height
|
||||||
end
|
end
|
||||||
function cec.maxResolution() -- Get the maximum screen resolution.
|
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]
|
copy.bgp[y-y1][x-x1] = screen.bgp[y][x]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for y = math.max(math.min(y1+ty, height), 1), math.max(math.min(y2+ty, height), 1) do
|
local my1,my2 = math.max(math.min(y1+ty, height), 1), math.max(math.min(y2+ty, height), 1)
|
||||||
for x = math.max(math.min(x1+tx, width), 1), math.max(math.min(x2+tx, width), 1) do
|
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.txt[y][x] = copy.txt[y-y1-ty][x-x1-tx]
|
||||||
screen.fg[y][x] = copy.fg[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]
|
screen.bg[y][x] = copy.bg[y-y1-ty][x-x1-tx]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user