Kaphotics Posted August 3, 2011 Posted August 3, 2011 (edited) 5th Gen RNG Suite it displays stuff for copypasting in the console window! -- General Parameters for current game and setup (english) local game=0 -- 0 for white, 1 for black local rng=0x02216244-0x20*game -- PRNG Seed Location local mtrng=0x02215374-0x20*game -- Mersenne Twister Table Top local mac=0x123456 -- MAC Address of Emulator local pos_m=0x0224F92C-0x20*game -- Map Position -> XYZ local storage=0x02000200 local trackcgear=0 -- 0 on, 1 off; disable for Standard Abuse, enable for Entralink Abuse local research=0 -- 0 on, 1 off; only enable for dev features (unneeded) -- Setup Terminology abbreviations; from FractalFusion local bnd,br,bxr=bit.band,bit.bor,bit.bxor local rshift, lshift=bit.rshift, bit.lshift local mdword=memory.readdwordunsigned local mword=memory.readwordunsigned local mbyte=memory.readbyteunsigned local wdword=memory.writedword -- Setup initial variables, rest of script detection will take care of them local initl=0 local inith=0 local initm=0 local adv=0 local jump1=0 local jump2=0 local jump3=0 local jump4=0 local jump5=0 local jump6=0 local jump7=0 local jump8=0 local jump9=0 local jump10=0 local jump11=0 local jump12=0 local jump13=0 local jump14=0 local jump15=0 local jump16=0 local jump17=0 local jump18=0 local jump19=0 local jump20=0 local total=0 local last=0 local lastm=0 local lmtp=0 local steptable=0 local mtf=0 local mttrack=0 local nextmt=0 local second=0 local minute=0 local hour=0 local cgearoff=0 local cachevalue=0 local notrestored=0 local wasrestored=0 -- S frame detection function; works off of seeing how many times the lower half was advanced -- Lua sucks and only allows 16 bit multiplication, so 32 bit multiplication can't be used -- The lower seed is advanced as follows, if observed as a standalone 32 bit number: -- SEED1 = (0x6C078965 * SEED1) + 0x00269EC3; from Kazo function next(s) local a=0x6C07*(s%65536)+rshift(s,16)*0x8965 local b=0x8965*(s%65536)+(a%65536)*65536+0x00269EC3 local c=b%4294967296 return c end -- To predict Mersenne advancement, it's a little harder. Copied and adapted pre-existing Lua -- http://code.google.com/p/gocha-tas/source/browse/trunk/Scripts/mt19937.lua?r=117 -- Mersenne Twister: A random number generator -- ported to Lua by gocha, based on mt19937ar.c module("mt19937", package.seeall) require "bit" -- Period parameters local N = 624 local M = 397 local MATRIX_A = 0x9908b0df -- constant vector a local UPPER_MASK = 0x80000000 -- most significant w-r bits local LOWER_MASK = 0x7fffffff -- least significant r bits local mt = {} -- the array for the state vector local mti = N + 1 -- mti==N+1 means mt[N] is not initialized -- initializes mt[N] with a seed function randomseed(s) s = bit.band(s, 0xffffffff) mt[1] = s for i = 1, N - 1 do -- s = 1812433253 * (bit.bxor(s, bit.rshift(s, 30))) + i s = bit.bxor(s, bit.rshift(s, 30)) local s_lo = bit.band(s, 0xffff) local s_hi = bit.rshift(s, 16) local s_lo2 = bit.band(1812433253 * s_lo, 0xffffffff) local s_hi2 = bit.band(1812433253 * s_hi, 0xffff) s = bit.bor(bit.lshift(bit.rshift(s_lo2, 16) + s_hi2, 16), bit.band(s_lo2, 0xffff)) -- s = bit.band(s + i, 0xffffffff) local s_lim = -bit.tobit(s) -- assumes i<2^31 if (s_lim > 0 and s_lim <= i) then s = i - s_lim else s = s + i end mt[i+1] = s -- See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. -- In the previous versions, MSBs of the seed affect -- only MSBs of the array mt[]. -- 2002/01/09 modified by Makoto Matsumoto end mti = N end local mag01 = { 0, MATRIX_A } -- mag01[x] = x * MATRIX_A for x=0,1 -- generates a random number on [0,0xffffffff]-interval function random_int32() local y if (mti >= N) then -- generate N words at one time local kk if (mti == N + 1) then -- if init_genrand() has not been called, mt19937.randomseed(5489) -- a default initial seed is used end for kk = 1, N - M do y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK)) mt[kk] = bit.bxor(mt[kk+M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)]) end for kk = N - M + 1, N - 1 do y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK)) mt[kk] = bit.bxor(mt[kk+(M-N)], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)]) end y = bit.bor(bit.band(mt[N], UPPER_MASK), bit.band(mt[1], LOWER_MASK)) mt[N] = bit.bxor(mt[M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)]) mti = 0 end y = mt[mti+1] mti = mti + 1 return y end function random(...) -- local r = mt19937.random_int32() * (1.0/4294967296.0) local rtemp = mt19937.random_int32() local r = (bit.band(rtemp, 0x7fffffff) * (1.0/4294967296.0)) + (bit.tobit(rtemp) < 0 and 0.5 or 0) local arg = {...} if #arg == 0 then return r elseif #arg == 1 then local u = math.floor(arg[1]) if 1 <= u then return math.floor(r*u)+1 else error("bad argument #1 to 'random' (internal is empty)") end elseif #arg == 2 then local l, u = math.floor(arg[1]), math.floor(arg[2]) if l <= u then return math.floor((r*(u-l+1))+l) else error("bad argument #2 to 'random' (internal is empty)") end else error("wrong number of arguments") end end -- Lua script begin! while true do wdword(storage,1) -- setup every loop seed2=mdword(rng+4) seed1=mdword(rng) adv=0 test=last mtv=mdword(mtrng) mtp=mdword(mtrng+0x9C0) delay=mdword(0x02FFFC3C) timehex=mdword(0x023FFDEC) datehex=mdword(0x023FFDE8) hour=string.format("%02X",(timehex%0x100)%0x40) -- memory stores as decimal, but Lua reads as hex. Convert. minute=string.format("%02X",(rshift(timehex%0x10000,8))) second=string.format("%02X",(mbyte(0x02FFFDEE))) year=string.format("%02X",(mbyte(0x02FFFDE8))) month=string.format("%02X",(mbyte(0x02FFFDE9))) day=string.format("%02X",(mbyte(0x02FFFDEA))) -- display seeds every loop gui.text(1,10,string.format("Current: %08X%08X",seed2,seed1)) gui.text(1,180,string.format("Initial: %08X%08X",inith,initl)) gui.text(1,170, string.format("M: %d, X: %d, Y: %d, Z: %d", mword(pos_m), mword(pos_m+0x6), mword(pos_m+0xE), mword(pos_m+0xA))) -- Check to see if the RNG advanced from the last value while seed1~=0 and seed2~=0 and delay > 2 do if adv>200 then -- RNG advanced a bunch, or the game/script was reset. Reset variables then stop loop. steptable=0 adv =0 jump1=0 jump2=0 jump3=0 jump4=0 jump5=0 jump6=0 jump7=0 jump8=0 jump9=0 jump10=0 jump11=0 jump12=0 jump13=0 jump14=0 jump15=0 jump16=0 jump17=0 jump18=0 jump19=0 jump20=0 if mdword(storage)==1 and delay>3 and mdword(storage+0x4*2)~=0 then print(""..string.format("Restoring session. Please Wait...")) steptable=mdword(storage+0x4*1) -- restore mt initm=mdword(storage+0x4*2) lastm=mdword(storage+0x4*7) randomseed(initm) i=624*steptable+1 while i>0 do -- restore internal mt frame nextmt=math.floor(random_int32()) i=i-1 end mttrack=1 -- turn on tracking inith=mdword(storage+0x4*4) -- restore PRNG initl=mdword(storage+0x4*3) cacheseed=mdword(storage+0x4*5) cachevalue=mdword(storage+0x4*6) lastm=mtv mtv=lastm lmtp=mtp if initm==0 or inith==0 or initl==0 then print(""..string.format("Save state's session did not start with script.")) print(""..string.format("Either load a valid save state or resume with this one.")) initl=mdword(rng) -- reset to session inith=mdword(rng+4) mttrack=0 emu.pause() total=0 steptable=0 mtf=0 lmtp=mtp steptable=0 else print(""..string.format("PRNG: %08X%08X",inith,initl)) print(""..string.format("MTRNG: %08X", initm)) last=cacheseed total=cachevalue -- restored frame end cgearoff=mdword(storage+0x4*8) -- remember if c-gear was turned on or not notrestored=1 wasrestored=1 elseif initm==inith then print(""..string.format("Game Reset. Re-initializing.")) total=0 steptable=0 mtf=0 lmtp=mtp initl=mdword(rng) inith=mdword(rng+4) initm=mdword(mtrng) if inith>0x7FFFFFFF then wdword(storage+0x4*4,inith-0x100000000) else wdword(storage+0x4*4,inith) end -- dumb storage problems, have to make sure they are recognized as the right number type before storage if initl>0x7FFFFFFF then wdword(storage+0x4*3,initl-0x100000000) else wdword(storage+0x4*3,initl) end if initm>0x7FFFFFFF then wdword(storage+0x4*2,initm-0x100000000) else wdword(storage+0x4*2,initm) end lastm=initm randomseed(initm) mttrack=1 -- enable mersenne tracking nextmt=random_int32() -- get first untempered mersenne value, this is the value that will replace the MTRNG seed in the memory when the table is redone cgearenoff=0 wasrestored=0 print(""..string.format("Session Initial Seed: %08X%08X",inith,initl)) --print(""..string.format("Next: %08X", nextmt)) -- debug -- see if initial seeding happened (high32=mtseed) mttrack=1 -- enable tracking print(""..string.format("Initial Seeding Detected. MTRNG Seed: %08X", initm)) else print(""..string.format("Foreign Save State Detected, or Restart didn't refresh. Reset again.")) total=0 steptable=0 mtf=0 lmtp=mtp initl=mdword(rng) inith=mdword(rng+4) initm=mdword(mtrng) if inith>0x7FFFFFFF then wdword(storage+0x4*4,inith-0x100000000) else wdword(storage+0x4*4,inith) end if initl>0x7FFFFFFF then wdword(storage+0x4*3,initl-0x100000000) else wdword(storage+0x4*3,initl) end if initm>0x7FFFFFFF then wdword(storage+0x4*2,initm-0x100000000) else wdword(storage+0x4*2,initm) end lastm=initm randomseed(initm) mttrack=0 -- disable mersenne tracking nextmt=random_int32() -- get first untempered mersenne value, this is the value that will replace the MTRNG seed in the memory when the table is redone cgearenoff=0 wasrestored=0 end print(""..string.format("")) -- Visual Line to separate. break elseif test~=seed1 then -- RNG advanced at least once. Lets advance once and repeat the loop. test=next(test) adv=adv+1 elseif test==seed1 then if adv > 0 then -- Refresh Frame Advancement Table if there's more than one advancement this frame. jump20=jump19 jump19=jump18 jump18=jump17 jump17=jump16 jump16=jump15 jump15=jump14 jump14=jump13 jump13=jump12 jump12=jump11 jump11=jump10 jump10=jump9 jump9=jump8 jump8=jump7 jump7=jump6 jump6=jump5 jump5=jump4 jump4=jump3 jump3=jump2 jump2=jump1 jump1=adv end break -- last frame's advanced RNG value matches the current. Stop loop. end end gui.text(180,10,string.format("%d/%d/%d",month,day,2000+year)) -- Display Date gui.text(180,19,string.format("%02d:%02d:%02d",hour,minute,second,delay)) -- Display Time -- Check to see if the MTRNG changed, only if tracking is enabled. if mttrack==1 and notrestored == 0 then if (lmtp>mtp and delay > 50 and notrestored==0) or (lmtp==mtp and lastm~=mtv) then strmtv=string.format("%08X",mtv) -- Mersenne Twister untempered is in one format while the memory is in another strnmt=string.format("%08X",nextmt) -- Convert to a string hex so that they can be equated when their decimal isn't if strmtv~=strnmt then -- New untempered table value isn't as predicted, so the c-gear was turned on! mttrack=1 -- print(strmtv,strnmt,string.format("%08X",lastm)) -- debug for bad initialize if wasrestored==1 then print(""..string.format("Earlier restoration may have failed. Double Check.")) print(""..string.format("If C-Gear was just turned on this frame, ignore.")) print(""..string.format("")) wasrestored=0 end -- mttrack=0 --else print(""..string.format("C-Gear turned on. Determining C-Gear Seed and restarting tracking.")) steptable=1 wdword(storage+0x4*1, steptable) -- Finding the C-Gear seed you hit -- Load Time Values hour=string.format("%02X",(timehex%0x100)%0x40) -- Memory stores as decimal, but Lua reads as hex. Convert. minute=string.format("%02X",(rshift(timehex%0x10000,8))) second=string.format("%02X",(mbyte(0x02FFFDEE))) year=string.format("%02X",(mbyte(0x02FFFDE8))) month=string.format("%02X",(mbyte(0x02FFFDE9))) day=string.format("%02X",(mbyte(0x02FFFDEA))) ab=(month*day+minute+second)%256 cd=hour cgd=delay%65536-1 -- Delay from a frame before is used. abcd=ab*0x100+cd efgh=(year+cgd)%0x10000 tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000 randomseed(tempcgear) trialseed=random_int32() tempcgearuntemp=string.format("%08X",trialseed) if strmtv~=tempcgearuntemp then second=second-1 -- Subtract a second to check a different set. if second < 0 then -- Balaning minutes second=59 minute=minute-1 if minute<0 then -- Balancing Hours minute=59 hour=hour-1 end end ab=(month*day+minute+second)%256 -- Rebuild seed, try again. cd=hour abcd=ab*0x100+cd efgh=(year+cgd)%0x10000 tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000 randomseed(tempcgear) trialseed=random_int32() tempcgearuntemp=string.format("%08X",trialseed) end initm=tempcgear print(""..string.format("C-Gear Seed: %08X Delay: %d",tempcgear,cgd)) print(""..string.format("")) -- Visual Blank Line cgearenabled=2 wdword(storage+0x4*8,cgearenabled) if initm>0x7FFFFFFF then wdword(storage+0x4*2,initm-0x100000000) else wdword(storage+0x4*2,initm) end i=0 while i~=624 do -- get the next untempered for the cgear nextmt=math.floor(random_int32()) i=i+1 end --end else -- untempered is as predicted -> predict next one for when the time rolls around i=0 while i~=624 do -- do 624 iterations to build the remaining 623 and the first of the next. nextmt=math.floor(random_int32()) i=i+1 end --print(""..string.format("Next: %08X", nextmt)) -- debug steptable=steptable+1 -- mersenne twister has a new table as the counter is reset to 0; tables++ wdword(storage+0x4*1, steptable) -- save state storage of table refreshes end end gui.text(1,160,string.format("MTRNG Seed: %08X",initm)) gui.text(1,150,string.format("Frame: %d",mtf)) -- gui.text(1,38,string.format("next mt: %08X", nextmt)) -- debug end -- Advancement Tracking for the PRNG and Mersenne Twister total=adv+total -- total advancements = advancements on this frame + total advancements from previous frames if total-cachevalue>200 then -- check to see if we should refresh the cached value cachevalue=total end mtf=mtp+(steptable-1)*624 -- Mersenne Twister Frame = Pointer Value + (TableRefresh-1)*624 ; this accounts for the initial value of 0x270 which is actually zero gui.text(1,19,string.format("Frame: %d", total)) -- Display PRNG Frame; total advancements since the initial seed -- If the user specifies they want to use the C-Gear if trackcgear==0 then -- C-Gear Seed Generation Loop ab=(month*day+minute+second)%256 -- Build Seed cd=hour cgd=delay%65536+1 abcd=ab*0x100+cd efgh=(year+cgd)%0x10000 betaseed=ab*0x1000000+cd*0x10000+efgh -- Seed before MAC applied cgearseed=betaseed+mac -- Seed after MAC applied, return this value. gui.text(1,130,string.format("Next C-Gear: %08X",cgearseed)) -- Display the C-Gear Seed of the next frame gui.text(1,140,string.format("Delay: %d", delay)) -- Display Current Delay elseif cgearenabled==2 then gui.text(1,130,string.format(" C-GEAR WAS TURNED ON: SEE NEW MTRNG SEED")) end -- If user specifies they want to see the frame advancement chart if research==0 then -- Display framebased advancement table gui.text(1,37,string.format("%d", jump1)) gui.text(1,46,string.format("%d", jump2)) gui.text(1,55,string.format("%d", jump3)) gui.text(1,64,string.format("%d", jump4)) gui.text(1,73,string.format("%d", jump5)) gui.text(1,82,string.format("%d", jump6)) gui.text(1,91,string.format("%d", jump7)) gui.text(1,100,string.format("%d", jump8)) gui.text(1,109,string.format("%d", jump9)) gui.text(1,118,string.format("%d", jump10)) gui.text(20,37,string.format("%d", jump11)) gui.text(20,46,string.format("%d", jump12)) gui.text(20,55,string.format("%d", jump13)) gui.text(20,64,string.format("%d", jump14)) gui.text(20,73,string.format("%d", jump15)) gui.text(20,82,string.format("%d", jump16)) gui.text(20,91,string.format("%d", jump17)) gui.text(20,100,string.format("%d", jump18)) gui.text(20,109,string.format("%d", jump19)) gui.text(20,118,string.format("%d", jump20)) end -- Set Up variables for next frame's pass lmtp=mtp last=seed1 lastm=mtv if lastm>0x7FFFFFFF then wdword(storage+0x4*7,lastm-0x100000000) else wdword(storage+0x4*7,lastm) end wdword(storage+0x4*6,total) if seed1>0x7FFFFFFF then wdword(storage+0x4*5,seed1-0x100000000) else wdword(storage+0x4*5,seed1) end notrestored=0 -- End Lua emu.frameadvance() end still may have some bugs to work out, however it's pretty much done edit: Added C-Gear detection and it will properly track the frames if you turn on the C-Gear. It also tells you what C-Gear seed you hit in addition to delay in the Console. The value that seeds the MTRNG is displayed on the HUD (changed from only displaying the initial seed from the start of the game). edit2: fixed bugs and allowed people to turn off the frame chart and C-Gear prediction. dubbed "research" and "trackcgear" different from image: frame advancement chart is displayed only by turning on research mode, and it's more collapsed than above (changed). c-gear tracking and research is by default off -- edit3: added save state support old version without state support: -- General Parameters for current game and setup(currently English White) local rng=0x02216244 -- PRNG Seed Location local mtrng=0x02215374 -- Mersenne Twister Table Top local mac=0x123456 -- MAC Address of Emulator local pos_m=0x0224F92C -- Map Position -> XYZ local trackcgear=1 -- 0 on, 1 off; disable for Standard Abuse, enable for Entralink Abuse local research=1 -- 0 on, 1 off; only enable for dev features (unneeded) -- Setup Terminology abbreviations; from FractalFusion local bnd,br,bxr=bit.band,bit.bor,bit.bxor local rshift, lshift=bit.rshift, bit.lshift local mdword=memory.readdwordunsigned local mword=memory.readwordunsigned local mbyte=memory.readbyteunsigned -- Setup initial variables, rest of script detection will take care of them local initl=0 local inith=0 local initm=0 local adv=0 local jump1=0 local jump2=0 local jump3=0 local jump4=0 local jump5=0 local jump6=0 local jump7=0 local jump8=0 local jump9=0 local jump10=0 local jump11=0 local jump12=0 local jump13=0 local jump14=0 local jump15=0 local jump16=0 local jump17=0 local jump18=0 local jump19=0 local jump20=0 local total=0 local last=0 local lastm=0 local lmtp=0 local steptable=0 local mtf=0 local mttrack=0 local nextmt=0 local second=0 local minute=0 local hour=0 local cgearenabled=0 -- S frame detection function; works off of seeing how many times the lower half was advanced -- Lua sucks and only allows 16 bit multiplication, so 32 bit multiplication can't be used -- The lower seed is advanced as follows, if observed as a standalone 32 bit number: -- SEED1 = (0x6C078965 * SEED1) + 0x00269EC3; from Kazo function next(s) local a=0x6C07*(s%65536)+rshift(s,16)*0x8965 local b=0x8965*(s%65536)+(a%65536)*65536+0x00269EC3 local c=b%4294967296 return c end -- To predict Mersenne advancement, it's a little harder. Copied and adapted pre-existing Lua -- http://code.google.com/p/gocha-tas/source/browse/trunk/Scripts/mt19937.lua?r=117 -- Mersenne Twister: A random number generator -- ported to Lua by gocha, based on mt19937ar.c module("mt19937", package.seeall) require "bit" -- Period parameters local N = 624 local M = 397 local MATRIX_A = 0x9908b0df -- constant vector a local UPPER_MASK = 0x80000000 -- most significant w-r bits local LOWER_MASK = 0x7fffffff -- least significant r bits local mt = {} -- the array for the state vector local mti = N + 1 -- mti==N+1 means mt[N] is not initialized -- initializes mt[N] with a seed function randomseed(s) s = bit.band(s, 0xffffffff) mt[1] = s for i = 1, N - 1 do -- s = 1812433253 * (bit.bxor(s, bit.rshift(s, 30))) + i s = bit.bxor(s, bit.rshift(s, 30)) local s_lo = bit.band(s, 0xffff) local s_hi = bit.rshift(s, 16) local s_lo2 = bit.band(1812433253 * s_lo, 0xffffffff) local s_hi2 = bit.band(1812433253 * s_hi, 0xffff) s = bit.bor(bit.lshift(bit.rshift(s_lo2, 16) + s_hi2, 16), bit.band(s_lo2, 0xffff)) -- s = bit.band(s + i, 0xffffffff) local s_lim = -bit.tobit(s) -- assumes i<2^31 if (s_lim > 0 and s_lim <= i) then s = i - s_lim else s = s + i end mt[i+1] = s -- See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. -- In the previous versions, MSBs of the seed affect -- only MSBs of the array mt[]. -- 2002/01/09 modified by Makoto Matsumoto end mti = N end local mag01 = { 0, MATRIX_A } -- mag01[x] = x * MATRIX_A for x=0,1 -- generates a random number on [0,0xffffffff]-interval function random_int32() local y if (mti >= N) then -- generate N words at one time local kk if (mti == N + 1) then -- if init_genrand() has not been called, mt19937.randomseed(5489) -- a default initial seed is used end for kk = 1, N - M do y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK)) mt[kk] = bit.bxor(mt[kk+M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)]) end for kk = N - M + 1, N - 1 do y = bit.bor(bit.band(mt[kk], UPPER_MASK), bit.band(mt[kk+1], LOWER_MASK)) mt[kk] = bit.bxor(mt[kk+(M-N)], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)]) end y = bit.bor(bit.band(mt[N], UPPER_MASK), bit.band(mt[1], LOWER_MASK)) mt[N] = bit.bxor(mt[M], bit.rshift(y, 1), mag01[1 + bit.band(y, 1)]) mti = 0 end y = mt[mti+1] mti = mti + 1 return y end function random(...) -- local r = mt19937.random_int32() * (1.0/4294967296.0) local rtemp = mt19937.random_int32() local r = (bit.band(rtemp, 0x7fffffff) * (1.0/4294967296.0)) + (bit.tobit(rtemp) < 0 and 0.5 or 0) local arg = {...} if #arg == 0 then return r elseif #arg == 1 then local u = math.floor(arg[1]) if 1 <= u then return math.floor(r*u)+1 else error("bad argument #1 to 'random' (internal is empty)") end elseif #arg == 2 then local l, u = math.floor(arg[1]), math.floor(arg[2]) if l <= u then return math.floor((r*(u-l+1))+l) else error("bad argument #2 to 'random' (internal is empty)") end else error("wrong number of arguments") end end -- Lua script begin! while true do -- setup every loop seed2=mdword(rng+4) seed1=mdword(rng) adv=0 test=last mtv=mdword(mtrng) mtp=mdword(mtrng+0x9C0) delay=mdword(0x02FFFC3C) timehex=mdword(0x023FFDEC) datehex=mdword(0x023FFDE8) hour=string.format("%02X",(timehex%0x100)%0x40) -- memory stores as decimal, but Lua reads as hex. Convert. minute=string.format("%02X",(rshift(timehex%0x10000,8))) second=string.format("%02X",(mbyte(0x02FFFDEE))) year=string.format("%02X",(mbyte(0x02FFFDE8))) month=string.format("%02X",(mbyte(0x02FFFDE9))) day=string.format("%02X",(mbyte(0x02FFFDEA))) -- display seeds every loop gui.text(1,10,string.format("Current: %08X%08X",seed2,seed1)) gui.text(1,180,string.format("Initial: %08X%08X",inith,initl)) gui.text(1,170, string.format("M: %d, X: %d, Y: %d, Z: %d", mword(pos_m), mword(pos_m+0x6), mword(pos_m+0xE), mword(pos_m+0xA))) -- Check to see if the RNG advanced from the last value while seed1~=0 and seed2~=0 do if adv>200 then -- RNG advanced a bunch, or the game/script was reset. Reset variables then stop loop. print(""..string.format("Detected a reset or massive advancement. Re-initializing.")) adv =0 total=0 jump1=0 jump2=0 jump3=0 jump4=0 jump5=0 jump6=0 jump7=0 jump8=0 jump9=0 jump10=0 jump11=0 jump12=0 jump13=0 jump14=0 jump15=0 jump16=0 jump17=0 jump18=0 jump19=0 jump20=0 steptable=0 mtf=0 lmtp=mtp initl=mdword(rng) inith=mdword(rng+4) initm=mdword(mtrng) lastm=initm randomseed(initm) mttrack=0 -- disable mersenne tracking nextmt=random_int32() -- get first untempered mersenne value, this is the value that will replace the MTRNG seed in the memory when the table is redone cgearenabled=0 print(""..string.format("Session Initial Seed: %08X%08X",inith,initl)) --print(""..string.format("Next: %08X", nextmt)) -- debug if initm==inith then -- see if initial seeding happened (high32=mtseed) mttrack=1 -- enable tracking print(""..string.format("Initial Seeding Detected. MTRNG Seed: %08X", initm)) else print(""..string.format("Save State Detected. Unable to determine initial MTRNG")) end print(""..string.format("")) -- Visual Line to separate. break elseif test~=seed1 then -- RNG advanced at least once. Lets advance once and repeat the loop. test=next(test) adv=adv+1 elseif test==seed1 then if adv > 0 then -- Refresh Frame Advancement Table if there's more than one advancement this frame. jump20=jump19 jump19=jump18 jump18=jump17 jump17=jump16 jump16=jump15 jump15=jump14 jump14=jump13 jump13=jump12 jump12=jump11 jump11=jump10 jump10=jump9 jump9=jump8 jump8=jump7 jump7=jump6 jump6=jump5 jump5=jump4 jump4=jump3 jump3=jump2 jump2=jump1 jump1=adv end break -- last frame's advanced RNG value matches the current. Stop loop. end end gui.text(180,10,string.format("%d/%d/%d",month,day,2000+year)) -- Display Date gui.text(180,19,string.format("%02d:%02d:%02d",hour,minute,second,delay)) -- Display Time -- Check to see if the MTRNG changed, only if tracking is enabled. if mttrack==1 then if (lmtp>mtp and delay > 50) or (lmtp==mtp and lastm~=mtv) then strmtv=string.format("%08X",mtv) -- Mersenne Twister untempered is in one format while the memory is in another strnmt=string.format("%08X",nextmt) -- Convert to a string hex so that they can be equated when their decimal isn't if strmtv~=strnmt then -- New untempered table value isn't as predicted, so the c-gear was turned on! mttrack=1 print(""..string.format("C-Gear turned on. Determining C-Gear Seed and restarting tracking.")) steptable=1 -- Finding the C-Gear seed you hit -- Load Time Values hour=string.format("%02X",(timehex%0x100)%0x40) -- Memory stores as decimal, but Lua reads as hex. Convert. minute=string.format("%02X",(rshift(timehex%0x10000,8))) second=string.format("%02X",(mbyte(0x02FFFDEE))) year=string.format("%02X",(mbyte(0x02FFFDE8))) month=string.format("%02X",(mbyte(0x02FFFDE9))) day=string.format("%02X",(mbyte(0x02FFFDEA))) ab=(month*day+minute+second)%256 cd=hour cgd=delay%65536-1 -- Delay from a frame before is used. abcd=ab*0x100+cd efgh=(year+cgd)%0x10000 tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000 randomseed(tempcgear) trialseed=random_int32() tempcgearuntemp=string.format("%08X",trialseed) if strmtv~=tempcgearuntemp then second=second-1 -- Subtract a second to check a different set. if second < 0 then -- Balaning minutes second=59 minute=minute-1 if minute<0 then -- Balancing Hours minute=59 hour=hour-1 end end ab=(month*day+minute+second)%256 -- Rebuild seed, try again. cd=hour abcd=ab*0x100+cd efgh=(year+cgd)%0x10000 tempcgear=(ab*0x1000000+cd*0x10000+efgh+mac)%0x100000000 randomseed(tempcgear) trialseed=random_int32() tempcgearuntemp=string.format("%08X",trialseed) end initm=tempcgear print(""..string.format("C-Gear Seed: %08X Delay: %d",tempcgear,cgd)) print(""..string.format("")) -- Visual Blank Line cgearenabled=1 i=0 while i~=624 do -- get the next untempered for the cgear nextmt=math.floor(random_int32()) i=i+1 end else -- untempered is as predicted -> predict next one for when the time rolls around i=0 while i~=624 do -- do 624 iterations to build the remaining 623 and the first of the next. nextmt=math.floor(random_int32()) i=i+1 end --print(""..string.format("Next: %08X", nextmt)) -- debug steptable=steptable+1 -- mersenne twister has a new table as the counter is reset to 0; tables++ end end gui.text(1,160,string.format("MTRNG Seed: %08X",initm)) gui.text(1,150,string.format("Frame: %d",mtf)) -- gui.text(1,38,string.format("next mt: %08X", nextmt)) -- debug end -- Advancement Tracking for the PRNG and Mersenne Twister total=adv+total -- total advancements = advancements on this frame + total advancements from previous frames mtf=mtp+(steptable-1)*624 -- Mersenne Twister Frame = Pointer Value + (TableRefresh-1)*624 ; this accounts for the initial value of 0x270 which is actually zero gui.text(1,19,string.format("Frame: %d", total)) -- Display PRNG Frame; total advancements since the initial seed -- If the user specifies they want to use the C-Gear if trackcgear==0 then -- C-Gear Seed Generation Loop ab=(month*day+minute+second)%256 -- Build Seed cd=hour cgd=delay%65536+1 abcd=ab*0x100+cd efgh=(year+cgd)%0x10000 betaseed=ab*0x1000000+cd*0x10000+efgh -- Seed before MAC applied cgearseed=betaseed+mac -- Seed after MAC applied, return this value. gui.text(1,130,string.format("Next C-Gear: %08X",cgearseed)) -- Display the C-Gear Seed of the next frame gui.text(1,140,string.format("Delay: %d", delay)) -- Display Current Delay elseif cgearenabled==1 then gui.text(1,130,string.format(" C-GEAR WAS TURNED ON: SEE NEW MTRNG SEED")) end -- If user specifies they want to see the frame advancement chart if research==0 then -- Display framebased advancement table gui.text(1,37,string.format("%d", jump1)) gui.text(1,46,string.format("%d", jump2)) gui.text(1,55,string.format("%d", jump3)) gui.text(1,64,string.format("%d", jump4)) gui.text(1,73,string.format("%d", jump5)) gui.text(1,82,string.format("%d", jump6)) gui.text(1,91,string.format("%d", jump7)) gui.text(1,100,string.format("%d", jump8)) gui.text(1,109,string.format("%d", jump9)) gui.text(1,118,string.format("%d", jump10)) gui.text(20,37,string.format("%d", jump11)) gui.text(20,46,string.format("%d", jump12)) gui.text(20,55,string.format("%d", jump13)) gui.text(20,64,string.format("%d", jump14)) gui.text(20,73,string.format("%d", jump15)) gui.text(20,82,string.format("%d", jump16)) gui.text(20,91,string.format("%d", jump17)) gui.text(20,100,string.format("%d", jump18)) gui.text(20,109,string.format("%d", jump19)) gui.text(20,118,string.format("%d", jump20)) end -- Set Up variables for next frame's pass lmtp=mtp last=seed1 lastm=mtv -- End Lua emu.frameadvance() end not adding the part that tracks battle RNG, for obvious reasons Edited May 23, 2012 by Kaphotics typos, added black support
Bond697 Posted August 4, 2011 Posted August 4, 2011 i've been using this to watch the rng: while true do gui.text(1,185, string.format("%08X %08X", memory.readdword(0x02216248), memory.readdword(0x02216244))) emu.frameadvance() end lua is using windows' definition of a word when it runs, so you need to define a 32-bit value as a dword. also, for anyone who wants to try this out and isn't aware, the string.format method is really close to printf(), so you can use the variable definitins and other stuff for string.format(). for example, "%08X" is a capital letter hex value 8 digits large. "%08x" is the same thing but with lower case hex values, "%08u" is unsigned decimal, etc
codemonkey85 Posted August 4, 2011 Posted August 4, 2011 Whoa... that is seriously cool. Man, if only we had this back in Gen IV!
RedJiggly Posted September 7, 2011 Posted September 7, 2011 I wonder... could the coordinate script maybe be used to create a world map of black and white? Something like: every time the coordinates change, save a new picture of the screen with the specified coordinates in the name? And then, by having some other script (maybe in LUA, or maybe in some completely other language) try to merge all these pictures together(i.e., grab the picture with the lowest X and Y, and then get the picture with the X and Y that are the second-lowest, and add that picture on top of the old one at X minus lowestX and Y minus lowestY, and so on.)
Kaphotics Posted May 21, 2012 Author Posted May 21, 2012 (edited) rng helper -- very old version. see first post for most up to date -- RNG location for current game (English White) local rng=0x02216244 -- setup terminology abbreviations local rshift=bit.rshift local mdword=memory.readdwordunsigned -- setup initial variables = 0, rest of script detection will take care of them local initl=0 local inith=0 local adv=0 local total=0 local last=0 local jump1=0 -- setup frame detection function function next(s) local a=0x6C07*(s%65536)+rshift(s,16)*0x8965 local b=0x8965*(s%65536)+(a%65536)*65536+0x00269EC3 local c=b%4294967296 return c end -- Lua script begin! while true do -- setup every loop seed2=mdword(rng+4) seed1=mdword(rng) adv=0 test=last -- display seeds every loop gui.text(1,10,string.format("Current: %08X%08X",seed2,seed1)) gui.text(1,180,string.format("Initial: %08X%08X",inith,initl)) gui.text(180,10,string.format("Delay: %d", mdword(0x023FFC3C))) gui.text(1,170, string.format("M: %d, X: %d, Y: %d, Z: %d", memory.readword(0x0224F92C), memory.readword(0x0224F932,2), memory.readword(0x0224F93A), memory.readword(0x0224F936))) -- copied from map coord Lua -- check to see if the RNG advanced from the last value while seed1~=0 and seed2~=0 do if adv>200 then -- RNG advanced a bunch. Reset script then stop loop. print(""..string.format("Detected a reset or massive advancement. Re-initializing.")) adv =0 total=0 jump1=0 initl=mdword(rng) inith=mdword(rng+4) print(""..string.format("Session Initial Seed: %08X%08X",inith,initl)) break elseif test~=seed1 then -- RNG advanced at least once. Lets advance once and repeat the loop. test=next(test) adv=adv+1 jump1=adv elseif test==seed1 then break -- last frame's advanced RNG value matches the current. Stop loop. end end -- advancement tracking total=adv+total gui.text(1,19,string.format("Frame: %d", total)) gui.text(1,28,string.format("Jump: %d", jump1)) last=seed1 emu.frameadvance() end main use is that it tracks RNG frames after keeping the seeds from the moment the script starts. it grabs the initial seed when the game is reset, or the first seed it can find and keeps it stored as long as the script runs. I may have it write the initial seeds it gets to somewhere so that upon loading a save state it can find and re-determine the frame (session preservation), but this was just for fun Edited May 23, 2012 by Kaphotics
Kaphotics Posted May 23, 2012 Author Posted May 23, 2012 (edited) Map Coordinates White while true do gui.text(1,184, string.format("Map: %d, X: %d, Y: %d, Z: %d", memory.readword(0x0224F92C), memory.readword(0x0224F932,2), memory.readword(0x0224F93A), memory.readword(0x0224F936))) emu.frameadvance() end Black while true do gui.text(1,184, string.format("Map: %d, X: %d, Y: %d, Z: %d", memory.readword(0x0224F90C), memory.readword(0x0224F912,2), memory.readword(0x0224F91A), memory.readword(0x0224F916))) emu.frameadvance() end Download Link (English White) Edited May 23, 2012 by Kaphotics moved suite to top, map position to this post
Waitress_Tsubame Posted July 14, 2012 Posted July 14, 2012 Kinda weird why when I use the above lua script from the first post, the numbers stacked vertically in 2 columns remained zero in my Desmume. And also the frame value is still 0 BTW, kinda a bit unrelated, but is there a lua script for HGSS?
Kaphotics Posted September 15, 2012 Author Posted September 15, 2012 (edited) B2W2 Zonedata / Map Coordinates Notes: L toggles the raw zonedata display on/off. (default Q in DeSmuME) local rshift, lshift=bit.rshift, bit.lshift local md,mw,mb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned local gt,sf=gui.text,string.format local table={} local on,enbl,overprint,enblo=1,1,1,1 if mb(0x023FFE09)==0x00 then -- Not "2" ~ Not B2/W2 pos_m=md(0x02000024)+0x3461C zds=md(0x02000024)+0x3DFAC owstart=md(0x02000024)+0x34E04 game=1 else pos_m=md(0x02000024)+0x36780 zds=md(0x02000024)+0x41B2C owstart=md(0x02000024)+0x36BE8 game=2 end function main() table=joypad.get(1) if table.L then gt(0,0, "Toggling Display") enbl=0 else if enbl==0 then on=(on+1)%2 enbl=1 end end if table.R then gt(0,0, "Printout") enblo=0 else if enblo==0 then overprint=(overprint+1)%2 enblo=1 end end if on==0 then if game==2 then bike=rshift(mw(zds+2*15),10)%2 fly=rshift(mw(zds+2*15),13)%2 else bike=rshift(mb(zds+0x1F),2)%2 fly=rshift(mb(zds+0x1F),5)%2 end if bike==1 then gt(159,110,sf("Bike - Enabled")) else gt(159,110,sf("Bike - Disabled")) end if fly==1 then gt(159,120,sf("Fly - Enabled")) else gt(159,120,sf("Fly - Disabled")) end gt(1,50,sf("00-01: %04x",mw(zds+2*0))) gt(80,50,sf("10-11: %04x",mw(zds+2*8))) gt(159,50,sf("20-21: %04x",mw(zds+2*16))) gt(1,60,sf("02-03: %04x",mw(zds+2*1))) gt(80,60,sf("12-13: %04x",mw(zds+2*9))) gt(159,60,sf("22-23: %04x",mw(zds+2*17))) gt(1,70,sf("04-05: %04x",mw(zds+2*2))) gt(80,70,sf("14-15: %04x",mw(zds+2*10))) gt(159,70,sf("24-27: %08x",md(zds+2*18))) gt(1,80,sf("06-07: %04x",mw(zds+2*3))) gt(80,80,sf("16-17: %04x",mw(zds+2*11))) gt(159,80,sf("28-2B: %08x",md(zds+2*20))) gt(1,90,sf("08-09: %04x",mw(zds+2*4))) gt(80,90,sf("18-19: %04x",mw(zds+2*12))) gt(159,90,sf("2C-2F: %08x",md(zds+2*22))) gt(1,100,sf("0A-0B: %04x",mw(zds+2*5))) gt(80,100,sf("1A-1B: %04x",mw(zds+2*13))) gt(1,110,sf("0C-0D: %04x",mw(zds+2*6))) gt(80,110,sf("1C-1D: %04x",mw(zds+2*14))) gt(1,120,sf("0E-0F: %04x",mw(zds+2*7))) gt(80,120,sf("1E-1F: %04x",mw(zds+2*15))) end if overprint==0 then fcount=mb(0x4+owstart) ncount=mb(0x5+owstart) wcount=mb(0x6+owstart) tcount=mb(0x7+owstart) furnstart=0x8 furnend=furnstart+0x14*fcount-1 npcstart=0x08+mb(0x04+owstart)*0x14 npcend= npcstart+0x24*ncount-1 warpstart=0x08+mb(0x04+owstart)*0x14+mb(0x05+owstart)*0x24 warpend=warpstart+0x14*wcount-1 trigstart=0x08+mb(0x04+owstart)*0x14+mb(0x05+owstart)*0x24+mb(0x06+owstart)*0x14 trigend=trigstart+0x16*tcount-1 print(sf("Overworld Data [%d] @ 0x%08X",mw(zds+2*11),owstart)) if fcount>0 then print(sf("[%d] Furniture Range: 0x%04X-0x%04X",fcount,furnstart,furnend)) else print(sf("[%d] No Furniture",fcount)) end if ncount>0 then print(sf("[%d] NPC Range: 0x%04X-0x%04X",ncount,npcstart,npcend)) else print(sf("[%d] No NPCs",ncount)) end if wcount>0 then print(sf("[%d] Warp Range: 0x%04X-0x%04X",wcount,warpstart,warpend)) else print(sf("[%d] No Warps",wcount)) end if tcount>0 then print(sf("[%d] Trigger Range: 0x%04X-0x%04X",tcount,trigstart,trigend)) else print(sf("[%d] No Triggers",tcount)) end if md(owstart)~=trigend-3 then print("Error in parsing, please be in game.") else print("Successful Parse!") end print("") print("") overprint=1 end gt(160,145,sf("Overworld: %5d",mw(zds+2*11))) gt(160,155,sf("Script: %8d",mw(zds+2*3))) gt(160,165,sf("Text: %10d",mw(zds+2*5))) flyx=md(zds+2*18) flyy=md(zds+2*22) flyz=md(zds+2*20) if (flyx==5 and flyy==4 and flyz==0) or (flyx==13 and flyy==0 and flyz==5) then gt(149,174,sf("Can't Fly to here.")) else gt(185,174,sf("FlyTo (XYZ)")) gt(185,184,sf("%d,%d,%d",flyx,flyy,flyz)) end gt(1,145, sf("SubMap of Map: %3d",mw(zds+2*12))) if mw(zds+2*10)%256<255 then gt(1,155,sf("Slot Location: %d",mw(zds+2*10)%256)) else gt(1,155,sf("No Encounters Here!")) end gt(1,165, sf("Current Position")) gt(2,175, sf("M: %3d, X: %3d", mw(pos_m), mw(pos_m+0x6))) gt(2,184, sf("Y: %3d, Z: %3d", mw(pos_m+0xE), mw(pos_m+0xA))) end gui.register(main) Edited February 17, 2013 by Kaphotics
Kaphotics Posted November 30, 2012 Author Posted November 30, 2012 (edited) B2/W2 Script Parser Reads the memory of the game and translates the script language to meaningful instructions similar to XSE and other scripting programs. I primarily made the script to help me see how commands are used and help further our understanding of each command. No, it does not make the scripts, only interprets the hex. I've made a ton of progress and the whole script is 90,000 characters! Too big to include in this post. http://dl.dropbox.com/u/12206225/pporg/bw2scr/scrparse.lua Old bare below. local rshift, lshift=bit.rshift, bit.lshift local wd,ww,wb=memory.writedword,memory.writeword,memory.writebyte local rd,rw,rb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned mb=function(SRP) return rb(SRP) end mw=function(SRP) return rb(SRP)+rb(SRP+1)*0x100 end md=function(SRP) return rb(SRP)+rb(SRP+1)*0x100+rb(SRP+2)*0x10000+rb(SRP+3)*0x1000000 end local gt,sf=gui.text,string.format local table={} local start=md(0x02000024)+0x459A4 local startscr=md(md(0x02000024)+0x459A4)+md(0x02000024)+0x0459A8 local SRP=start local goscrp=0 local iterhead=0 local iterscr=0 local scrt={} local scrnum=0 local scrindex=mw(md(0x02000024)+0x41B32) local printiter=0 local catcherror=1 local itercatch=290 function main() --Notify when analysis is starting: if SRP==start then print(""..string.format("~Script File %d~",scrindex)) end while goscrp==0 and mw(SRP)~=0xFD13 and iterhead<35 do readval=md(SRP) scrt[scrnum] = readval if rd(start) > 4000 then print(""..sf("~Error Catch, Start Read Error~",curscr)) goscrp=-1 end SRP=SRP+4 scrnum=scrnum+1 print(""..sf("Script %d: %08X",scrnum,readval)) iterhead=iterhead+1 end if scrnum>0 then gt(1,00,sf("%08X",scrt[0])) end if scrnum>1 then gt(1,10,sf("%08X",scrt[1])) end if scrnum>2 then gt(1,20,sf("%08X",scrt[2])) end if scrnum>3 then gt(1,30,sf("%08X",scrt[3])) end if scrnum>4 then gt(1,40,sf("%08X",scrt[4])) end --Notify that Lua is ready to parse the script data if mw(SRP)==0xFD13 and goscrp==0 then ---print(""..sf("Finished Offset Parse")) goscrp=1 --proceed to next phase SRP=SRP+2 curscr=1 end --Begin while goscrp==1 and scrnum>=curscr and catcherror==1 and iterscr<300 do printiter=printiter+1 if printiter>20 or iterscr>itercatch then print(""..sf("~Error Catch, Command Read Error~",curscr)) catcherror=0 break end print(""..sf("~~~~~Script %d~~~~~~",curscr)) iterscr=1 done=0 while done==0 and md(SRP-2)~=0x0002 and (mw(SRP)~=0x5544 or mw(SRP)~=0x0000 or mw(SRP)~=0x4652) and iterscr<300 do if printiter>20 or iterscr>itercatch then print(""..sf("~Error Catch, Command Read Error~",curscr)) catcherror=0 break end cmd=mw(SRP) SRP=SRP+2 if cmd==0x02 then print(""..sf("End (0x0002)")) curscr=curscr+1 if scrnum>=curscr then print(""..sf("~~~~~Script %d~~~~~~",curscr)) else done=1 end elseif cmd==0x04 then rt=md(SRP) SRP=SRP+4 print(""..sf("CallRoutine (0x0004) 0x%08X",rt)) elseif cmd==0x05 then print(""..sf("End???[*TR] (0x0005)")) elseif cmd==0x08 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("Logic08 (0x0008) %s%d",fa,u16a)) elseif cmd==0x09 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("Logic09 (0x0009) %s%d",fa,u16a)) elseif cmd==0x0A then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("Logic0A (0x000A) %s%02X",fa,u16a)) elseif cmd==0x10 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("Readflag (0x0010) %s%d",fa,u16a)) elseif cmd==0x11 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("Logic11 (0x0011) %s%d",fa,u16a)) elseif cmd==0x19 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("CompareAtoB (0x0019) A=%s%d B=%s%d",fa,u16a,fb,u16b)) elseif cmd==0x1C then std=mw(SRP) SRP=SRP+2 print(""..sf("CallStd (0x001C) 0x%04X",std)) elseif cmd==0x1D then std=mw(SRP) SRP=SRP+2 print(""..sf("EndStdReturn[**] (0x001D)")) elseif cmd==0x1E then jump=md(SRP) SRP=SRP+4 print(""..sf("GoTo (0x001E) jump=0x%08X",jump)) elseif cmd==0x1F then logic=mb(SRP) SRP=SRP+1 jump=md(SRP) SRP=SRP+4 print(""..sf("IfThenGoTo (0x001F) 0x%02X jump=0x%08X",logic,jump)) elseif cmd==0x23 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("SetFlag (0x0023) %s%d",fa,u16a)) elseif cmd==0x24 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("ClearFlag (0x0023) %s%d",fa,u16a)) elseif cmd==0x26 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("SetVarEqCont (0x0028) %s%d %s%d",fa,u16a,fb,u16b)) elseif cmd==0x27 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("SetVar27 (0x0027) %s%d %s%d",fa,u16a,fb,u16b)) elseif cmd==0x28 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("SetVarEqVal (0x0028) %s%d %s%d",fa,u16a,fb,u16b)) elseif cmd==0x2A then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("SetVarEq28 (0x002A) %s%d %s%d",fa,u16a,fb,u16b)) elseif cmd==0x2E then print(""..sf("LockAll (0x002E)")) elseif cmd==0x2F then print(""..sf("UnlockAll (0x002F)")) elseif cmd==0x30 then print(""..sf("WaitMoment (0x0030)")) elseif cmd==0x32 then print(""..sf("WaitKeyPress (0x0032)")) elseif cmd==0x33 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("EventMessage (0x0033) id=%s%d",fa,u16a)) elseif cmd==0x34 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("GreyMessage (0x0034) id=%s%d view=%s%d",fa,u16a,fb,u16b)) elseif cmd==0x35 then print(""..sf("CloseEventMessage (0x0035)")) elseif cmd==0x36 then print(""..sf("CloseGreyMessage (0x0036)")) elseif cmd==0x38 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u8a=mw(SRP) SRP=SRP+1 if u8a/0x8000>=1 then fb="Var_" u8a=u8a%0x4000 elseif u8a/0x4000>=1 then fb="Cont_" u8a=u8a%0x4000 else fb="Num_" end print(""..sf("BubbleMessage (0x0038) %s%d %s%d",fa,u16a,fb,u8a)) elseif cmd==0x39 then print(""..sf("CloseBubbleMessage (0x0039)")) elseif cmd==0x3C then u8a=mb(SRP) SRP=SRP+1 u8b=mb(SRP) SRP=SRP+1 mid=mw(SRP) SRP=SRP+2 if mid/0x8000>=1 then fm="Var_" mid=mid%0x4000 elseif mid/0x4000>=1 then fm="Cont_" mid=mid%0x4000 else fm="Num_" end npc=mw(SRP) SRP=SRP+2 view=mw(SRP) SRP=SRP+2 type=mw(SRP) SRP=SRP+2 print(""..sf("Message1 (0x003C) MID=%s%X NPC=%d",fm,mid,npc)) elseif cmd==0x3D then u8a=mb(SRP) SRP=SRP+1 u8b=mb(SRP) SRP=SRP+1 mid=mw(SRP) SRP=SRP+2 if mid/0x8000>=1 then fm="Var_" mid=mid%0x4000 elseif mid/0x4000>=1 then fm="Cont_" mid=mid%0x4000 else fm="Num_" end view=mw(SRP) SRP=SRP+2 type=mw(SRP) SRP=SRP+2 print(""..sf("Message2 (0x003D) MID=%s%X",fm,mid)) elseif cmd==0x3E then print(""..sf("CloseMessage (0x003E)")) elseif cmd==0x3F then print(""..sf("CloseMessage2[*] (0x003F)")) elseif cmd==0x43 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("BorderMessage (0x0028) id=%s%d color=%s%d",fa,u16a,fb,u16b)) elseif cmd==0x44 then print(""..sf("CloseBorderMessage (0x0044)")) elseif cmd==0x47 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("PopYesNoVar (0x0047) 0x%04X",u16a)) elseif cmd==0x48 then u8a=mw(SRP) SRP=SRP+2 if u8a/0x8000>=1 then f1="Var_" u8a=u8a%0x4000 elseif u8a/0x4000>=1 then f1="Cont_" u8a=u8a%0x4000 else f1="Num_" end u8b=mw(SRP) SRP=SRP+2 if u8b/0x8000>=1 then f2="Var_" u8b=u8b%0x4000 elseif u8b/0x4000>=1 then f2="Cont_" u8b=u8b%0x4000 else f2="Num_" end u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end u16c=mw(SRP) SRP=SRP+2 if u16c/0x8000>=1 then fc="Var_" u16c=u16c%0x4000 elseif u16c/0x4000>=1 then fc="Cont_" u16c=u16c%0x4000 else fc="Num_" end u16d=mw(SRP) SRP=SRP+2 if u16d/0x8000>=1 then fd="Var_" u16d=u16d%0x4000 elseif u16d/0x4000>=1 then fd="Cont_" u16d=u16d%0x4000 else fd="Num_" end u16e=mw(SRP) SRP=SRP+2 if u16e/0x8000>=1 then fe="Var_" u16e=u16e%0x4000 elseif u16e/0x4000>=1 then fe="Cont_" u16e=u16e%0x4000 else fe="Num_" end print(""..sf("Message3 (0x0048) %s%d %s%d %s%d %s%d %s%d %s%d %s%d",f1,u8a,f2,u8b,fa,u16a,fb,u16b,fc,u16c,fd,u16d,fe,u16e)) elseif cmd==0x4B then print(""..sf("CloseAngryMessage (0x004B)")) elseif cmd==0x4C then u8a=mb(SRP) SRP=SRP+1 print(""..sf("???? (0x004C), 0x%02X",u8a)) elseif cmd==0x64 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u32a=md(SRP) SRP=SRP+4 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("Movement[***] (0x0064) A=%s%d color=%s%d",fa,u16a,fb,u32a)) elseif cmd==0x65 then print(""..sf("WaitMovement (0x0065)")) elseif cmd==0x68 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("StoreHeroPosition (0x0068) A=%s%d B=%s%d",fa,u16a,fb,u16b)) elseif cmd==0x6C then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("???? (0x006C) %s%d",fa,u16a)) elseif cmd==0x6D then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="" end u16c=mw(SRP) SRP=SRP+2 if u16c/0x8000>=1 then fc="Var_" u16c=u16c%0x4000 elseif u16c/0x4000>=1 then fc="Cont_" u16c=u16c%0x4000 else fc="" end u16d=mw(SRP) SRP=SRP+2 if u16d/0x8000>=1 then fd="Var_" u16d=u16d%0x4000 elseif u16d/0x4000>=1 then fd="Cont_" u16d=u16d%0x4000 else fd="" end u16e=mw(SRP) SRP=SRP+2 if u16e/0x8000>=1 then fe="Var_" u16e=u16e%0x4000 elseif u16e/0x4000>=1 then fe="Cont_" u16e=u16e%0x4000 else fe="" end print(""..sf("SetOWPos (0x006D) npc=%s%d x=%s%d y=%s%d z=%s%d dir=%s%d",fa,u16a,fb,u16b,fc,u16c,fd,u16d,fe,u16e)) elseif cmd==0x74 then print(""..sf("FacePlayer")) elseif cmd==0x85 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end u16c=mw(SRP) SRP=SRP+2 if u16c/0x8000>=1 then fc="Var_" u16c=u16c%0x4000 elseif u16c/0x4000>=1 then fc="Cont_" u16c=u16c%0x4000 else fc="Num_" end print(""..sf("TrBattle (0x0085) Opp1=%s%d Opp2=%s%d Logic=%s%d",fa,u16a,fb,u16b,fc,u16c)) elseif cmd==0x8C then print(""..sf("EndBattle (0x008C)")) elseif cmd==0x8D then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("SetVarBattleResult (0x008D) %s%d",fa,u16a)) elseif cmd==0x8E then print(""..sf("DisableTrainer (0x008E)")) elseif cmd==0xA6 then u16a=mw(SRP) SRP=SRP+2 print(""..sf("PlaySound (0x00A6) opp1=0x%X opp2=0x%X logic=%d",u16a,u16b,u16c)) elseif cmd==0xCB then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 print(""..sf("StoreRand (0x00CB) %s%d rand(0x%d)",fa,u16a,u16b)) elseif cmd==0xCC then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("SetVarQualItem (0x00CC) %s%d",fa,u16a)) elseif cmd==0xCD then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("SetVarQual???? (0x00CD) %s%d",fa,u16a)) elseif cmd==0x227 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("??? (0x0227) A=%s%d B=%s%d",fa,u16a,fb,u16b)) elseif cmd==0x24F then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="" end u16c=mw(SRP) SRP=SRP+2 if u16c/0x8000>=1 then fc="Var_" u16c=u16c%0x4000 elseif u16c/0x4000>=1 then fc="Cont_" u16c=u16c%0x4000 else fc="" end u16d=mw(SRP) SRP=SRP+2 if u16d/0x8000>=1 then fd="Var_" u16d=u16d%0x4000 elseif u16d/0x4000>=1 then fd="Cont_" u16d=u16d%0x4000 else fd="" end print(""..sf("????? (0x024F) A=%s%d B=%s%d C=%s%d D=%s%d",fa,u16a,fb,u16b,fc,u16c,fd,u16d)) elseif cmd==0x276 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end u16b=mw(SRP) SRP=SRP+2 if u16b/0x8000>=1 then fb="Var_" u16b=u16b%0x4000 elseif u16b/0x4000>=1 then fb="Cont_" u16b=u16b%0x4000 else fb="Num_" end print(""..sf("??? (0x0276) A=%s%d B=%s%d",fa,u16a,fb,u16b)) elseif cmd==0x2C5 then u16a=mw(SRP) SRP=SRP+2 if u16a/0x8000>=1 then fa="Var_" u16a=u16a%0x4000 elseif u16a/0x4000>=1 then fa="Cont_" u16a=u16a%0x4000 else fa="Num_" end print(""..sf("??? (0x02C5) A=%s%d",fa,u16a)) else print(""..sf("0x%X",cmd)) iterscr=iterscr+1 end end end if goscrp==1 and scrnum<curscr then print(""..sf("~~~~~~Finish~~~~~~")) goscrp=2 end gt(1,70,sf("Total Scripts: %d",scrnum)) gt(1,80,sf("Attempts: %d",iterhead)) gt(1,90,sf("SRP: %08X",SRP)) if goscrp==2 then gt(1,100,sf("~~~~~Finish~~~~~")) end end gui.register(main) Some examples of what it creates in the Console window: http://pastebin.com/raw.php?i=72nRf1aa http://pastebin.com/raw.php?i=fRBaRPkv http://pastebin.com/raw.php?i=gMRLPeuR http://pastebin.com/raw.php?i=TpgbtWnF To use it, the script file must be already loaded in game. Talk to an NPC that uses a script from the script file so that the game will have it loaded in the memory. Some locations don't work, I've only tested it indoors. I'll be updating it when I get time, school comes first Unknown/Un-programmed commands can throw off the parse so in general don't trust anything when it starts reporting hex. Edited December 2, 2012 by Kaphotics
Kaphotics Posted February 1, 2013 Author Posted February 1, 2013 (edited) Overworld Editing for BW/B2W2 Edits a single memory value of all overworlds of a certain type (say NPC->Overworld Sprite) to help the user position/assign overworlds properly. Pretty useful in finding out overworld sprite values. Enable (and keep on) before a fade2black map change, not a seamless route change. Even though the pic is B2W2, it works in BW. Current setup is to edit the sprite of all overworld NPCs. local rshift, lshift=bit.rshift, bit.lshift local wd,ww,wb=memory.writedword,memory.writeword,memory.writebyte local rd,rw,rb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned mb=function(x) return rb(x) end mw=function(x) return rb(x)+rb(x+1)*0x100 end md=function(x) return rb(x)+rb(x+1)*0x100+rb(x+2)*0x10000+rb(x+3)*0x1000000 end local gt,sf=gui.text,string.format if mb(0x023FFE09)==0x00 then -- Not "2" ~ Not B2/W2 pos_m=md(0x02000024)+0x3461C zds=md(0x02000024)+0x3DFAC ows=md(0x02000024)+0x34E04 game=1 else pos_m=md(0x02000024)+0x36780 zds=md(0x02000024)+0x41B2C ows=md(0x02000024)+0x36BE8 game=2 end local useupper=true local L8=0x01 local U8=0x00 local edit="NPC" local mapexit=1 local offset=0x02 --sprite. change to 0xA for script reassigning function main() --L8=math.random(500) --mapexit=math.random(6) if edit=="Furniture" then mode=1 mult=0x14 editat=0x08+ows elseif edit=="NPC" then mode=2 mult=0x24 editat=0x08+mb(0x04+ows)*0x14+ows elseif edit=="Warp" then mode=3 mult=0x14 editat=0x08+mb(0x04+ows)*0x14+mb(0x05+ows)*0x24+ows elseif edit=="Trigger" then mode=4 mult=0x16 editat=0x08+mb(0x04+ows)*0x14+mb(0x05+ows)*0x24+mb(0x06+ows)*0x14+ows end count=mb(ows+3+mode) --word editing mode if useupper==true then if mw(editat+offset)~=(L8+U8*0x100) then i=0 gt(1,00,sf("Map is Switching!")) while i<count do insert=(L8+U8*0x100) if mode==3 then ww(i*mult+offset+editat+4,mapexit) end ww(i*mult+offset+editat,insert) i=i+1 end end end --byte editing mode if useupper==false then if mb(editat+offset)~=(L8) then i=0 gt(1,00,sf("Map is Switching!")) while i<count do insert=(L8) if mode==3 then ww(i*mult+offset+editat+4,mapexit) end wb(i*mult+offset+editat,insert) i=i+1 end end end --Debug gt(1,10,sf("OW Data Start: %08X",ows)) gt(1,20,sf("Desired Count: %d",count)) gt(1,30,sf("Start of Desired Data: %08X",editat)) gt(1,40,sf("Mode: %s",edit)) end gui.register(main) Event Script writer for BW & B2/W2 Replaces the first script of the current map with a customized event script. Be sure the current event script file is loaded before enabling in order to write to the proper area. Allows a user to test an event script in real time, and change up instructions on the fly rather than tinker with the ROM. Be sure to buffer the event script file that is being edited with zeroes such that a long custom script won't overwrite other important memory locations. This is how I tested both of on my YouTube channel. local wb,md,gt,sf=memory.writebyte,memory.readdwordunsigned,gui.text,string.format local rd,rw,rb=memory.readdwordunsigned,memory.readwordunsigned,memory.readbyteunsigned mb=function(x) return rb(x) end mw=function(x) return rb(x)+rb(x+1)*0x100 end md=function(x) return rb(x)+rb(x+1)*0x100+rb(x+2)*0x10000+rb(x+3)*0x1000000 end local i,j,x,t=1,1,1,{} if mb(0x023FFE09)==0x00 then -- Not "2" ~ Not B2/W2 pos_m=md(0x02000024)+0x3461C zds=md(0x02000024)+0x3DFAC ows=md(0x02000024)+0x34E04 scstart=md(md(0x02000024)+0x41834)+md(0x02000024)+0x41838 game=1 else pos_m=md(0x02000024)+0x36780 zds=md(0x02000024)+0x41B2C ows=md(0x02000024)+0x36BE8 scstart=md(md(0x02000024)+0x459A4)+md(0x02000024)+0x0459A8 game=2 end function main() --List all portions of or script s1="2E 00" s2="" s3="" s4="02 00" --Concatenate all strings in order s=s1..s2..s3..s4 --Remove spaces from eventscript so that we can add the script in s = string.gsub (s, " ", "") --Break up eventscript string into a table while i<=string.len(s) do t[j] ="0x"..string.sub(s,i,i+1) j=j+1 i=i+2 end --Write script per byte via values in the table. while x<j do wb(scstart+x-1,t[x]) --Graphical display of text gt((x-1)%10*15,math.floor((x-1)/0xA)*10,sf("%02X",t[x])) x=x+1 end x=1 end gui.register(main) Edited February 17, 2013 by Kaphotics
BowWave Posted May 7, 2013 Posted May 7, 2013 Maybe I am dumb...but does the lua script for RNG frame work only on BW 1? Because I use a similar one but I was looking for one to use on BW2 USA.
LEGOanimal22 Posted July 6, 2013 Posted July 6, 2013 When I try this, I get an error saying "lua51.dll is missing" Where can I get that file?
cpan1 Posted July 7, 2013 Posted July 7, 2013 http://projectpokemon.org/forums/showthread.php?16582-LUA-Script&p=131824&viewfull=1#post131824 From 6th post down.
LEGOanimal22 Posted July 9, 2013 Posted July 9, 2013 It seems like ALL of Kaphotics Dropbox links are down
Kaphotics Posted July 9, 2013 Author Posted July 9, 2013 If the links are down, the script is still included within tags.I deleted them from my dropbox because I really shouldn't have to host the small scripts/useless images.
cpan1 Posted July 9, 2013 Posted July 9, 2013 You can get the libraries (*.dll's) through the Lua for Windows installer http://code.google.com/p/luaforwindows/ I used Desmume 0.9.7 nosse version.
Fr0sTLiCh Posted September 15, 2013 Posted September 15, 2013 how can i get ram addresses for a rom in another language (spanish)? thanks in advance
shadowofdarkness Posted February 9, 2016 Posted February 9, 2016 (edited) I'm trying to find or get working a version of this for White (J) does anyone have one that I could get please? I have tried modifying this script using the rng and mtrng values from the notable breakpoints page on the wiki for the Japanese versions of the game but it never works. It reports a seed but it is always wrong and the frames don't track right. Along with it randomly pausing the emulator with the following error. "Save state's session did not start with script." "Either load a valid save state or resume with this one." The only thing I got working right is the map position and that I don't use. I tracked the correct pos_m offset for White (J) on my own. It is pos_m=0x0224F78C which could be useful for other people. Edited February 9, 2016 by shadowofdarkness fix formatting
Pokestarter Posted August 5, 2020 Posted August 5, 2020 I am a total noob in ROM hacking. Do you have any tutorials for people of my like?
Hamhub7 Posted January 26, 2022 Posted January 26, 2022 Sorry to necro a thread but @Kaphotics I have been scouring the web for zonedata tools for BW1. This is the closest I have found, but it's for BW2. The scripts don't seem to work on the original versions, and I am not skilled enough with the internals of these games to modify the scripts to work on the originals. Do you by any chance have scripts that work for BW1 or could point me in the right direction on how to modify the BW2 ones? 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now