702 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
		
		
			
		
	
	
			702 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| 
								 | 
							
								--Shamelessly based off the FF1 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 itemMessages = {}
							 | 
						||
| 
								 | 
							
								local consumableStacks = nil
							 | 
						||
| 
								 | 
							
								local prevstate = ""
							 | 
						||
| 
								 | 
							
								local curstate =  STATE_UNINITIALIZED
							 | 
						||
| 
								 | 
							
								local zeldaSocket = nil
							 | 
						||
| 
								 | 
							
								local frame = 0
							 | 
						||
| 
								 | 
							
								local gameMode = 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local cave_index
							 | 
						||
| 
								 | 
							
								local triforce_byte
							 | 
						||
| 
								 | 
							
								local game_state
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local u8 = nil
							 | 
						||
| 
								 | 
							
								local wU8 = nil
							 | 
						||
| 
								 | 
							
								local isNesHawk = false
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local shopsChecked = {}
							 | 
						||
| 
								 | 
							
								local shopSlotLeft       = 0x0628
							 | 
						||
| 
								 | 
							
								local shopSlotMiddle     = 0x0629
							 | 
						||
| 
								 | 
							
								local shopSlotRight      = 0x062A
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								--N.B.: you won't find these in a RAM map. They're flag values that the base patch derives from the cave ID.
							 | 
						||
| 
								 | 
							
								local blueRingShopBit       = 0x40
							 | 
						||
| 
								 | 
							
								local potionShopBit         = 0x02
							 | 
						||
| 
								 | 
							
								local arrowShopBit          = 0x08
							 | 
						||
| 
								 | 
							
								local candleShopBit         = 0x10
							 | 
						||
| 
								 | 
							
								local shieldShopBit         = 0x20
							 | 
						||
| 
								 | 
							
								local takeAnyCaveBit        = 0x01
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local sword                 = 0x0657
							 | 
						||
| 
								 | 
							
								local bombs                 = 0x0658
							 | 
						||
| 
								 | 
							
								local maxBombs              = 0x067C
							 | 
						||
| 
								 | 
							
								local keys                  = 0x066E
							 | 
						||
| 
								 | 
							
								local arrow                 = 0x0659
							 | 
						||
| 
								 | 
							
								local bow                   = 0x065A
							 | 
						||
| 
								 | 
							
								local candle                = 0x065B
							 | 
						||
| 
								 | 
							
								local recorder              = 0x065C
							 | 
						||
| 
								 | 
							
								local food                  = 0x065D
							 | 
						||
| 
								 | 
							
								local waterOfLife           = 0x065E
							 | 
						||
| 
								 | 
							
								local magicalRod            = 0x065F
							 | 
						||
| 
								 | 
							
								local raft                  = 0x0660
							 | 
						||
| 
								 | 
							
								local bookOfMagic           = 0x0661
							 | 
						||
| 
								 | 
							
								local ring                  = 0x0662
							 | 
						||
| 
								 | 
							
								local stepladder            = 0x0663
							 | 
						||
| 
								 | 
							
								local magicalKey            = 0x0664
							 | 
						||
| 
								 | 
							
								local powerBracelet         = 0x0665
							 | 
						||
| 
								 | 
							
								local letter                = 0x0666
							 | 
						||
| 
								 | 
							
								local clockItem             = 0x066C
							 | 
						||
| 
								 | 
							
								local heartContainers       = 0x066F
							 | 
						||
| 
								 | 
							
								local partialHearts         = 0x0670
							 | 
						||
| 
								 | 
							
								local triforceFragments     = 0x0671
							 | 
						||
| 
								 | 
							
								local boomerang             = 0x0674
							 | 
						||
| 
								 | 
							
								local magicalBoomerang      = 0x0675
							 | 
						||
| 
								 | 
							
								local magicalShield         = 0x0676
							 | 
						||
| 
								 | 
							
								local rupeesToAdd           = 0x067D
							 | 
						||
| 
								 | 
							
								local rupeesToSubtract      = 0x067E
							 | 
						||
| 
								 | 
							
								local itemsObtained         = 0x0677
							 | 
						||
| 
								 | 
							
								local takeAnyCavesChecked   = 0x0678
							 | 
						||
| 
								 | 
							
								local localTriforce         = 0x0679
							 | 
						||
| 
								 | 
							
								local bonusItemsObtained    = 0x067A
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								itemAPids = {
							 | 
						||
| 
								 | 
							
								    ["Boomerang"] = 7100,
							 | 
						||
| 
								 | 
							
								    ["Bow"] = 7101,
							 | 
						||
| 
								 | 
							
								    ["Magical Boomerang"] = 7102,
							 | 
						||
| 
								 | 
							
								    ["Raft"] = 7103,
							 | 
						||
| 
								 | 
							
								    ["Stepladder"] = 7104,
							 | 
						||
| 
								 | 
							
								    ["Recorder"] = 7105,
							 | 
						||
| 
								 | 
							
								    ["Magical Rod"] = 7106,
							 | 
						||
| 
								 | 
							
								    ["Red Candle"] = 7107,
							 | 
						||
| 
								 | 
							
								    ["Book of Magic"] = 7108,
							 | 
						||
| 
								 | 
							
								    ["Magical Key"] = 7109,
							 | 
						||
| 
								 | 
							
								    ["Red Ring"] = 7110,
							 | 
						||
| 
								 | 
							
								    ["Silver Arrow"] = 7111,
							 | 
						||
| 
								 | 
							
								    ["Sword"] = 7112,
							 | 
						||
| 
								 | 
							
								    ["White Sword"] = 7113,
							 | 
						||
| 
								 | 
							
								    ["Magical Sword"] = 7114,
							 | 
						||
| 
								 | 
							
								    ["Heart Container"] = 7115,
							 | 
						||
| 
								 | 
							
								    ["Letter"] = 7116,
							 | 
						||
| 
								 | 
							
								    ["Magical Shield"] = 7117,
							 | 
						||
| 
								 | 
							
								    ["Candle"] = 7118,
							 | 
						||
| 
								 | 
							
								    ["Arrow"] = 7119,
							 | 
						||
| 
								 | 
							
								    ["Food"] = 7120,
							 | 
						||
| 
								 | 
							
								    ["Water of Life (Blue)"] = 7121,
							 | 
						||
| 
								 | 
							
								    ["Water of Life (Red)"] = 7122,
							 | 
						||
| 
								 | 
							
								    ["Blue Ring"] = 7123,
							 | 
						||
| 
								 | 
							
								    ["Triforce Fragment"] = 7124,
							 | 
						||
| 
								 | 
							
								    ["Power Bracelet"] = 7125,
							 | 
						||
| 
								 | 
							
								    ["Small Key"] = 7126,
							 | 
						||
| 
								 | 
							
								    ["Bomb"] = 7127,
							 | 
						||
| 
								 | 
							
								    ["Recovery Heart"] = 7128,
							 | 
						||
| 
								 | 
							
								    ["Five Rupees"] = 7129,
							 | 
						||
| 
								 | 
							
								    ["Rupee"] = 7130,
							 | 
						||
| 
								 | 
							
								    ["Clock"] = 7131,
							 | 
						||
| 
								 | 
							
								    ["Fairy"] = 7132
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								itemCodes = {
							 | 
						||
| 
								 | 
							
								    ["Boomerang"] = 0x1D,
							 | 
						||
| 
								 | 
							
								    ["Bow"] = 0x0A,
							 | 
						||
| 
								 | 
							
								    ["Magical Boomerang"] = 0x1E,
							 | 
						||
| 
								 | 
							
								    ["Raft"] = 0x0C,
							 | 
						||
| 
								 | 
							
								    ["Stepladder"] = 0x0D,
							 | 
						||
| 
								 | 
							
								    ["Recorder"] = 0x05,
							 | 
						||
| 
								 | 
							
								    ["Magical Rod"] = 0x10,
							 | 
						||
| 
								 | 
							
								    ["Red Candle"] = 0x07,
							 | 
						||
| 
								 | 
							
								    ["Book of Magic"] = 0x11,
							 | 
						||
| 
								 | 
							
								    ["Magical Key"] = 0x0B,
							 | 
						||
| 
								 | 
							
								    ["Red Ring"] = 0x13,
							 | 
						||
| 
								 | 
							
								    ["Silver Arrow"] = 0x09,
							 | 
						||
| 
								 | 
							
								    ["Sword"] = 0x01,
							 | 
						||
| 
								 | 
							
								    ["White Sword"] = 0x02,
							 | 
						||
| 
								 | 
							
								    ["Magical Sword"] = 0x03,
							 | 
						||
| 
								 | 
							
								    ["Heart Container"] = 0x1A,
							 | 
						||
| 
								 | 
							
								    ["Letter"] = 0x15,
							 | 
						||
| 
								 | 
							
								    ["Magical Shield"] = 0x1C,
							 | 
						||
| 
								 | 
							
								    ["Candle"] = 0x06,
							 | 
						||
| 
								 | 
							
								    ["Arrow"] = 0x08,
							 | 
						||
| 
								 | 
							
								    ["Food"] = 0x04,
							 | 
						||
| 
								 | 
							
								    ["Water of Life (Blue)"] = 0x1F,
							 | 
						||
| 
								 | 
							
								    ["Water of Life (Red)"] = 0x20,
							 | 
						||
| 
								 | 
							
								    ["Blue Ring"] = 0x12,
							 | 
						||
| 
								 | 
							
								    ["Triforce Fragment"] = 0x1B,
							 | 
						||
| 
								 | 
							
								    ["Power Bracelet"] = 0x14,
							 | 
						||
| 
								 | 
							
								    ["Small Key"] = 0x19,
							 | 
						||
| 
								 | 
							
								    ["Bomb"] = 0x00,
							 | 
						||
| 
								 | 
							
								    ["Recovery Heart"] = 0x22,
							 | 
						||
| 
								 | 
							
								    ["Five Rupees"] = 0x0F,
							 | 
						||
| 
								 | 
							
								    ["Rupee"] = 0x18,
							 | 
						||
| 
								 | 
							
								    ["Clock"] = 0x21,
							 | 
						||
| 
								 | 
							
								    ["Fairy"] = 0x23
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								--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["ram"]       = function() memory.usememorydomain("RAM") 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["ram"]       = function() memory.usememorydomain("RAM") 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								itemIDNames = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								for key, value in pairs(itemAPids) do
							 | 
						||
| 
								 | 
							
								    itemIDNames[value] = key
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function determineItem(array)
							 | 
						||
| 
								 | 
							
								    memdomain.ram()
							 | 
						||
| 
								 | 
							
								    currentItemsObtained = u8(itemsObtained)
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotSword()
							 | 
						||
| 
								 | 
							
								    local currentSword = u8(sword)
							 | 
						||
| 
								 | 
							
								    wU8(sword, math.max(currentSword, 1))
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotWhiteSword()
							 | 
						||
| 
								 | 
							
								    local currentSword = u8(sword)
							 | 
						||
| 
								 | 
							
								    wU8(sword, math.max(currentSword, 2))
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotMagicalSword()
							 | 
						||
| 
								 | 
							
								    wU8(sword, 3)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotBomb()
							 | 
						||
| 
								 | 
							
								    local currentBombs = u8(bombs)
							 | 
						||
| 
								 | 
							
								    local currentMaxBombs = u8(maxBombs)
							 | 
						||
| 
								 | 
							
								    wU8(bombs, math.min(currentBombs + 4, currentMaxBombs))
							 | 
						||
| 
								 | 
							
								    wU8(0x505, 0x29) -- Fake bomb to show item get.
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotArrow()
							 | 
						||
| 
								 | 
							
								    local currentArrow = u8(arrow)
							 | 
						||
| 
								 | 
							
								    wU8(arrow, math.max(currentArrow, 1))
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotSilverArrow()
							 | 
						||
| 
								 | 
							
								    wU8(arrow, 2)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotBow()
							 | 
						||
| 
								 | 
							
								    wU8(bow, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotCandle()
							 | 
						||
| 
								 | 
							
								    local currentCandle = u8(candle)
							 | 
						||
| 
								 | 
							
								    wU8(candle, math.max(currentCandle, 1))
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotRedCandle()
							 | 
						||
| 
								 | 
							
								    wU8(candle, 2)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotRecorder()
							 | 
						||
| 
								 | 
							
								    wU8(recorder, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotFood()
							 | 
						||
| 
								 | 
							
								    wU8(food, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotWaterOfLifeBlue()
							 | 
						||
| 
								 | 
							
								    local currentWaterOfLife = u8(waterOfLife)
							 | 
						||
| 
								 | 
							
								    wU8(waterOfLife, math.max(currentWaterOfLife, 1))
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotWaterOfLifeRed()
							 | 
						||
| 
								 | 
							
								    wU8(waterOfLife, 2)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotMagicalRod()
							 | 
						||
| 
								 | 
							
								    wU8(magicalRod, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotBookOfMagic()
							 | 
						||
| 
								 | 
							
								    wU8(bookOfMagic, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotRaft()
							 | 
						||
| 
								 | 
							
								    wU8(raft, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotBlueRing()
							 | 
						||
| 
								 | 
							
								    local currentRing = u8(ring)
							 | 
						||
| 
								 | 
							
								    wU8(ring, math.max(currentRing, 1))
							 | 
						||
| 
								 | 
							
								    memDomain.saveram()
							 | 
						||
| 
								 | 
							
								    local currentTunicColor = u8(0x0B92)
							 | 
						||
| 
								 | 
							
								    if currentTunicColor == 0x29 then 
							 | 
						||
| 
								 | 
							
								        wU8(0x0B92, 0x32)
							 | 
						||
| 
								 | 
							
								        wU8(0x0804, 0x32)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotRedRing()
							 | 
						||
| 
								 | 
							
								    wU8(ring, 2)
							 | 
						||
| 
								 | 
							
								    memDomain.saveram()
							 | 
						||
| 
								 | 
							
								    wU8(0x0B92, 0x16)
							 | 
						||
| 
								 | 
							
								    wU8(0x0804, 0x16)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotStepladder()
							 | 
						||
| 
								 | 
							
								    wU8(stepladder, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotMagicalKey()
							 | 
						||
| 
								 | 
							
								    wU8(magicalKey, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotPowerBracelet()
							 | 
						||
| 
								 | 
							
								    wU8(powerBracelet, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotLetter()
							 | 
						||
| 
								 | 
							
								    wU8(letter, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotHeartContainer()
							 | 
						||
| 
								 | 
							
								    local currentHeartContainers = bit.rshift(bit.band(u8(heartContainers), 0xF0), 4)
							 | 
						||
| 
								 | 
							
								    if currentHeartContainers < 16 then
							 | 
						||
| 
								 | 
							
								        currentHeartContainers = math.min(currentHeartContainers + 1, 16)
							 | 
						||
| 
								 | 
							
								        local currentHearts = bit.band(u8(heartContainers), 0x0F) + 1
							 | 
						||
| 
								 | 
							
								        wU8(heartContainers, bit.lshift(currentHeartContainers, 4) + currentHearts)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotTriforceFragment()
							 | 
						||
| 
								 | 
							
								    local triforceByte = 0xFF
							 | 
						||
| 
								 | 
							
								    local newTriforceCount = u8(localTriforce) + 1
							 | 
						||
| 
								 | 
							
								    wU8(localTriforce, newTriforceCount)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotBoomerang()
							 | 
						||
| 
								 | 
							
								    wU8(boomerang, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotMagicalBoomerang()
							 | 
						||
| 
								 | 
							
								    wU8(magicalBoomerang, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotMagicalShield()
							 | 
						||
| 
								 | 
							
								    wU8(magicalShield, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotRecoveryHeart()
							 | 
						||
| 
								 | 
							
								    local currentHearts = bit.band(u8(heartContainers), 0x0F)
							 | 
						||
| 
								 | 
							
								    local currentHeartContainers = bit.rshift(bit.band(u8(heartContainers), 0xF0), 4)
							 | 
						||
| 
								 | 
							
								    if currentHearts < currentHeartContainers then 
							 | 
						||
| 
								 | 
							
								        currentHearts = currentHearts + 1 
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        wU8(partialHearts, 0xFF)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    currentHearts = bit.bor(bit.band(u8(heartContainers), 0xF0), currentHearts)
							 | 
						||
| 
								 | 
							
								    wU8(heartContainers, currentHearts)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotFairy()
							 | 
						||
| 
								 | 
							
								    local currentHearts = bit.band(u8(heartContainers), 0x0F)
							 | 
						||
| 
								 | 
							
								    local currentHeartContainers = bit.rshift(bit.band(u8(heartContainers), 0xF0), 4)
							 | 
						||
| 
								 | 
							
								    if currentHearts < currentHeartContainers then 
							 | 
						||
| 
								 | 
							
								        currentHearts = currentHearts + 3
							 | 
						||
| 
								 | 
							
								        if currentHearts > currentHeartContainers then
							 | 
						||
| 
								 | 
							
								            currentHearts = currentHeartContainers
							 | 
						||
| 
								 | 
							
								            wU8(partialHearts, 0xFF)
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        wU8(partialHearts, 0xFF)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    currentHearts = bit.bor(bit.band(u8(heartContainers), 0xF0), currentHearts)
							 | 
						||
| 
								 | 
							
								    wU8(heartContainers, currentHearts)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotClock()
							 | 
						||
| 
								 | 
							
								    wU8(clockItem, 1)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotFiveRupees()
							 | 
						||
| 
								 | 
							
								    local currentRupeesToAdd = u8(rupeesToAdd)
							 | 
						||
| 
								 | 
							
								    wU8(rupeesToAdd, math.min(currentRupeesToAdd + 5, 255))
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotSmallKey()
							 | 
						||
| 
								 | 
							
								    wU8(keys, math.min(u8(keys) + 1, 9))
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function gotItem(item)
							 | 
						||
| 
								 | 
							
								    --Write itemCode to itemToLift
							 | 
						||
| 
								 | 
							
								    --Write 128 to itemLiftTimer
							 | 
						||
| 
								 | 
							
								    --Write 4 to sound effect queue
							 | 
						||
| 
								 | 
							
								    itemName = itemIDNames[item]
							 | 
						||
| 
								 | 
							
								    itemCode = itemCodes[itemName]
							 | 
						||
| 
								 | 
							
								    wU8(0x505, itemCode)
							 | 
						||
| 
								 | 
							
								    wU8(0x506, 128)
							 | 
						||
| 
								 | 
							
								    wU8(0x602, 4)
							 | 
						||
| 
								 | 
							
								    numberObtained = u8(itemsObtained) + 1
							 | 
						||
| 
								 | 
							
								    wU8(itemsObtained, numberObtained)
							 | 
						||
| 
								 | 
							
								    if itemName == "Boomerang" then gotBoomerang() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Bow" then gotBow() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Magical Boomerang" then gotMagicalBoomerang() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Raft" then gotRaft() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Stepladder" then gotStepladder() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Recorder" then gotRecorder() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Magical Rod" then gotMagicalRod() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Red Candle" then gotRedCandle() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Book of Magic" then gotBookOfMagic() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Magical Key" then gotMagicalKey() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Red Ring" then gotRedRing() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Silver Arrow" then gotSilverArrow() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Sword" then gotSword() end
							 | 
						||
| 
								 | 
							
								    if itemName == "White Sword" then gotWhiteSword() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Magical Sword" then gotMagicalSword() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Heart Container" then gotHeartContainer() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Letter" then gotLetter() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Magical Shield" then gotMagicalShield() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Candle" then gotCandle() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Arrow" then gotArrow() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Food" then gotFood() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Water of Life (Blue)" then gotWaterOfLifeBlue() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Water of Life (Red)" then gotWaterOfLifeRed() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Blue Ring" then gotBlueRing() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Triforce Fragment" then gotTriforceFragment() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Power Bracelet" then gotPowerBracelet() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Small Key" then gotSmallKey() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Bomb" then gotBomb() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Recovery Heart" then gotRecoveryHeart() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Five Rupees" then gotFiveRupees() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Fairy" then gotFairy() end
							 | 
						||
| 
								 | 
							
								    if itemName == "Clock" then gotClock() end
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function StateOKForMainLoop()
							 | 
						||
| 
								 | 
							
								    memDomain.ram()
							 | 
						||
| 
								 | 
							
								    local gameMode = u8(0x12) 
							 | 
						||
| 
								 | 
							
								    return gameMode == 5 
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								local function checkCaveItemObtained()
							 | 
						||
| 
								 | 
							
								    memDomain.ram() 
							 | 
						||
| 
								 | 
							
								    local returnTable = {}
							 | 
						||
| 
								 | 
							
								    returnTable["slot1"] = u8(shopSlotLeft)
							 | 
						||
| 
								 | 
							
								    returnTable["slot2"] = u8(shopSlotMiddle)
							 | 
						||
| 
								 | 
							
								    returnTable["slot3"] = u8(shopSlotRight)
							 | 
						||
| 
								 | 
							
								    returnTable["takeAnys"] = u8(takeAnyCavesChecked)
							 | 
						||
| 
								 | 
							
								    return returnTable
							 | 
						||
| 
								 | 
							
								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", "middle", "bottom", 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 generateOverworldLocationChecked()
							 | 
						||
| 
								 | 
							
								    memDomain.ram()
							 | 
						||
| 
								 | 
							
								    data = uRange(0x067E, 0x81)
							 | 
						||
| 
								 | 
							
								    data[0] = nil
							 | 
						||
| 
								 | 
							
								    return data
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getHCLocation()
							 | 
						||
| 
								 | 
							
								    memDomain.rom()
							 | 
						||
| 
								 | 
							
								    data = u8(0x1789A)
							 | 
						||
| 
								 | 
							
								    return data
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getPBLocation()
							 | 
						||
| 
								 | 
							
								    memDomain.rom()
							 | 
						||
| 
								 | 
							
								    data = u8(0x10CB2)
							 | 
						||
| 
								 | 
							
								    return data
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function generateUnderworld16LocationChecked()
							 | 
						||
| 
								 | 
							
								    memDomain.ram()
							 | 
						||
| 
								 | 
							
								    data = uRange(0x06FE, 0x81)
							 | 
						||
| 
								 | 
							
								    data[0] = nil
							 | 
						||
| 
								 | 
							
								    return data
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function generateUnderworld79LocationChecked()
							 | 
						||
| 
								 | 
							
								    memDomain.ram()
							 | 
						||
| 
								 | 
							
								    data = uRange(0x077E, 0x81)
							 | 
						||
| 
								 | 
							
								    data[0] = nil
							 | 
						||
| 
								 | 
							
								    return data
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function updateTriforceFragments()
							 | 
						||
| 
								 | 
							
								    memDomain.ram()
							 | 
						||
| 
								 | 
							
								    local triforceByte = 0xFF
							 | 
						||
| 
								 | 
							
								    totalTriforceCount = u8(localTriforce)
							 | 
						||
| 
								 | 
							
								    local currentPieces = bit.rshift(triforceByte, 8 - math.min(8, totalTriforceCount))
							 | 
						||
| 
								 | 
							
								    wU8(triforceFragments, currentPieces)
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function processBlock(block)
							 | 
						||
| 
								 | 
							
								    if block ~= nil then
							 | 
						||
| 
								 | 
							
								        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 bonusItems = block["bonusItems"]
							 | 
						||
| 
								 | 
							
								        if bonusItems ~= nil and isInGame then
							 | 
						||
| 
								 | 
							
								            for i, item in ipairs(bonusItems) do
							 | 
						||
| 
								 | 
							
								                memDomain.ram()
							 | 
						||
| 
								 | 
							
								                if i > u8(bonusItemsObtained) then
							 | 
						||
| 
								 | 
							
								                    if u8(0x505) == 0 then
							 | 
						||
| 
								 | 
							
								                        gotItem(item)
							 | 
						||
| 
								 | 
							
								                        wU8(itemsObtained, u8(itemsObtained) - 1)
							 | 
						||
| 
								 | 
							
								                        wU8(bonusItemsObtained, u8(bonusItemsObtained) + 1)
							 | 
						||
| 
								 | 
							
								                    end
							 | 
						||
| 
								 | 
							
								                end
							 | 
						||
| 
								 | 
							
								            end
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								        local itemsBlock = block["items"]
							 | 
						||
| 
								 | 
							
								        memDomain.saveram()
							 | 
						||
| 
								 | 
							
								        isInGame = StateOKForMainLoop()
							 | 
						||
| 
								 | 
							
								        updateTriforceFragments()
							 | 
						||
| 
								 | 
							
								        if itemsBlock ~= nil and isInGame then
							 | 
						||
| 
								 | 
							
								            memDomain.ram()
							 | 
						||
| 
								 | 
							
								            --get item from item code
							 | 
						||
| 
								 | 
							
								            --get function from item
							 | 
						||
| 
								 | 
							
								            --do function
							 | 
						||
| 
								 | 
							
								            for i, item in ipairs(itemsBlock) do
							 | 
						||
| 
								 | 
							
								                memDomain.ram()
							 | 
						||
| 
								 | 
							
								                if u8(0x505) == 0 then
							 | 
						||
| 
								 | 
							
								                    if i > u8(itemsObtained) then
							 | 
						||
| 
								 | 
							
								                        gotItem(item)
							 | 
						||
| 
								 | 
							
								                    end
							 | 
						||
| 
								 | 
							
								                end
							 | 
						||
| 
								 | 
							
								            end
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								        local shopsBlock = block["shops"]
							 | 
						||
| 
								 | 
							
								        if shopsBlock ~= nil then
							 | 
						||
| 
								 | 
							
								            wU8(shopSlotLeft, bit.bor(u8(shopSlotLeft), shopsBlock["left"]))
							 | 
						||
| 
								 | 
							
								            wU8(shopSlotMiddle, bit.bor(u8(shopSlotMiddle), shopsBlock["middle"]))
							 | 
						||
| 
								 | 
							
								            wU8(shopSlotRight, bit.bor(u8(shopSlotRight), shopsBlock["right"]))
							 | 
						||
| 
								 | 
							
								        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 = zeldaSocket: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(0x1F, 0x10)
							 | 
						||
| 
								 | 
							
								    playerName[0] = nil
							 | 
						||
| 
								 | 
							
								    local retTable = {}
							 | 
						||
| 
								 | 
							
								    retTable["playerName"] = playerName
							 | 
						||
| 
								 | 
							
								    if StateOKForMainLoop() then
							 | 
						||
| 
								 | 
							
								        retTable["overworld"] = generateOverworldLocationChecked()
							 | 
						||
| 
								 | 
							
								        retTable["underworld1"] = generateUnderworld16LocationChecked()
							 | 
						||
| 
								 | 
							
								        retTable["underworld2"] = generateUnderworld79LocationChecked()
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    retTable["caves"] = checkCaveItemObtained()
							 | 
						||
| 
								 | 
							
								    memDomain.ram()
							 | 
						||
| 
								 | 
							
								    if gameMode ~= 19 then
							 | 
						||
| 
								 | 
							
								        gameMode = u8(0x12)
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    retTable["gameMode"] = gameMode
							 | 
						||
| 
								 | 
							
								    retTable["overworldHC"] = getHCLocation()
							 | 
						||
| 
								 | 
							
								    retTable["overworldPB"] = getPBLocation()
							 | 
						||
| 
								 | 
							
								    retTable["itemsObtained"] = u8(itemsObtained)
							 | 
						||
| 
								 | 
							
								    msg = json.encode(retTable).."\n"
							 | 
						||
| 
								 | 
							
								    local ret, error = zeldaSocket: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 Zelda1Client.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
							 | 
						||
| 
								 | 
							
								                    zeldaSocket = client
							 | 
						||
| 
								 | 
							
								                    zeldaSocket:settimeout(0)
							 | 
						||
| 
								 | 
							
								                end
							 | 
						||
| 
								 | 
							
								            end
							 | 
						||
| 
								 | 
							
								        end
							 | 
						||
| 
								 | 
							
								        emu.frameadvance()
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								main()
							 |