Added sdgReader (Requires the use of luajit)
This commit is contained in:
parent
a758272e14
commit
3883b14122
171
LoveKaraoke/cdgreader.lua
Normal file
171
LoveKaraoke/cdgreader.lua
Normal file
@ -0,0 +1,171 @@
|
||||
require("bin")
|
||||
require("bit")
|
||||
--require("luabit.bit")
|
||||
-- CDG Command Code
|
||||
CDG_COMMAND = 0x09
|
||||
-- CDG Instruction Codes
|
||||
CDG_INST_MEMORY_PRESET = 1
|
||||
CDG_INST_BORDER_PRESET = 2
|
||||
CDG_INST_TILE_BLOCK = 6
|
||||
CDG_INST_SCROLL_PRESET = 20
|
||||
CDG_INST_SCROLL_COPY = 24
|
||||
CDG_INST_DEF_TRANSP_COL = 28
|
||||
CDG_INST_LOAD_COL_TBL_0_7 = 30
|
||||
CDG_INST_LOAD_COL_TBL_8_15 = 31
|
||||
CDG_INST_TILE_BLOCK_XOR = 38
|
||||
-- Bitmask for all CDG fields
|
||||
CDG_MASK = 0x3F
|
||||
cdgPlayer={}
|
||||
function cdgPlayer:init(cdgFileName)
|
||||
self.FileName = cdgFileName
|
||||
-- Check the CDG file exists
|
||||
if not io.fileExists(self.FileName) then
|
||||
ErrorString = "No such file: ".. self.FileName
|
||||
error(ErrorString)
|
||||
end
|
||||
self:decode()
|
||||
end
|
||||
function cdgPlayer:decode()
|
||||
-- Open the cdg file
|
||||
self.cdgFile = bin.load(self.FileName)
|
||||
-- Main processing loop
|
||||
while true do
|
||||
packd = self:cdgGetNextPacket()
|
||||
if packd then
|
||||
self:cdgPacketProcess(packd)
|
||||
else
|
||||
self.cdgFile:close()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Decode the CDG commands read from the CDG file
|
||||
function cdgPlayer:cdgPacketProcess(packd)
|
||||
if bit.band(packd['command'], CDG_MASK) == CDG_COMMAND then
|
||||
inst_code = bit.band(packd['instruction'], CDG_MASK)
|
||||
if inst_code == CDG_INST_MEMORY_PRESET then
|
||||
self:cdgMemoryPreset(packd)
|
||||
elseif inst_code == CDG_INST_BORDER_PRESET then
|
||||
self:cdgBorderPreset(packd)
|
||||
elseif inst_code == CDG_INST_TILE_BLOCK then
|
||||
self:cdgTileBlockCommon(packd, false)
|
||||
elseif inst_code == CDG_INST_SCROLL_PRESET then
|
||||
self:cdgScrollPreset(packd)
|
||||
elseif inst_code == CDG_INST_SCROLL_COPY then
|
||||
self:cdgScrollCopy(packd)
|
||||
elseif inst_code == CDG_INST_DEF_TRANSP_COL then
|
||||
self:cdgDefineTransparentColour(packd)
|
||||
elseif inst_code == CDG_INST_LOAD_COL_TBL_0_7 then
|
||||
self:cdgLoadColourTableCommon(packd, 0)
|
||||
elseif inst_code == CDG_INST_LOAD_COL_TBL_8_15 then
|
||||
self:cdgLoadColourTableCommon(packd, 1)
|
||||
elseif inst_code == CDG_INST_TILE_BLOCK_XOR then
|
||||
self:cdgTileBlockCommon(packd, 1)
|
||||
else
|
||||
ErrorString = "Unknown command in CDG file: " + str(inst_code)
|
||||
print(ErrorString)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Read the next CDG command from the file (24 bytes each)
|
||||
function cdgPlayer:cdgGetNextPacket() -- Come back to this!!!
|
||||
packd={}
|
||||
packet = bin.new(self.cdgFile:getBlock("s",24))
|
||||
--print(packet)
|
||||
if packet:getlength() == 24 then
|
||||
packd['command']=packet:getBlock("n",1)--struct.unpack('B', packet[0])[0]
|
||||
packd['instruction']=packet:getBlock("n",1)--struct.unpack('B', packet[1])[0]
|
||||
packd['parityQ']=packet:getBlock("s",2)--struct.unpack('2B', packet:sub(2,4))[0:2]
|
||||
packd['data']=bin.newDataBuffer(16)--struct.unpack('16B', packet[4:20])[0:16]
|
||||
packd['data']:fillBuffer(packet:getBlock("s",16),1)
|
||||
packd['parity']=packet:getBlock("s",4)--struct.unpack('4B', packet[20:24])[0:4]
|
||||
return packd
|
||||
elseif packet:getlength() > 0 then
|
||||
print("Didn't read 24 bytes")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
function cdgPlayer:cdgMemoryPreset(packd)
|
||||
colour = bit.band(packd['data'][1], 0x0F)
|
||||
repea = bit.band(packd['data'][2], 0x0F)
|
||||
print (string.format("cdgMemoryPreset [Colour=%d, Repeat=%d]", colour, repea))
|
||||
return
|
||||
end
|
||||
function cdgPlayer:cdgBorderPreset(packd)
|
||||
colour = bit.band(packd['data'][1], 0x0F)
|
||||
print (string.format("cdgMemoryPreset [Colour=%d]", colour))
|
||||
return
|
||||
end
|
||||
function cdgPlayer:cdgScrollPreset(packd)
|
||||
self:cdgScrollCommon(packd, false)
|
||||
return
|
||||
end
|
||||
function cdgPlayer:cdgScrollCopy(packd)
|
||||
self.cdgScrollCommon(packd, true)
|
||||
return
|
||||
end
|
||||
function cdgPlayer:cdgScrollCommon(packd, copy)
|
||||
-- Decode the scroll command parameters
|
||||
data_block = packd['data']
|
||||
colour = bit.band(data_block[1], 0x0F)
|
||||
hScroll = bit.band(data_block[2], 0x3F)
|
||||
vScroll = bit.band(data_block[3], 0x3F)
|
||||
hSCmd = bit.rshift(bit.band(hScroll, 0x30), 4)
|
||||
hOffset = bit.band(hScroll, 0x07)
|
||||
vSCmd = bit.rshift(bit.band(vScroll, 0x30), 4)
|
||||
vOffset = bit.band(vScroll, 0x0F)
|
||||
|
||||
if copy then
|
||||
typeStr = "cdgScrollCopy"
|
||||
else
|
||||
typeStr = "cdgScrollPreset"
|
||||
end
|
||||
print(string.format("%s [colour=%d, hScroll=%d, vScroll=%d]", typeStr, colour, hScroll, vScroll))
|
||||
return
|
||||
end
|
||||
function cdgPlayer:cdgTileBlockCommon(packd, xor)
|
||||
-- Decode the command parameters
|
||||
data_block = packd['data']
|
||||
colour0 = bit.band(data_block[1], 0x0F)
|
||||
colour1 = bit.band(data_block[2], 0x0F)
|
||||
column_index = bit.band(data_block[3], 0x1F) * 12
|
||||
row_index = bit.band(data_block[4], 0x3F) * 6
|
||||
|
||||
if xor then
|
||||
typeStr = "cdgTileBlockXOR"
|
||||
else
|
||||
typeStr = "cdgTileBlockNormal"
|
||||
end
|
||||
print(string.format("%s [Colour0=%d, Colour1=%d, ColIndex=%d, RowIndex=%d]", typeStr, colour0, colour1, column_index, row_index))
|
||||
return
|
||||
end
|
||||
function cdgPlayer:cdgDefineTransparentColour(packd)
|
||||
data_block = packd['data']
|
||||
colour = bit.band(data_block[1], 0x0F)
|
||||
print (string.format("cdgDefineTransparentColour [Colour=%d]", colour))
|
||||
return
|
||||
end
|
||||
function cdgPlayer:cdgLoadColourTableCommon (packd, tab)
|
||||
if tab == 0 then
|
||||
colourTableStart = 0
|
||||
print ("cdgLoadColourTable0..7")
|
||||
else
|
||||
colourTableStart = 8
|
||||
print ("cdgLoadColourTable8..15")
|
||||
end
|
||||
for i=0,7 do
|
||||
colourEntry = bit.lshift(bit.band(packd['data'][(2 * i)+1], CDG_MASK), 8)
|
||||
colourEntry = colourEntry + bit.band(packd['data'][(2 * i) + 2], CDG_MASK)
|
||||
colourEntry = bit.bor(bit.rshift(bit.band(colourEntry, 0x3F00), 2), bit.band(colourEntry, 0x003F))
|
||||
print (string.format(" Colour %d = 0x%X", (i + 1 + colourTableStart), colourEntry))
|
||||
end
|
||||
return
|
||||
end
|
||||
--[[
|
||||
|
||||
colourEntry = ((packd['data'][2 * i] & CDG_MASK) << 8)
|
||||
colourEntry = colourEntry + (packd['data'][(2 * i) + 1] & CDG_MASK)
|
||||
colourEntry = ((colourEntry & 0x3F00) >> 2) | (colourEntry & 0x003F)
|
||||
|
||||
]]
|
||||
player=cdgPlayer:init("test.cdg")
|
||||
BIN
LoveKaraoke/test.cdg
Normal file
BIN
LoveKaraoke/test.cdg
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user