Skip to content

Commit

Permalink
DARRAY Instruction implemented (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
DerelictDrone authored Sep 14, 2024
1 parent 3b021e0 commit 13da808
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 3 deletions.
144 changes: 142 additions & 2 deletions lua/entities/gmod_wire_gpu/cl_gpuvm.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ function ENT:OverrideVM()
self.VM.ErrorText[17] = "Frame instruction limit"
self.VM.ErrorText[18] = "Frame delayed by quota overrun"
self.VM.ErrorText[23] = "Error reading string data"
self.VM.ErrorText[24] = "Nonexistent color mode"

self.VM.Interrupt = function(self,interruptNo,interruptParameter,isExternal,cascadeInterrupt)
if self.ASYNC == 1 then
Expand Down Expand Up @@ -140,6 +141,80 @@ function ENT:OverrideVM()
return false
end

local RGBXXXCache = {}
local function RGBXXXSingleCellColor(VM,Address)
local c = VM:ReadCell(Address)
local cached = RGBXXXCache[c]
VM.TMR = VM.TMR + 1
if cached then return cached,1 end
VM.TMR = VM.TMR + 7
local crgb = math.floor(c / 1000)
local cgray = c - math.floor(c / 1000)*1000

local cb = cgray+28*math.fmod(crgb, 10)
local cg = cgray+28*math.fmod(math.floor(crgb / 10), 10)
local cr = cgray+28*math.fmod(math.floor(crgb / 100), 10)
local color = {x=cr,y=cg,z=cb,w=255}
RGBXXXCache[c] = color
return color,1
end

local B24Cache = {}
local function B24SingleCellColor(VM,Address)
local c = VM:ReadCell(Address)
local cached = B24Cache[c]
VM.TMR = VM.TMR + 1
if cached then return cached,1 end
VM.TMR = VM.TMR + 9
local R = bit.band(bit.rshift(c,16),255)
local G = bit.band(bit.rshift(c,8),255)
local B = bit.band(c,255)
local color = {x=R,y=G,z=B,w=255}
B24Cache[c] = color
return color,1
end

local ArithmeticRGBCache = {}
local function ArithmeticRGBSingleCellColor(VM,Address)
local c = VM:ReadCell(Address)
local cached = ArithmeticRGBCache[c]
VM.TMR = VM.TMR + 1
if cached then return cached,1 end
VM.TMR = VM.TMR + 14
local cb = math.fmod(c, 1000)
local cg = math.fmod(math.floor(c / 1e3), 1000)
local cr = math.fmod(math.floor(c / 1e6), 1000)
local color = {x=cr,y=cg,z=cb,w=255}
ArithmeticRGBCache[c] = color
return color,1
end

local function MonoSingleCellColor(VM,Address)
local c = VM:ReadCell(Address)
return {x=c,y=c,z=c,w=255},1
end

local function RGBThreeCellColor(VM,Address)
local v3f = VM:ReadVector3f(Address)
v3f.w = 255
return v3f,3
end

self.VM.ColorConversionModes = {
[0]={Converter = RGBXXXSingleCellColor, PixelSize = 1},
[1]={Converter = RGBThreeCellColor, PixelSize = 3},
[2]={Converter = B24SingleCellColor, PixelSize = 1},
[3]={Converter = ArithmeticRGBSingleCellColor, PixelSize = 1},
[4]={Converter = MonoSingleCellColor, PixelSize = 1},
}

function self.VM:ResetColorCaches()
RGBXXXCache = {}
B24Cache = {}
ArithmeticRGBCache = {}
end


-- Add internal registers
self.VM.InternalRegister[128] = "EntryPoint0"
self.VM.InternalRegister[129] = "EntryPoint1"
Expand Down Expand Up @@ -622,7 +697,7 @@ function VM:HardReset()
self.EntryPoint5 = 0
self.EntryPoint6 = 0
self.EntryPoint7 = 0

self:ResetColorCaches()
-- Is running asynchronous thread
self.ASYNC = 0

Expand Down Expand Up @@ -1985,7 +2060,72 @@ VM.OpcodeTable[235] = function(self) --DCULLMODE
self:Dyn_Emit("VM:WriteCell(65468,$2)")
end
VM.OpcodeTable[236] = function(self) --DARRAY

self:Dyn_Emit("$L RX = math.floor(VM:ReadCell($2))")
self:Dyn_Emit("$L RY = math.floor(VM:ReadCell(($2)+1))")
self:Dyn_Emit("$L PX = VM:ReadCell(($2)+2)")
self:Dyn_Emit("$L PY = VM:ReadCell(($2)+3)")
self:Dyn_Emit("$L CM = math.floor(VM:ReadCell(($2)+4))")
self:Dyn_Emit("$L PPTR = VM:ReadCell(($2)+5)")
self:Dyn_Emit("if not VM.ColorConversionModes[CM] then")
self:Dyn_Emit("VM:Interrupt(24,CM)")
self:Dyn_EmitInterruptCheck()
self:Dyn_Emit("end")
self:Dyn_Emit("$L PAMT = (RX*RY)*VM.ColorConversionModes[CM].PixelSize")
self:Dyn_Emit("$L PCVT = VM.ColorConversionModes[CM].Converter")
self:Dyn_Emit("$L StartX, StartY, DPTR = VM:ReadCell($1),VM:ReadCell(($1)+1),0")
self:Dyn_Emit("$L CurX, CurY = StartX,StartY")
self:Dyn_Emit("$L VD = {}")
self:Dyn_Emit("while(DPTR < PAMT) do")
self:Dyn_Emit("CurX = StartX")
self:Dyn_Emit("for x = 0, RX-1,1 do")
self:Dyn_Emit("$L ccolor,size = PCVT(VM,PPTR+DPTR)")
self:Dyn_EmitInterruptCheck()
self:Dyn_Emit("DPTR = DPTR + size")
self:Dyn_Emit("VD[1] = {x = CurX, y = CurY}")
self:Dyn_Emit("VD[2] = {x = CurX + PX, y = CurY}")
self:Dyn_Emit("VD[3] = {x = CurX + PX, y = CurY + PY}")
self:Dyn_Emit("VD[4] = {x = CurX, y = CurY + PY}")
self:Dyn_Emit("VM:SetColor(ccolor)")
self:Dyn_Emit("VM:DrawToBuffer(VD)")
self:Dyn_Emit("CurX = CurX + PX")
self:Dyn_BeginQuotaOnlyCode()
self:Dyn_Emit("VM.DARRAYCarriedX = x+1")
self:Dyn_Emit("VM.DARRAYInterruptedLoop = true")
self:Dyn_EndQuotaOnlyCode()
-- Copy of above for loop for quota override
self:Dyn_StartQuotaInterrupt()
self:Dyn_Emit("while(DPTR < PAMT) do")
self:Dyn_Emit("if not VM.DARRAYInterruptedLoop then")
self:Dyn_Emit("CurX = StartX")
self:Dyn_Emit("end")
self:Dyn_Emit("for x = VM.DARRAYCarriedX or 0, RX-1,1 do")
self:Dyn_Emit("$L ccolor,size = PCVT(VM,PPTR+DPTR)")
self:Dyn_EmitInterruptCheck()
self:Dyn_Emit("DPTR = DPTR + size")
self:Dyn_Emit("VD[1] = {x = CurX, y = CurY}")
self:Dyn_Emit("VD[2] = {x = CurX + PX, y = CurY}")
self:Dyn_Emit("VD[3] = {x = CurX + PX, y = CurY + PY}")
self:Dyn_Emit("VD[4] = {x = CurX, y = CurY + PY}")
self:Dyn_Emit("VM:SetColor(ccolor)")
self:Dyn_Emit("VM:DrawToBuffer(VD)")
self:Dyn_Emit("CurX = CurX + PX")
self:Dyn_BeginQuotaOnlyCode()
self:Dyn_Emit("VM.DARRAYCarriedX = x+1")
self:Dyn_Emit("VM.DARRAYInterruptedLoop = true")
self:Dyn_Emit("return")
self:Dyn_EndQuotaOnlyCode()
self:Dyn_Emit("end")
self:Dyn_Emit("VM.DARRAYCarriedX = nil")
self:Dyn_Emit("VM.DARRAYInterruptedLoop = nil")
self:Dyn_Emit("CurY = CurY + PY")
self:Dyn_Emit("end")
self:Dyn_Emit("VM.DARRAYCarriedX = nil")
self:Dyn_Emit("VM.DARRAYInterruptedLoop = nil")
self:Dyn_Emit("VM.QuotaOverrunFunc = nil")
self:Dyn_EndQuotaInterrupt()
self:Dyn_Emit("end")
self:Dyn_Emit("CurY = CurY + PY")
self:Dyn_Emit("end")
end
VM.OpcodeTable[237] = function(self) --DDTERMINAL

Expand Down
2 changes: 1 addition & 1 deletion lua/wire/cpulib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,7 @@ GPU(232, "DSCRSIZE", 2, 0.5, 0, "X", "Y", "Set screen
GPU(233, "DROTATESCALE", 2, 0.5, 0, "X", "Y", "Rotate by X, scale by Y")
GPU(234, "DORECTWH", 2, 0.5, 0, "VEC2F", "VEC2F", "Draw an outlined rectangle by width/height")
GPU(235, "DCULLMODE", 2, 0.7, 0, "IDX", "IDX", "Set cullmode and lighting mode")
--GPU(236, "DARRAY", 2, 1.0, 0, "VEC2F", "STRUCT","Draw an array of pixels")
GPU(236, "DARRAY", 2, 1.0, 0, "VEC2F", "STRUCT","Draw an array of width/height rectangles.\nStruct layout:\nResolution X, Resolution Y, Pixel Width, Pixel Height, Color Mode(like digital screen), Pointer to color buffer")
--GPU(237, "DDTERMINAL", 2, 1.0, 0, "VEC2F", "STRUCT","Draw a console screen/terminal window")
GPU(238, "DPIXEL", 2, 1.0, 0, "VEC2F", "COLOR", "Draw a pixel to screen")
GPU(239, "RESERVED", 2, 0.0, 0, "", "", "")
Expand Down

0 comments on commit 13da808

Please sign in to comment.