543 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			543 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local socket = require("socket")
 | 
						|
local json = require('json')
 | 
						|
local math = require('math')
 | 
						|
 | 
						|
local STATE_OK = "Ok"
 | 
						|
local STATE_TENTATIVELY_CONNECTED = "Tentatively Connected"
 | 
						|
local STATE_INITIAL_CONNECTION_MADE = "Initial Connection Made"
 | 
						|
local STATE_UNINITIALIZED = "Uninitialized"
 | 
						|
 | 
						|
local ITEM_INDEX = 0x03
 | 
						|
local WEAPON_INDEX = 0x07
 | 
						|
local ARMOR_INDEX = 0x0B
 | 
						|
 | 
						|
local goldLookup = {
 | 
						|
    [0x16C] = 10,
 | 
						|
    [0x16D] = 20,
 | 
						|
    [0x16E] = 25,
 | 
						|
    [0x16F] = 30,
 | 
						|
    [0x170] = 55,
 | 
						|
    [0x171] = 70,
 | 
						|
    [0x172] = 85,
 | 
						|
    [0x173] = 110,
 | 
						|
    [0x174] = 135,
 | 
						|
    [0x175] = 155,
 | 
						|
    [0x176] = 160,
 | 
						|
    [0x177] = 180,
 | 
						|
    [0x178] = 240,
 | 
						|
    [0x179] = 255,
 | 
						|
    [0x17A] = 260,
 | 
						|
    [0x17B] = 295,
 | 
						|
    [0x17C] = 300,
 | 
						|
    [0x17D] = 315,
 | 
						|
    [0x17E] = 330,
 | 
						|
    [0x17F] = 350,
 | 
						|
    [0x180] = 385,
 | 
						|
    [0x181] = 400,
 | 
						|
    [0x182] = 450,
 | 
						|
    [0x183] = 500,
 | 
						|
    [0x184] = 530,
 | 
						|
    [0x185] = 575,
 | 
						|
    [0x186] = 620,
 | 
						|
    [0x187] = 680,
 | 
						|
    [0x188] = 750,
 | 
						|
    [0x189] = 795,
 | 
						|
    [0x18A] = 880,
 | 
						|
    [0x18B] = 1020,
 | 
						|
    [0x18C] = 1250,
 | 
						|
    [0x18D] = 1455,
 | 
						|
    [0x18E] = 1520,
 | 
						|
    [0x18F] = 1760,
 | 
						|
    [0x190] = 1975,
 | 
						|
    [0x191] = 2000,
 | 
						|
    [0x192] = 2750,
 | 
						|
    [0x193] = 3400,
 | 
						|
    [0x194] = 4150,
 | 
						|
    [0x195] = 5000,
 | 
						|
    [0x196] = 5450,
 | 
						|
    [0x197] = 6400,
 | 
						|
    [0x198] = 6720,
 | 
						|
    [0x199] = 7340,
 | 
						|
    [0x19A] = 7690,
 | 
						|
    [0x19B] = 7900,
 | 
						|
    [0x19C] = 8135,
 | 
						|
    [0x19D] = 9000,
 | 
						|
    [0x19E] = 9300,
 | 
						|
    [0x19F] = 9500,
 | 
						|
    [0x1A0] = 9900,
 | 
						|
    [0x1A1] = 10000,
 | 
						|
    [0x1A2] = 12350,
 | 
						|
    [0x1A3] = 13000,
 | 
						|
    [0x1A4] = 13450,
 | 
						|
    [0x1A5] = 14050,
 | 
						|
    [0x1A6] = 14720,
 | 
						|
    [0x1A7] = 15000,
 | 
						|
    [0x1A8] = 17490,
 | 
						|
    [0x1A9] = 18010,
 | 
						|
    [0x1AA] = 19990,
 | 
						|
    [0x1AB] = 20000,
 | 
						|
    [0x1AC] = 20010,
 | 
						|
    [0x1AD] = 26000,
 | 
						|
    [0x1AE] = 45000,
 | 
						|
    [0x1AF] = 65000
 | 
						|
}
 | 
						|
 | 
						|
local extensionConsumableLookup = {
 | 
						|
    [432] = 0x3C,
 | 
						|
    [436] = 0x3C,
 | 
						|
    [440] = 0x3C,
 | 
						|
    [433] = 0x3D,
 | 
						|
    [437] = 0x3D,
 | 
						|
    [441] = 0x3D,
 | 
						|
    [434] = 0x3E,
 | 
						|
    [438] = 0x3E,
 | 
						|
    [442] = 0x3E,
 | 
						|
    [435] = 0x3F,
 | 
						|
    [439] = 0x3F,
 | 
						|
    [443] = 0x3F
 | 
						|
}
 | 
						|
 | 
						|
local itemMessages = {}
 | 
						|
local consumableStacks = nil
 | 
						|
local prevstate = ""
 | 
						|
local curstate =  STATE_UNINITIALIZED
 | 
						|
local ff1Socket = nil
 | 
						|
local frame = 0
 | 
						|
 | 
						|
local u8 = nil
 | 
						|
local wU8 = nil
 | 
						|
local isNesHawk = false
 | 
						|
 | 
						|
 | 
						|
--Sets correct memory access functions based on whether NesHawk or QuickNES is loaded
 | 
						|
local function defineMemoryFunctions()
 | 
						|
	local memDomain = {}
 | 
						|
	local domains = memory.getmemorydomainlist()
 | 
						|
	if domains[1] == "System Bus" then
 | 
						|
		--NesHawk
 | 
						|
		isNesHawk = true
 | 
						|
		memDomain["systembus"] = function() memory.usememorydomain("System Bus") end
 | 
						|
		memDomain["saveram"]   = function() memory.usememorydomain("Battery RAM") end
 | 
						|
		memDomain["rom"]       = function() memory.usememorydomain("PRG ROM") end
 | 
						|
	elseif domains[1] == "WRAM" then
 | 
						|
		--QuickNES
 | 
						|
		memDomain["systembus"] = function() memory.usememorydomain("System Bus") end
 | 
						|
		memDomain["saveram"]   = function() memory.usememorydomain("WRAM") end
 | 
						|
		memDomain["rom"]       = function() memory.usememorydomain("PRG ROM") end
 | 
						|
	end
 | 
						|
	return memDomain
 | 
						|
end
 | 
						|
 | 
						|
local memDomain = defineMemoryFunctions()
 | 
						|
u8 = memory.read_u8
 | 
						|
wU8 = memory.write_u8
 | 
						|
uRange = memory.readbyterange
 | 
						|
 | 
						|
local function StateOKForMainLoop()
 | 
						|
    memDomain.saveram()
 | 
						|
    local A = u8(0x102) -- Party Made
 | 
						|
    local B = u8(0x0FC)
 | 
						|
    local C = u8(0x0A3)
 | 
						|
    return A ~= 0x00 and not (A== 0xF2 and B == 0xF2 and C == 0xF2)
 | 
						|
end
 | 
						|
 | 
						|
function table.empty (self)
 | 
						|
    for _, _ in pairs(self) do
 | 
						|
        return false
 | 
						|
    end
 | 
						|
    return true
 | 
						|
end
 | 
						|
 | 
						|
function slice (tbl, s, e)
 | 
						|
    local pos, new = 1, {}
 | 
						|
    for i = s + 1, e do
 | 
						|
        new[pos] = tbl[i]
 | 
						|
        pos = pos + 1
 | 
						|
    end
 | 
						|
    return new
 | 
						|
end
 | 
						|
 | 
						|
local bizhawk_version = client.getversion()
 | 
						|
local is23Or24Or25 = (bizhawk_version=="2.3.1") or (bizhawk_version:sub(1,3)=="2.4") or (bizhawk_version:sub(1,3)=="2.5")
 | 
						|
local is26To28 =  (bizhawk_version:sub(1,3)=="2.6") or (bizhawk_version:sub(1,3)=="2.7") or (bizhawk_version:sub(1,3)=="2.8")
 | 
						|
 | 
						|
local function getMaxMessageLength()
 | 
						|
    if is23Or24Or25 then
 | 
						|
        return client.screenwidth()/11
 | 
						|
    elseif is26To28 then
 | 
						|
        return client.screenwidth()/12
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function drawText(x, y, message, color)
 | 
						|
    if is23Or24Or25 then
 | 
						|
        gui.addmessage(message)
 | 
						|
    elseif is26To28 then
 | 
						|
        gui.drawText(x, y, message, color, 0xB0000000, 18, "Courier New", nil, nil, nil, "client")
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function clearScreen()
 | 
						|
    if is23Or24Or25 then
 | 
						|
        return
 | 
						|
    elseif is26To28 then
 | 
						|
        drawText(0, 0, "", "black")
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function drawMessages()
 | 
						|
    if table.empty(itemMessages) then
 | 
						|
        clearScreen()
 | 
						|
        return
 | 
						|
    end
 | 
						|
    local y = 10
 | 
						|
    found = false
 | 
						|
    maxMessageLength = getMaxMessageLength()
 | 
						|
    for k, v in pairs(itemMessages) do
 | 
						|
        if v["TTL"] > 0 then
 | 
						|
            message = v["message"]
 | 
						|
            while true do
 | 
						|
                drawText(5, y, message:sub(1, maxMessageLength), v["color"])
 | 
						|
                y = y + 16
 | 
						|
 | 
						|
                message = message:sub(maxMessageLength + 1, message:len())
 | 
						|
                if message:len() == 0 then
 | 
						|
                    break
 | 
						|
                end
 | 
						|
            end
 | 
						|
            newTTL = 0
 | 
						|
            if is26To28 then
 | 
						|
                newTTL = itemMessages[k]["TTL"] - 1
 | 
						|
            end
 | 
						|
            itemMessages[k]["TTL"] = newTTL
 | 
						|
            found = true
 | 
						|
        end
 | 
						|
    end
 | 
						|
    if found == false then
 | 
						|
        clearScreen()
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function generateLocationChecked()
 | 
						|
    memDomain.saveram()
 | 
						|
    data = uRange(0x01FF, 0x101)
 | 
						|
    data[0] = nil
 | 
						|
    return data
 | 
						|
end
 | 
						|
 | 
						|
function setConsumableStacks()
 | 
						|
    memDomain.rom()
 | 
						|
    consumableStacks = {}
 | 
						|
    -- In order shards, tent, cabin, house, heal, pure, soft, ext1, ext2, ext3, ex4
 | 
						|
    consumableStacks[0x35] = 1
 | 
						|
    consumableStacks[0x36] = u8(0x47400) + 1
 | 
						|
    consumableStacks[0x37] = u8(0x47401) + 1
 | 
						|
    consumableStacks[0x38] = u8(0x47402) + 1
 | 
						|
    consumableStacks[0x39] = u8(0x47403) + 1
 | 
						|
    consumableStacks[0x3A] = u8(0x47404) + 1
 | 
						|
    consumableStacks[0x3B] = u8(0x47405) + 1
 | 
						|
    consumableStacks[0x3C] = u8(0x47406) + 1
 | 
						|
    consumableStacks[0x3D] = u8(0x47407) + 1
 | 
						|
    consumableStacks[0x3E] = u8(0x47408) + 1
 | 
						|
    consumableStacks[0x3F] = u8(0x47409) + 1
 | 
						|
end
 | 
						|
 | 
						|
function getEmptyWeaponSlots()
 | 
						|
    memDomain.saveram()
 | 
						|
    ret = {}
 | 
						|
    count = 1
 | 
						|
    slot1 = uRange(0x118, 0x4)
 | 
						|
    slot2 = uRange(0x158, 0x4)
 | 
						|
    slot3 = uRange(0x198, 0x4)
 | 
						|
    slot4 = uRange(0x1D8, 0x4)
 | 
						|
    for i,v in pairs(slot1) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x118 + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    for i,v in pairs(slot2) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x158 + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    for i,v in pairs(slot3) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x198 + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    for i,v in pairs(slot4) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x1D8 + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return ret
 | 
						|
end
 | 
						|
 | 
						|
function getEmptyArmorSlots()
 | 
						|
    memDomain.saveram()
 | 
						|
    ret = {}
 | 
						|
    count = 1
 | 
						|
    slot1 = uRange(0x11C, 0x4)
 | 
						|
    slot2 = uRange(0x15C, 0x4)
 | 
						|
    slot3 = uRange(0x19C, 0x4)
 | 
						|
    slot4 = uRange(0x1DC, 0x4)
 | 
						|
    for i,v in pairs(slot1) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x11C + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    for i,v in pairs(slot2) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x15C + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    for i,v in pairs(slot3) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x19C + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    for i,v in pairs(slot4) do
 | 
						|
        if v == 0 then
 | 
						|
            ret[count] = 0x1DC + i
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return ret
 | 
						|
end
 | 
						|
 | 
						|
function processBlock(block)
 | 
						|
    local msgBlock = block['messages']
 | 
						|
    if msgBlock ~= nil then
 | 
						|
        for i, v in pairs(msgBlock) do
 | 
						|
            if itemMessages[i] == nil then
 | 
						|
                local msg = {TTL=450, message=v, color=0xFFFF0000}
 | 
						|
                itemMessages[i] = msg
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
    local itemsBlock = block["items"]
 | 
						|
    memDomain.saveram()
 | 
						|
    isInGame = u8(0x102)
 | 
						|
    if itemsBlock ~= nil and isInGame ~= 0x00 then
 | 
						|
        if consumableStacks == nil then
 | 
						|
            setConsumableStacks()
 | 
						|
        end
 | 
						|
        memDomain.saveram()
 | 
						|
--         print('ITEMBLOCK: ')
 | 
						|
--         print(itemsBlock)
 | 
						|
        itemIndex = u8(ITEM_INDEX)
 | 
						|
--         print('ITEMINDEX: '..itemIndex)
 | 
						|
        for i, v in pairs(slice(itemsBlock, itemIndex, #itemsBlock)) do
 | 
						|
            -- Minus the offset and add to the correct domain
 | 
						|
            local memoryLocation = v
 | 
						|
            if v >= 0x100 and v <= 0x114 then
 | 
						|
                -- This is a key item
 | 
						|
                memoryLocation = memoryLocation - 0x0E0
 | 
						|
                wU8(memoryLocation, 0x01)
 | 
						|
            elseif v >= 0x1E0 then
 | 
						|
                -- This is a movement item
 | 
						|
                -- Minus Offset (0x100) - movement offset (0xE0)
 | 
						|
                memoryLocation = memoryLocation - 0x1E0
 | 
						|
                -- Canal is a flipped bit
 | 
						|
                if memoryLocation == 0x0C then
 | 
						|
                    wU8(memoryLocation, 0x00)
 | 
						|
                else
 | 
						|
                    wU8(memoryLocation, 0x01)
 | 
						|
                end
 | 
						|
 | 
						|
            elseif v >= 0x16C and v <= 0x1AF then
 | 
						|
                -- This is a gold item
 | 
						|
                amountToAdd = goldLookup[v]
 | 
						|
                biggest = u8(0x01E)
 | 
						|
                medium = u8(0x01D)
 | 
						|
                smallest = u8(0x01C)
 | 
						|
                currentValue = 0x10000 * biggest + 0x100 * medium + smallest
 | 
						|
                newValue = currentValue + amountToAdd
 | 
						|
                newBiggest = math.floor(newValue / 0x10000)
 | 
						|
                newMedium = math.floor(math.fmod(newValue, 0x10000) / 0x100)
 | 
						|
                newSmallest = math.floor(math.fmod(newValue, 0x100))
 | 
						|
                wU8(0x01E, newBiggest)
 | 
						|
                wU8(0x01D, newMedium)
 | 
						|
                wU8(0x01C, newSmallest)
 | 
						|
            elseif v >= 0x115 and v <= 0x11B then
 | 
						|
                -- This is a regular consumable OR a shard
 | 
						|
                -- Minus Offset (0x100) + item offset (0x20)
 | 
						|
                memoryLocation = memoryLocation - 0x0E0
 | 
						|
                currentValue = u8(memoryLocation)
 | 
						|
                amountToAdd = consumableStacks[memoryLocation]
 | 
						|
                if currentValue < 99 then
 | 
						|
                    wU8(memoryLocation, currentValue + amountToAdd)
 | 
						|
                end
 | 
						|
            elseif v >= 0x1B0  and v <= 0x1BB then
 | 
						|
                -- This is an extension consumable
 | 
						|
                memoryLocation = extensionConsumableLookup[v]
 | 
						|
                currentValue = u8(memoryLocation)
 | 
						|
                amountToAdd = consumableStacks[memoryLocation]
 | 
						|
                if currentValue < 99 then
 | 
						|
                    value = currentValue + amountToAdd
 | 
						|
                    if value > 99 then
 | 
						|
                        value = 99
 | 
						|
                    end
 | 
						|
                    wU8(memoryLocation, value)
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        if #itemsBlock ~= itemIndex then
 | 
						|
            wU8(ITEM_INDEX, #itemsBlock)
 | 
						|
        end
 | 
						|
 | 
						|
        memDomain.saveram()
 | 
						|
        weaponIndex = u8(WEAPON_INDEX)
 | 
						|
        emptyWeaponSlots = getEmptyWeaponSlots()
 | 
						|
        lastUsedWeaponIndex = weaponIndex
 | 
						|
--         print('WEAPON_INDEX: '.. weaponIndex)
 | 
						|
        memDomain.saveram()
 | 
						|
        for i, v in pairs(slice(itemsBlock, weaponIndex, #itemsBlock)) do
 | 
						|
            if v >= 0x11C and v <= 0x143 then
 | 
						|
                -- Minus the offset and add to the correct domain
 | 
						|
                local itemValue = v - 0x11B
 | 
						|
                if #emptyWeaponSlots > 0 then
 | 
						|
                    slot = table.remove(emptyWeaponSlots, 1)
 | 
						|
                    wU8(slot, itemValue)
 | 
						|
                    lastUsedWeaponIndex = weaponIndex + i
 | 
						|
                else
 | 
						|
                    break
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        if lastUsedWeaponIndex ~= weaponIndex then
 | 
						|
            wU8(WEAPON_INDEX, lastUsedWeaponIndex)
 | 
						|
        end
 | 
						|
        memDomain.saveram()
 | 
						|
        armorIndex = u8(ARMOR_INDEX)
 | 
						|
        emptyArmorSlots = getEmptyArmorSlots()
 | 
						|
        lastUsedArmorIndex = armorIndex
 | 
						|
--         print('ARMOR_INDEX: '.. armorIndex)
 | 
						|
        memDomain.saveram()
 | 
						|
        for i, v in pairs(slice(itemsBlock, armorIndex, #itemsBlock)) do
 | 
						|
            if v >= 0x144 and v <= 0x16B then
 | 
						|
                -- Minus the offset and add to the correct domain
 | 
						|
                local itemValue = v - 0x143
 | 
						|
                if #emptyArmorSlots > 0 then
 | 
						|
                    slot = table.remove(emptyArmorSlots, 1)
 | 
						|
                    wU8(slot, itemValue)
 | 
						|
                    lastUsedArmorIndex = armorIndex + i
 | 
						|
                else
 | 
						|
                    break
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        if lastUsedArmorIndex ~= armorIndex then
 | 
						|
            wU8(ARMOR_INDEX, lastUsedArmorIndex)
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function difference(a, b)
 | 
						|
    local aa = {}
 | 
						|
    for k,v in pairs(a) do aa[v]=true end
 | 
						|
    for k,v in pairs(b) do aa[v]=nil end
 | 
						|
    local ret = {}
 | 
						|
    local n = 0
 | 
						|
    for k,v in pairs(a) do
 | 
						|
        if aa[v] then n=n+1 ret[n]=v end
 | 
						|
    end
 | 
						|
    return ret
 | 
						|
end
 | 
						|
 | 
						|
function receive()
 | 
						|
    l, e = ff1Socket:receive()
 | 
						|
    if e == 'closed' then
 | 
						|
        if curstate == STATE_OK then
 | 
						|
            print("Connection closed")
 | 
						|
        end
 | 
						|
        curstate = STATE_UNINITIALIZED
 | 
						|
        return
 | 
						|
    elseif e == 'timeout' then
 | 
						|
        print("timeout")
 | 
						|
        return
 | 
						|
    elseif e ~= nil then
 | 
						|
        print(e)
 | 
						|
        curstate = STATE_UNINITIALIZED
 | 
						|
        return
 | 
						|
    end
 | 
						|
    processBlock(json.decode(l))
 | 
						|
 | 
						|
    -- Determine Message to send back
 | 
						|
    memDomain.rom()
 | 
						|
    local playerName = uRange(0x7BCBF, 0x41)
 | 
						|
    playerName[0] = nil
 | 
						|
    local retTable = {}
 | 
						|
    retTable["playerName"] = playerName
 | 
						|
    if StateOKForMainLoop() then
 | 
						|
        retTable["locations"] = generateLocationChecked()
 | 
						|
    end
 | 
						|
    msg = json.encode(retTable).."\n"
 | 
						|
    local ret, error = ff1Socket:send(msg)
 | 
						|
    if ret == nil then
 | 
						|
        print(error)
 | 
						|
    elseif curstate == STATE_INITIAL_CONNECTION_MADE then
 | 
						|
        curstate = STATE_TENTATIVELY_CONNECTED
 | 
						|
    elseif curstate == STATE_TENTATIVELY_CONNECTED then
 | 
						|
        print("Connected!")
 | 
						|
        itemMessages["(0,0)"] = {TTL=240, message="Connected", color="green"}
 | 
						|
        curstate = STATE_OK
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function main()
 | 
						|
    if (is23Or24Or25 or is26To28) == false then
 | 
						|
        print("Must use a version of bizhawk 2.3.1 or higher")
 | 
						|
        return
 | 
						|
    end
 | 
						|
    server, error = socket.bind('localhost', 52980)
 | 
						|
 | 
						|
    while true do
 | 
						|
        gui.drawEllipse(248, 9, 6, 6, "Black", "Yellow")
 | 
						|
        frame = frame + 1
 | 
						|
        drawMessages()
 | 
						|
        if not (curstate == prevstate) then
 | 
						|
            -- console.log("Current state: "..curstate)
 | 
						|
            prevstate = curstate
 | 
						|
        end
 | 
						|
        if (curstate == STATE_OK) or (curstate == STATE_INITIAL_CONNECTION_MADE) or (curstate == STATE_TENTATIVELY_CONNECTED) then
 | 
						|
            if (frame % 60 == 0) then
 | 
						|
                gui.drawEllipse(248, 9, 6, 6, "Black", "Blue")
 | 
						|
                receive()
 | 
						|
            else
 | 
						|
                gui.drawEllipse(248, 9, 6, 6, "Black", "Green")
 | 
						|
            end
 | 
						|
        elseif (curstate == STATE_UNINITIALIZED) then
 | 
						|
            gui.drawEllipse(248, 9, 6, 6, "Black", "White")
 | 
						|
            if  (frame % 60 == 0) then
 | 
						|
                gui.drawEllipse(248, 9, 6, 6, "Black", "Yellow")
 | 
						|
 | 
						|
                drawText(5, 8, "Waiting for client", 0xFFFF0000)
 | 
						|
                drawText(5, 32, "Please start FF1Client.exe", 0xFFFF0000)
 | 
						|
 | 
						|
                -- Advance so the messages are drawn
 | 
						|
                emu.frameadvance()
 | 
						|
                server:settimeout(2)
 | 
						|
                print("Attempting to connect")
 | 
						|
                local client, timeout = server:accept()
 | 
						|
                if timeout == nil then
 | 
						|
                    -- print('Initial Connection Made')
 | 
						|
                    curstate = STATE_INITIAL_CONNECTION_MADE
 | 
						|
                    ff1Socket = client
 | 
						|
                    ff1Socket:settimeout(0)
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        emu.frameadvance()
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
main()
 |