178 lines
4.9 KiB
Lua
178 lines
4.9 KiB
Lua
AddCSLuaFile()
|
|
DEFINE_BASECLASS( "base_wire_entity" )
|
|
ENT.PrintName = "Wire Extended Bus"
|
|
ENT.WireDebugName = "Extended Bus"
|
|
|
|
if CLIENT then return end -- No more client
|
|
|
|
function ENT:Initialize()
|
|
self:PhysicsInit( SOLID_VPHYSICS)
|
|
self:SetMoveType( MOVETYPE_VPHYSICS)
|
|
self:SetSolid( SOLID_VPHYSICS)
|
|
self:SetUseType( SIMPLE_USE)
|
|
self.Outputs = Wire_CreateOutputs(self, {"Memory"})
|
|
self.Inputs = Wire_CreateInputs(self,{"Memory1","Memory2","Memory3","Memory4","Memory5","Memory6","Memory7","Memory8"})
|
|
|
|
self.DataRate = 0
|
|
self.DataBytes = 0
|
|
self.PerformRecursiveScan = 1
|
|
self.ControlDataSize = 32
|
|
self.ControlData = {}
|
|
|
|
self.Memory = {}
|
|
self.MemStart = {}
|
|
self.MemEnd = {}
|
|
for i = 1,8 do
|
|
self.Memory[i] = nil
|
|
self.MemStart[i] = 0
|
|
self.MemEnd[i] = 0
|
|
end
|
|
self:SetOverlayText("Data rate: 0 bps")
|
|
end
|
|
|
|
function ENT:Think()
|
|
BaseClass.Think(self)
|
|
|
|
self.DataRate = self.DataBytes
|
|
self.DataBytes = 0
|
|
|
|
Wire_TriggerOutput(self, "Memory", self.DataRate)
|
|
self:SetOverlayText("Data rate: "..math.floor(self.DataRate*2).." bps")
|
|
self:NextThink(CurTime()+0.5)
|
|
end
|
|
|
|
function ENT:ReadCell(Address)
|
|
Address = math.floor(Address)
|
|
if (Address >= 0) and (Address < self.ControlDataSize) then
|
|
if Address < 16 then
|
|
if Address % 2 == 0 then
|
|
return self.MemStart[Address/2+1]
|
|
else
|
|
return self.MemEnd[(Address-1)/2+1]
|
|
end
|
|
elseif Address == 16 then
|
|
return self.ControlDataSize
|
|
elseif Address == 18 then
|
|
return self.DataRate
|
|
elseif Address == 20 then
|
|
return self.PerformRecursiveScan
|
|
elseif Address >= 32 then
|
|
return self.ControlData[Address-31] or 0
|
|
end
|
|
return 0
|
|
else
|
|
for i = 1,8 do
|
|
if (Address-self.ControlDataSize >= self.MemStart[i]) and
|
|
(Address-self.ControlDataSize <= self.MemEnd[i]) then
|
|
if self.Memory[i] then
|
|
if self.Memory[i].ReadCell then
|
|
self.DataBytes = self.DataBytes + 1
|
|
local val = self.Memory[i]:ReadCell(Address-self.ControlDataSize-self.MemStart[i])
|
|
return val or 0
|
|
end
|
|
else
|
|
return 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local recursiveCounter = 0
|
|
function ENT:GetDeviceInfo(deviceEnt)
|
|
local deviceType = CPULib.GetDeviceType(deviceEnt:GetClass())
|
|
if deviceEnt.Socket then
|
|
if deviceEnt.Socket.Inputs.Memory.Src then
|
|
self:GetDeviceInfo(deviceEnt.Socket.Inputs.Memory.Src)
|
|
else
|
|
table.insert(self.ControlData,14)
|
|
end
|
|
return
|
|
elseif deviceEnt.Plug then
|
|
if deviceEnt.Plug.Inputs.Memory.Src then
|
|
self:GetDeviceInfo(deviceEnt.Plug.Inputs.Memory.Src)
|
|
else
|
|
table.insert(self.ControlData,13)
|
|
end
|
|
return
|
|
end
|
|
|
|
table.insert(self.ControlData,deviceType)
|
|
|
|
if self.PerformRecursiveScan >= 1 then
|
|
recursiveCounter = recursiveCounter + 1
|
|
if recursiveCounter < 256 then
|
|
if (deviceEnt:GetClass() == "gmod_wire_addressbus") or
|
|
(deviceEnt:GetClass() == "gmod_wire_extbus") then
|
|
for i = 1,8 do
|
|
if deviceEnt.Memory[i] then
|
|
self:GetDeviceInfo(deviceEnt.Memory[i])
|
|
else
|
|
table.insert(self.ControlData,0)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function ENT:WriteCell(Address, Value)
|
|
Address = math.floor(Address)
|
|
if (Address >= 0) and (Address < self.ControlDataSize) then
|
|
-- [0..15] Address bus settings
|
|
-- [16] Control data area size
|
|
-- [17] Write to request device info
|
|
-- [18] Data transfer rate
|
|
-- [19] Override returned device type (0: no override)
|
|
-- [20] Perform recursive scan
|
|
-- [32..] Device types
|
|
if Address < 16 then
|
|
if Address % 2 == 0 then
|
|
self.MemStart[Address/2+1] = math.floor(Value)
|
|
else
|
|
self.MemEnd[(Address-1)/2+1] = math.floor(Value)
|
|
end
|
|
elseif Address == 16 then
|
|
self.ControlDataSize = math.max(32,math.floor(Value))
|
|
elseif Address == 17 then
|
|
recursiveCounter = 0
|
|
self.ControlData = {}
|
|
for i = 1,8 do
|
|
if self.Memory[i] then
|
|
self:GetDeviceInfo(self.Memory[i])
|
|
else
|
|
table.insert(self.ControlData,0)
|
|
end
|
|
end
|
|
elseif Address == 20 then
|
|
self.PerformRecursiveScan = Value
|
|
end
|
|
return true
|
|
else
|
|
local res = false
|
|
for i = 1,8 do
|
|
if (Address-self.ControlDataSize >= self.MemStart[i]) and
|
|
(Address-self.ControlDataSize <= self.MemEnd[i]) then
|
|
if self.Memory[i] then
|
|
if self.Memory[i].WriteCell then
|
|
self.Memory[i]:WriteCell(Address-self.ControlDataSize-self.MemStart[i], Value)
|
|
end
|
|
end
|
|
self.DataBytes = self.DataBytes + 1
|
|
res = true
|
|
end
|
|
end
|
|
return res
|
|
end
|
|
end
|
|
|
|
function ENT:TriggerInput(iname, value)
|
|
for i = 1,8 do
|
|
if iname == "Memory"..i then
|
|
self.Memory[i] = self.Inputs["Memory"..i].Src
|
|
end
|
|
end
|
|
end
|
|
|
|
duplicator.RegisterEntityClass("gmod_wire_extbus", WireLib.MakeWireEnt, "Data")
|