Posts for FatRatKnight

Post subject: My last push...
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
As the Consolation Team Contest didn't quite work out the way I thought it would, here I am reviving this thread for one last push. By the way, laponge36 had submitted this for week 2, which I sadly can't view with my problems (encode requested): http://dehacked.2y.net/microstorage.php/info/1572741131/Sorcerer%27s%20Maze%20241356.pjm If the suggested route for the CTC looks like a bad choice, there's no CTC anymore, so if you do think it's time to start at World 4, now might be a good time to do so. Though, it would appear I neglected to post my lua scripts then. I'll fix that mistake now... This one just paints a tiny box on each ball. Mousing over the box will provide basic stats on the angle and speed of the ball, though the OldScratchStuff generally dumps more addresses: Download SM.lua
Language: lua

local R1u, R1s= memory.readbyte , memory.readbytesigned local R2u, R2s= memory.readword , memory.readwordsigned local R4u, R4s= memory.readdword, memory.readdwordsigned local keys, lastkeys= input.get(),input.get() --***************************************************************************** local function UpdateKeys() lastkeys= keys; keys= input.get() end local function Press(k) return keys[k] and (not lastkeys[k]) end --***************************************************************************** local function Limits(v,l,h) return math.max(math.min(v,h),l) end local function Within(v,l,h) return (v >= l) and (v <= h) end local function HexStr(v) return string.upper(string.format("%x",v)) end --***************************************************************************** --***************************************************************************** local function GuiTextRight(x,y,t,c) --***************************************************************************** c= c or -1 x= x - #tostring(t)*4 gui.text(x,y,t,c) end local red= -0x00FFFF01 --Bypass some bug I call "80Red" gui.opacity(0.75) local BallStart= 0x00115BE4 --***************************************************************************** local function Fn() --***************************************************************************** UpdateKeys() -- for j= 0, 33 do -- GuiTextRight(66, 2+7*j,R2s(0x001137A4+2*j),-1) -- end local MouseCount= 0 for i= 0, 99 do local addr= BallStart + 0xAC*i if R1u(addr) ~= 0 then local x,y= R2u(addr+0x74),R2u(addr+0x76) gui.box(x-1,y-1,x+1,y+1,0x00FF0080,0x00FF00FF) if Within(keys.xmouse,x-1,x+1) and Within(keys.ymouse,y-1,y+1) then gui.line(x,y, x+R4s(addr+0x2C)/10 , y+R4s(addr+0x30)/10 , red) GuiTextRight(20, 2+20*MouseCount, R4s(addr+0x38)) --Position GuiTextRight(20,10+20*MouseCount, R4s(addr+0x3C)) GuiTextRight(40, 2+20*MouseCount, R4s(addr+0x2C)) --Velocity GuiTextRight(40,10+20*MouseCount, R4s(addr+0x30)) GuiTextRight(60, 2+20*MouseCount, R2u(addr+0x22)) --Speed/Angle GuiTextRight(60,10+20*MouseCount, R2u(addr+0x20)) MouseCount= MouseCount+1 end end -- If ball exists end -- For loop end -- Function gui.register(Fn) --***************************************************************************** local function OldScratchStuff() --***************************************************************************** UpdateKeys() for j= 0, 23 do GuiTextRight(9,2+7*j,HexStr((j+0x00)*2),0x00FF00FF) end for j= 0, 23 do GuiTextRight(83,2+7*j,HexStr(R2u(0x00119F0C+(j+0x00)*2))) end for i= 0, 10 do local addr= BallStart + 0xAC*i if R2u(addr) ~= 0 then for j= 0, 23 do GuiTextRight(33+23*i, 2+7*j,R2s(addr+2*(j+0x00))) end -- if bit.band(R2u(addr+2),4) == 0 then local Angle= R2u(addr+0x9A) / 2048 * math.pi local Speed= R2u(addr+0x98) GuiTextRight(33+23*i, 180, math.floor(Speed*math.sin(Angle))) GuiTextRight(33+23*i, 190, math.floor(Speed*math.cos(Angle))) -- end end end end --gui.register(OldScratchStuff) --***************************************************************************** while true do -- I did observe a glitch with joypad.set without this loop. --***************************************************************************** emu.frameadvance() end
And this one merely logs certain events (using the Output Console via print). Might not be bad to take a look: Download SM_logger.lua
Language: lua

local OutputFn= print -- print, or to a file? local R1u, R1s= memory.readbyte , memory.readbytesigned local R2u, R2s= memory.readword , memory.readwordsigned local R4u, R4s= memory.readdword, memory.readdwordsigned local keys, lastkeys= input.get(),input.get() --***************************************************************************** local function UpdateKeys() lastkeys= keys; keys= input.get() end local function Press(k) return keys[k] and (not lastkeys[k]) end --***************************************************************************** local function Limits(v,l,h) return math.max(math.min(v,h),l) end local function Within(v,l,h) return (v >= l) and (v <= h) end local function HexStr(v) return string.upper(string.format("%x",v)) end --***************************************************************************** --***************************************************************************** local function GuiTextRight(x,y,t,c) --***************************************************************************** c= c or -1 x= x - #tostring(t)*4 gui.text(x,y,t,c) end local red= -0x00DFFF01 --Bypass some bug I call "80Red" local BallArray= {}; for i= 0, 99 do BallArray[i]= {exist= false,st=0} end --***************************************************************************** local function RecordBall(ball, addr) --***************************************************************************** ball.exist= (R2u(addr ) ~= 0) ball.st= R2u(addr+0x02) end --***************************************************************************** local function EdgeCheck(case1, case2, msg1, msg2) --***************************************************************************** if case1 and (not case2) then OutputFn(msg1) elseif (not case1) and case2 then OutputFn(msg2) end end --***************************************************************************** local function MessageLog(b, ball, addr) --***************************************************************************** --Existance local temp= R2u(addr) EdgeCheck(temp ~= 0 , ball.exist, movie.framecount() .. " + Ball #" .. b .. " spawned at " .. R4u(addr+0x14) .. " " .. R4u(addr+0x10) .. " - s" .. R2u(addr+0x22) .. " a" .. R2u(addr+0x20), movie.framecount() .. " - Ball #" .. b .. " deleted." ) if (temp == 0) then return end -- Uh, it doesn't exist. Stop messages. --Status temp= R2u(addr+2) EdgeCheck(bit.band(temp,1) ~= 0, bit.band(ball.st,1) ~= 0, movie.framecount() .. " #" .. b .. " hit ceiling", movie.framecount() .. " #" .. b .. " hit paddle, (pad x" .. R4u(0x001137B4) .. ") - s" .. R2u(addr+0x22) .. " a" .. R2u(addr+0x20) ) EdgeCheck(bit.band(temp,4) ~= 0, bit.band(ball.st,4) ~= 0, movie.framecount() .. " #" .. b .. " released from paddle.", movie.framecount() .. " #" .. b .. " is stuck to paddle." ) end --***************************************************************************** local function HandleBalls() --***************************************************************************** for b= 0, 99 do local ball= BallArray[b] local addr= 0x00115BE4 + 0xAC*b MessageLog(b, ball, addr) RecordBall(ball, addr) end end emu.registerafter(HandleBalls) --***************************************************************************** while true do -- I did observe a glitch with joypad.set without this loop. --***************************************************************************** emu.frameadvance() end
And these are my current notes on memory addresses:
0x0011322E - Blocks left
0x0010B030 - Player Control

00115BE4 [size=0xAC][count=100] Ball stuff
+00,2x Does ball exist? Some sort of identifier?
+02,2x Bit-packed:
  0x0001 - Allowed to hit paddle?  0 = No (still going up from paddle hit)  1 = Yes
  0x0004 - Released from paddle?  0 = Stuck to paddle  1 = Flying free
+04,2? Ball power-up (giant, fire)
+06,2s Angle (precise to 4096)
+08,2? Fire ball related.
+0A,2s Is it fire ball?  -1 = No  0 = Yes
+0C,2? Giant ball related.
+0E
+10,4? X-pos
+14,4? Y-pos
+18
+1A
+1C
+1E
+20,2s Angle (2)
+22,2u Speed
+24,4? X-pos (2)
+28,4? Y-pos (2)
+2C,4s X-vel
+30,4s Y-vel
+34,2s Angle (3)
+36,2u Speed (2)
+38,4? X-pos (3)
+3C,4? Y-pos (3)
+40
+42
+44
+46
+48,4? X-pos (4, halfstep?)
+4C,4? Y-pos (4, halfstep?)
+50,4u X-vel, absolute value?
+54,4u Y-vel, absolute value?
+58
+5A
+5C
+5E
+60
+62
+64
+66
+68
+6A
+6C
+6E
+70
+72
+74,2u X-pixel
+76,2u Y-pixel
+78,2u X-pixel: Trail1
+7A,2u Y-pixel: Trail1
+7C,2u X-pixel: Trail2
+7E,2u Y-pixel: Trail2
+80,2u X-pixel: Trail3
+82,2u Y-pixel: Trail3
+84,2u X-pixel: Trail4
+86,2u Y-pixel: Trail4
+88,2u X-pixel: Trail5
+8A,2u Y-pixel: Trail5
+8C,2u X-pixel: Trail6
+8E,2u Y-pixel: Trail6
+90,2u X-pixel: Trail7
+92,2u Y-pixel: Trail7
+94,2u X-pixel: Trail8
+96,2u Y-pixel: Trail8
+98,2u Speed (used only for sticky ball or pre-launch)
+9A,2s Angle (used only for sticky ball or pre-launch)
+9C,2u Timer for sticky ball (or pre-launch)
+9E,2s Countdown timer?
+A0,2? Related to ball speed? Incremented by timer at +9E
+A2,2x Which wall was last hit?
+A4
+A6
+A8
+AA
edit: Oh, my post in the CTC is more informative... Copying that instead I'd love to work on this myself, but the fact I can't make lapogne36's run sync here, but DarkKobold can on his computer, kind of scares me away, probably due to the fact I don't believe I can produce a movie that will sync on anyone else's machine. Regardless, this TAS does have my support. If there's anything you want done in script form, I will attempt to work one up. I just need a request, the more specific the better, or else I'd just be aimlessly scripting around.
Post subject: Pending closure, wish to hear a few thoughts first.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
A contest where almost no one participates is hardly a good contest. While I am considering closing this contest, I still want to encourage production of a Sorcerer's Maze TAS. There are a few reasons why I'm considering contest closure: * I have bad habits, particularly the fact I can't stay focused on a single project for long. This is particularly bad for leading any groups, as many people generally depend on a single entity to tell them what to do in a situation like this. If the fact I haven't made an update yet doesn't announce this problem, then perhaps stating it like this will. * The lack of participation is certainly another major factor. I'm holding on to exactly one submission for last week, and it's not even complete (whether it's a great run up until it stops is something I can't say, but that's another issue). I'm wondering how I should update things without anything really going on. * Technical issues I have. Currently, I'm holding to a movie file I can't view fully. Three stages in and there is a desync, and I have made no progress in resolving it. It's difficult being a judge for something that one can't even view, let alone confirm anything. Still, I'm only considering closing this contest. It's not closed yet. And if closed, I will honestly hate it if it also means terminating the TAS. I do not want it as an excuse to stop the TAS. My apologies for this negative post. I still do want to see completion of Sorcerer's Maze. Whether in this underpopulated contest or in a new thread at the PSX section, I want to do everything I can to encourage this TAS, and to, at long last, see the run fascinate people at the Workbench. I'm posting this before acting so I can hear some thoughts. I've stated my reasons, I wish to hear yours now.
Post subject: DarkKobold, you around?
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Sorry about delays. So far, just one submission (partial completion of World 4, but on time, regardless). I'm ready to forward it to DarkKobold at any time (I may just ask him to take over considering my problem). Also, I won't mind any encodes. As it is, for the moment, impossible for me to view any runs, anyone willing to create a YouTube video of any of these submissions will go quite appreciated.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Progress seems to come in bursts. I stop for a while, then pick right up again. This implies that I might stop right before 3-1, then go halfway through 3-3, then one more months of break before I finish at last. Well, it is a pattern, anyway. Regardless, I'm on my way through 2-2, and currently hit with a bit of frustration at the yeti. You see, I can leave the yeti in this fashion just fine, shooting downward to gain the necessary height to leap over the bullet. However, there is a potential to abuse a poor KGB guy to duck under that bullet instead. This, naturally, lets me jump up to those platforms sooner (about 14 frames) and is far more stylish to boot. Sadly, any RNG abuse I can come up with without wasting frames hasn't produced good results, but I've come close a few times. I may simply continue if I can't reach the optimal solution in this run.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
In my above code, I make references to two bugs. The 80Red glitch, as I call it, is a bug that fails to draw any color for any numeric representation of a number greater than or equal to 0x80000000. As the upper two digits represent the red portion of the colors (0x80000000), this means that any red in the range of 0x80 to 0xFF will produce an invalid color, and will not paint anything in most cases. This bug is common in several emulators, which I've spotted in FCEUX and VBA, but Snes9x isn't hit with this bug. The bug, furthermore, allows using negative numbers, which you can use to get the red components of 0x80 or higher. However, you need to know the mechanics of Twos Complement in order to understand what in the world it's doing to get the color you need. But by and large, subtract the normal color you want by (0xFFFFFFFF + 1) and it'll work as long as the red is 0x80 or higher. The bug does not apply when you use tables ( {r=0x80, g=0x00, b=0x00, a=0xFF} ) or strings ( "#800000FF" ) as your color. It only affects numeric representation ( 0x800000FF ). You can safely call the gui functions using 0x7FFFFFFF, but not 0x800000FF; However, -0x7FFFFF01 will get you the nice, half-brightness red you desire. Another glitch is the Enforced frameadvance bug, another arbitrary name I came up with. Basically, the bug does not exist as long as you have while true do [...] emu.frameadvance() end somewhere in your code, or at least the script doesn't exit with registers still running. An observed effect: joypad.set should normally affect only one frame. If it's not called for the next frame, it should default to simply passing the user's input through. With the emu.frameadvance() loop being absent, this reset does not take place -- the input from the joypad.set sticks permanently until joypad.set is called again or the script is closed by user. Usually not a problem for those making bots, however, as they tend to call joypad.set every frame, but this would affect those who make a macro script. I suspect there might be other effects that "forget" to be reset with an absent emu.frameadvance() loop, but regardless of the problems that crop up from it, sticking in that loop, even without any meaningful content in it, gets you safely around this bug. I have not observed this bug in any other emulator.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Roll call. Just want to confirm lapogne36 and DarkKobold are still working on this. As for my own progress in getting the movies to sync, I have no success. I'm pretty lost at this point, and would rather avoid going through every permutation of my settings to see if any of them work.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
There's a match. Both in the CRC and the MD5. There's a pretty strong chance I have the right dump. Still, thanks. I can better identify what I've got now. Having confirmed that much, I'll look more into the settings I've got. Though it is mostly defaults in there.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I am pushing on. Updated first post (with 1 week delay) to reflect that we are continuing. The fact lapogne36's run syncs for DarkKobold is good enough for me. Speaking of which, the runs handed to me (in case you don't want to hunt for them in the original edited post) are: lapogne36 - http://dehacked.2y.net/microstorage.php/info/1563393979/Sorcerer%27s%20Maze%20241356.pjm DarkKobold (mostly a test) - http://dehacked.2y.net/microstorage.php/info/1437226142/Copy%20of%20SMmenu.pjm Regardless, consider this post a call for help. I need to identify the problem, and to know how to identify whether I've got the correct dump of the game. As I have no knowledge in how to solve this problem, this is impossible for me to handle on my own (I'll just forward any further submissions to DarkKobold as long as this problem persists).
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I'm still having trouble getting any sync with these runs (lapogne36's run breaks at 2-3). I checked the options and it appears I've already been using the same ones. As for the MD5, I actually have little experience with it. How would I find the MD5 of something? Asking now so I'm not entirely in the dark when you hand me the letters and numbers. In any case, I'm pretty sure DarkKobold has access to lapogne36's file (during my sickness and I wanted to keep things rolling). It's already mostly due then, so I figure there won't be much damage. Besides, the earlier we figure out the problems, the better. I would hate to have things redone just because of one issue. Updating the first post to advise onlookers of delays.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
I've finally recovered enough from my sickness to work on an update. Not that I'm at top condition yet, but I'm no longer stuck in my bed now. Unfortunately, I have no success getting the submitted movies to sync. I'm largely using the default settings in PSXjin v2.0.2 if anyone's wondering. Submitters were DarkKobold and lapogne36. Let me know what settings are used, and whether the movie syncs for you. I'm having these technical difficulties right now.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Advance warning that an update might be late. I've fallen ill recently, and barely have the energy to verify the movies, let alone work out the changes to make on the initial post. I may pass the verification to DarkKobold and let him handle edits while I work on recovery. ... I should hope he's trustworthy, of course! If some other moderator or admin would rather verify, I can pass to that person instead.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Starting at address 0x00115BE4, there is an array containing stats of each ball. Add some multiple of 0xAC to get whatever ball you want to look at. I believe there is 100 of them. A list of offsets. Each piece of data takes up 2 or 4 bytes, as noted by the ,2u or ,4u after the offset. The u being unsigned, s being signed, and ? being either signed or unsigned (I haven't rightly identified which). x is used when it is best viewed in hexadecimal form
00115BE4 [size=0xAC][count=100]  Ball array
+00,2x Does ball exist? Some sort of identifier?
+02,2x Bit-packed:
  0x0001 - Allowed to hit paddle?  0 = No (still going up from paddle hit)  1 = Yes
  0x0004 - Released from paddle?  0 = Stuck to paddle  1 = Flying free
+04,2? Ball power-up (giant, fire)
+06,2s Angle (precise to 4096)
+08,2? Fire ball related.
+0A,2s Is it fire ball?  -1 = No  0 = Yes
+0C,2? Giant ball related.
+0E
+10,4? X-pos
+14,4? Y-pos
+18
+1A
+1C
+1E
+20,2s Angle (2)
+22,2u Speed
+24,4? X-pos (2)
+28,4? Y-pos (2)
+2C,4s X-vel
+30,4s Y-vel
+34,2s Angle (3)
+36,2u Speed (2)
+38,4? X-pos (3)
+3C,4? Y-pos (3)
+40
+42
+44
+46
+48,4? X-pos (4, halfstep?)
+4C,4? Y-pos (4, halfstep?)
+50,4u X-vel, absolute value?
+54,4u Y-vel, absolute value?
+58
+5A
+5C
+5E
+60
+62
+64
+66
+68
+6A
+6C
+6E
+70
+72
+74,2u X-pixel
+76,2u Y-pixel
+78,2u X-pixel: Trail1
+7A,2u Y-pixel: Trail1
+7C,2u X-pixel: Trail2
+7E,2u Y-pixel: Trail2
+80,2u X-pixel: Trail3
+82,2u Y-pixel: Trail3
+84,2u X-pixel: Trail4
+86,2u Y-pixel: Trail4
+88,2u X-pixel: Trail5
+8A,2u Y-pixel: Trail5
+8C,2u X-pixel: Trail6
+8E,2u Y-pixel: Trail6
+90,2u X-pixel: Trail7
+92,2u Y-pixel: Trail7
+94,2u X-pixel: Trail8
+96,2u Y-pixel: Trail8
+98,2u Speed (used only for sticky ball or pre-launch)
+9A,2s Angle (used only for sticky ball or pre-launch)
+9C,2u Timer for sticky ball (or pre-launch)
+9E,2s Countdown timer?
+A0,2? Related to ball speed? Incremented by timer at +9E
+A2,2x Which wall was last hit?
+A4
+A6
+A8
+AA
Post subject: Just updating my current script. Yay for research!
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Well, I've produced a script to paint hitboxes. That might be worth something. Download TGL.lua
Language: lua

R1u= memory.readbyte local function R2u(a) return R1u(a) + R1u(a+1)*0x100 end local lastkeys, keys= input.get(), input.get() --***************************************************************************** local function UpdateKeys() lastkeys= keys; keys= input.get() end local function Press(k) return keys[k] and not lastkeys[k] end --***************************************************************************** local function Limits(V,l,h) return math.max(math.min(V,h),l) end --***************************************************************************** --***************************************************************************** Draw= {} --Draw[button]( x , y , c ) --***************************************************************************** --Coordinates is the top-left pixel of the 3x5 digit. --Used for drawing compact, colored numbers. local Px,Li= gui.pixel, gui.line Draw[0]= function(x,y,c) -- ### Li(x ,y ,x ,y+4,c)-- # # Li(x+2,y ,x+2,y+4,c)-- # # Px(x+1,y ,c) -- # # Px(x+1,y+4,c) -- ### end Draw[1]= function(x,y,c) -- # Li(x ,y+4,x+2,y+4,c)-- ## Li(x+1,y ,x+1,y+3,c)-- # Px(x ,y+1,c) -- # end -- ### Draw[2]= function(x,y,c) -- ### Li(x ,y ,x+2,y ,c)-- # Li(x ,y+3,x+2,y+1,c)-- ### Li(x ,y+4,x+2,y+4,c)-- # Px(x ,y+2,c) -- ### Px(x+2,y+2,c) end Draw[3]= function(x,y,c) -- ### Li(x ,y ,x+1,y ,c)-- # Li(x ,y+2,x+1,y+2,c)-- ### Li(x ,y+4,x+1,y+4,c)-- # Li(x+2,y ,x+2,y+4,c)-- ### end Draw[4]= function(x,y,c) -- # # Li(x ,y ,x ,y+2,c)-- # # Li(x+2,y ,x+2,y+4,c)-- ### Px(x+1,y+2,c) -- # end -- # Draw[5]= function(x,y,c) -- ### Li(x ,y ,x+2,y ,c)-- # Li(x ,y+1,x+2,y+3,c)-- ### Li(x ,y+4,x+2,y+4,c)-- # Px(x ,y+2,c) -- ### Px(x+2,y+2,c) end Draw[6]= function(x,y,c) -- ### Li(x ,y ,x+2,y ,c)-- # Li(x ,y+1,x ,y+4,c)-- ### Li(x+2,y+2,x+2,y+4,c)-- # # Px(x+1,y+2,c) -- ### Px(x+1,y+4,c) end -- ### Draw[7]= function(x,y,c) -- # Li(x ,y ,x+1,y ,c)-- ## Li(x+2,y ,x+1,y+4,c)-- # end -- # Draw[8]= function(x,y,c) -- ### Li(x ,y ,x ,y+4,c)-- # # Li(x+2,y ,x+2,y+4,c)-- ### Px(x+1,y ,c) -- # # Px(x+1,y+2,c) -- ### Px(x+1,y+4,c) end Draw[9]= function(x,y,c) -- ### Li(x ,y ,x ,y+2,c)-- # # Li(x+2,y ,x+2,y+3,c)-- ### Li(x ,y+4,x+2,y+4,c)-- # Px(x+1,y ,c) -- ### Px(x+1,y+2,c) end Draw[10]=function(x,y,c) -- # Li(x ,y+1,x ,y+4,c)-- # # Li(x+2,y+1,x+2,y+4,c)-- # # Px(x+1,y ,c) -- ### Px(x+1,y+3,c) -- # # end Draw[11]=function(x,y,c) -- ## Li(x ,y ,x ,y+4,c)-- # # Li(x+1,y ,x+2,y+1,c)-- ## Li(x+1,y+4,x+2,y+3,c)-- # # Px(x+1,y+2,c) -- ## end Draw[12]=function(x,y,c) -- # Li(x ,y+1,x ,y+3,c)-- # # Li(x+1,y ,x+2,y+1,c)-- # Li(x+1,y+4,x+2,y+3,c)-- # # end -- # Draw[13]=function(x,y,c) -- ## Li(x ,y ,x ,y+4,c)-- # # Li(x+2,y+1,x+2,y+3,c)-- # # Px(x+1,y ,c) -- # # Px(x+1,y+4,c) -- ## end Draw[14]=function(x,y,c) -- ### Li(x ,y ,x ,y+4,c)-- # Li(x+1,y ,x+2,y ,c)-- ## Li(x+1,y+4,x+2,y+4,c)-- # Px(x+1,y+2,c) -- ### end Draw[15]=function(x,y,c) -- ### Li(x ,y ,x ,y+4,c)-- # Li(x+1,y ,x+2,y ,c)-- ## Px(x+1,y+2,c) -- # end -- # --***************************************************************************** local function __DN_AnyBase(right, y, Number, c, bkgnd, div) --***************************************************************************** -- Works with any base from 2 to 16. Paints the input number. -- Returns the x position where it would paint another digit. -- It only works with integers. Rounds fractions toward zero. if div < 2 then return end -- Prevents the function from never returning. local Digit= {} local Negative= false if Number < 0 then Number= -Number Negative= true end Number= math.floor(Number) c= c or "white" bkgnd= bkgnd or "clear" local i= 0 if Number < 1 then Digit[1]= 0 i= 1 end while (Number >= 1) do i= i+1 Digit[i]= Number % div Number= math.floor(Number/div) end if Negative then i= i+1 end local x= right - i*4 gui.box(x+1, y-1, right+1, y+5,bkgnd,bkgnd) i= 1 while Draw[Digit[i]] do Draw[Digit[i]](right-2,y,c) right= right-4 i=i+1 end if Negative then gui.line(right, y+2,right-2,y+2,c) right= right-4 end return right end --***************************************************************************** local function DrawNum(right, y, Number, c, bkgnd) --***************************************************************************** -- Paints the input number as right-aligned. Decimal version. return __DN_AnyBase(right, y, Number, c, bkgnd, 10) end --***************************************************************************** local function DrawNumx(right, y, Number, c, bkgnd) --***************************************************************************** -- Paints the input number as right-aligned. Hexadecimal version. return __DN_AnyBase(right, y, Number, c, bkgnd, 16) end --############################################################################# --############################################################################# -- Finally, to the core of my code! --***************************************************************************** local function DumpObjInfo() --***************************************************************************** for i=0x00, 0x17 do local Ypos= 12+8*i local addr= 0x0500 + i local color= "white" if R1u(addr) == 0 then color= "grey" end for j= 0, 24 do DrawNumx( 9+10*j,Ypos,R1u(addr + (j+7)*0x18),color,"black") end end end --***************************************************************************** local function GetBox(ObjIndex) --***************************************************************************** end --***************************************************************************** local function PaintHitBox(ObjIndex) --***************************************************************************** gui.box( R1u(ObjIndex + 20*0x18), math.min(R1u(ObjIndex + 22*0x18),R1u(ObjIndex + 23*0x18)), R1u(ObjIndex + 21*0x18), R1u(ObjIndex + 23*0x18), "clear","white" ) DrawNumx(R1u(ObjIndex + 21*0x18),R1u(ObjIndex + 23*0x18)+2, R1u(ObjIndex + 6*0x18),"white","black") DrawNum(R1u(ObjIndex + 21*0x18),R1u(ObjIndex + 23*0x18)+9, R1u(ObjIndex + 7*0x18),"yellow","black") end --***************************************************************************** local function SimpleStat() --***************************************************************************** local count= 19 for i=0x05, 0x17 do local x= 12*(i-4) local color= "white" if R1u(0x0500+i) == 0 then color= "grey"; count= count-1 end DrawNumx(x,191,R1u(0x0500+i),color,"black") end DrawNum(250,191,count,"yellow","black") count= 0 for i=0x01, 0x04 do if R1u(0x0500+i) ~= 0 then count= count+1 end end DrawNum(250,200,count) end --***************************************************************************** local function ScanObjs() --***************************************************************************** -- local count= 0 for i= 0, 0x17 do local addr= 0x0500 + i if R1u(addr) ~= 0 then -- count= count+1 if R1u(addr) == 0xA9 then -- Spawner object? else PaintHitBox(addr) end -- Spawner or else end -- Exist? end -- for end -- Function local Dr= {0x00, 0x32, 0x50, 0x64, 0x8C, 0xB4, 0xDC, 0xE6} -- Thresholds --***************************************************************************** local function ItemHUD() --***************************************************************************** -- For showing item drop information. DrawNumx(222,216,R1u(0x0043)) --Counter for enemy kills DrawNumx(214,216,R1u(0x0044),"grey") --Increments when $0043 overflows for i= 1, #Dr do local color= "white" local IMO= (i-2) % #Dr +1 --IMO is Index Minus One local tVal, tHigh= (R1u(0x0043)-Dr[IMO])%256, (Dr[i]-Dr[IMO])%256 if (tVal < tHigh) then color= "green" -- Mark next threshold we're hitting. DrawNum(202,216,tHigh - tVal,"yellow") -- How much until next item end DrawNumx(142+10*i,224,Dr[i],color) -- Show threshold list end end --***************************************************************************** local function BasicHUD() --***************************************************************************** -- Odds and ends, mostly. A variety of general information. -- Position. Address 0x0500, object count 0x18 (24), Offset 0 (player) DrawNumx(134,224,R1u(0x0518)) -- i01: Y position DrawNumx(142,224,R1u(0x0500 + 0x19*0x18),"yellow") -- i19: Y sub-pos DrawNumx(102,224,R1u(0x0530)) -- i02: X position DrawNumx(110,224,R1u(0x0500 + 0x1A*0x18),"yellow") -- i1A: X sub-pos -- Player health. Interestingly, at zero HP, our hitbox shrinks a bit. DrawNum(34,212,R1u(0x0048),"white","black") -- $0048: Immediate HP local t= R1u(0x0048) - R1u(0x0049) -- $0049: Delayed HP(blue bar) if t ~= 0 then -- If these don't match, then DrawNum(34,204,t,"green","black") -- we took damage or healed. end t= bit.band(R1u(0x0788),0x3F) -- Inv timer (player obj stats, if t ~= 0 then -- has other info packed in...) DrawNum(46,212,t,"grey","black") end end --***************************************************************************** local function Gui() --***************************************************************************** ScanObjs() SimpleStat() BasicHUD() ItemHUD() -- UpdateKeys() -- if Press("pageup") then Off= (Off+1)%32 end -- if Press("pagedown") then Off= (Off-1)%32 end -- DrawNumx(248,220,Off) -- DrawNum(248,210,count) end gui.register(Gui)
EDIT: Now it shows more stuff! See if you can figure those out!
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
franpa wrote:
Would you take death as a shortcut like in the Speed Demos Archive run? (I'm personally indifferent to this)
Most likely. Although I would take the time to show off the various weapons, that's no reason to avoid shortcuts. Deaths don't take a long time, so why not? AngerFist: So far, I'm also having trouble sinking time into Sorcerer's Maze at this moment. This should change soon, I hope. But my mention that I want a partner still stands. I'm hoping Sonikkustar's offer still stands.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
franpa wrote:
Edit: So 100% will include the optional vertical corridor levels? Level 11, 12, 13, 14 etc.?
Of course! My definition of 100% is whatever affects the password. Except for score (by extension, life bonus derived from score), current EE count, and location we save at. Corridors affect the password. They need to be cleared, right? I will also be collecting items which have no effect on the password other than mark the fact they were collected. In particular, the full life restoring items scattered in a few places. As it stands right now, I'm having a very difficult time remaining focused on this. I still made a small amount of progress, but I am convinced I need someone willing to TAS this alongside me.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Then world 2, it is. We'll probably have a decent run to watch no matter how we do things. I've already made adjustments to the first post. I suppose it's time to test World 2 for a bit, then.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Good items or not, you need to first reach them. 4-1 does have the split power, but it requires breaking an intervening block to reach it first. 4-2 I managed to reach the split quickly in a test (in a difficult hard-to-reach corner), but waiting for the ball to come back took a while. I can point out a few other problems, but under TAS conditions, they might be moot anyway. On the other hand, World 2 also has its share of problems. I should not be blind to those just because it gave a good first impression. But even if we find the "magic" order of worlds to do, that doesn't mean we suddenly have all the MP we need for every stage. Some of the ones that lack any serious power-up will have to be done without using MP regardless, and going through some world with a fair stock of MP coming in won't change things. Anyway, part of my arguments here does get biased due to the fact I have to do things myself, only to have someone speak up after I start going in the wrong direction despite having asked for a bit of assistance earlier. Then again, people tend to speak where there are noticeable incorrect answers rather than no visible answers. The incorrect answer is easily seen, while the lack of any answers are, well... Nothing to see, so no one cares as they see nothing. I hope you can understand some of my irritation, but I do not know what you see. Neither do you know what exact details I'm looking for, just the general stuff, and it only becomes clear when I've already made a mistake. In any case, a decision does need to be made relatively swiftly, so that more time can be set aside for TASing the right path (or reschedule the due dates...?). So far, it's 2 -> 4, or 4 -> 2, followed by 1 -> 3 -> 5 -> 6. I'm still leaning toward 2 first, due to my earlier tests (and my current irritated mood. That's very likely to disappear over time, however). It's just a slight lean, though, and I'll need a little time to clear my thoughts before I make my decision. Feel free to provide some more convincing, though. I certainly won't mind a summary (in your view or anyone else wishing to chime in) of the 9 non-boss levels in worlds 2 and 4. Nothing intricate, we probably won't have the time for that. Besides, we probably won't know the perfect path between the worlds without first... You know, actually TASing the game through, so no need to perfect our knowledge of the route immediately.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
The research I ask for can come from any source, even myself. I've taken a look and I note that World 2 might actually be a better starting choice, especially since its first stage nets you a rather lofty sum of MP somehow. The world lends itself pretty decently to low MP usage in general, so perhaps I should change the route to 2 -> 1 -> 3 -> 4 -> 5 -> 6. ... And this decision affects no one other than myself and DarkKobold at the moment. Regardless, before I make the changes, I want to first see whether there is an outcry of the fact that I may change the route.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
lapogne36 wrote:
[...] I am not sure that start with world 1 is the best choice, since you will not be able to purchase an useful item in levels 1-3 AND 1-4 , so it will cost some time (since these levels can't release any useful item).
Got any suggestions on which world to start in where we are not in as significant a disadvantage due to lack of MP? I need to fix an order to do the worlds so we can have comparisons week by week. Should one team begin at World 1 and another begin at World 3, it will be impossible to judge who's the "winner" here without forcing both teams to complete the first six worlds in one massive lump. And that massive lump of "emptiness" in the meantime while waiting for those six worlds route from each of the teams is undesirable. Regardless. You've come forward to point out a possible flaw in my enforced route. I'll have to ask for research to decide whether to make changes, as coming up with a "better" route on the spot will only lead to more complications.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
It's an idea. At least there will be some form of competition here, even if no one else shows up. A friendly competition with shared information. We can begin TASing anytime. Just remember those due dates I set up.
Post subject: Hey, DarkKobold! You there?
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Looks pretty barren so far, more devoid of activity than I'd like. As such, I'm joining with DarkKobold. If I didn't just suddenly spring this contest up, we would have worked together on this game anyway. Also, the presence of this contest greatly encourages us to post regular weekly updates. Hopefully with an encode to go with it. If that doesn't bring people in later weeks, what will? The contest will remain open throughout, even if no one else joins for the first ten weeks. Who knows, maybe someone will find something we miss! As for arbitrary points, I've thought of one way to handle it: Adding points, dependent on participant teams, linear model: The first place team of each week will get points equal to the number of participating teams that week. The second place team will get that much minus 1. Third place gets the first place amount minus 2. And so on, where the last place team gets 1 point.
Post subject: PSXjin Lua scripting.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Strange. I didn't see any thread about general purpose lua stuff here. I figure I'd create one. In creation of this thread, I will start off by posting a quick script to help with handling the analog input using the main PSXjin window, instead of that clunky analog control window. Download analog.lua
Language: lua

-- Simplify handling analog input. 1 player only. -- FatRatKnight local keys, lastkeys= input.get(),input.get() --***************************************************************************** local function UpdateKeys() lastkeys= keys; keys= input.get() end --***************************************************************************** local function Press(k) return keys[k] and (not lastkeys[k]) end --***************************************************************************** local function Limits(v,l,h) return math.max(math.min(v,h),l) end --***************************************************************************** --***************************************************************************** local function GuiTextRight(x,y,t,c) --***************************************************************************** x= x - #tostring(t)*4 gui.text(x,y,t,c) end local CA= { xleft= 128, xright= 128, yleft= 128, yright= 128 } --***************************************************************************** local function ResetAnalog() --***************************************************************************** -- Should be obvious: Restore defaults. CA.xleft= 128; CA.xright= 128 CA.yleft= 128; CA.yright= 128 end local StickyAnalog= true --***************************************************************************** local function HandleAnalog() --***************************************************************************** -- Apply the input each frame. Reset it too, depending on mode. joypad.setanalog(1,CA) if not StickyAnalog then ResetAnalog() end end emu.registerbefore(HandleAnalog) --***************************************************************************** local function ControlAnalog() --***************************************************************************** -- Handle user input through main window UpdateKeys() -- Analog handler and display if keys.leftclick then CA.xleft= Limits(CA.xleft + keys.xmouse - lastkeys.xmouse, 0,255) CA.yleft= Limits(CA.yleft + keys.ymouse - lastkeys.ymouse, 0,255) gui.line(keys.xmouse, keys.ymouse, keys.xmouse - CA.xleft + 128, keys.ymouse - CA.yleft + 128, 0x0040FFFF) -- Blue end if keys.rightclick then CA.xright= Limits(CA.xright + keys.xmouse - lastkeys.xmouse, 0,255) CA.yright= Limits(CA.yright + keys.ymouse - lastkeys.ymouse, 0,255) gui.line(keys.xmouse, keys.ymouse, keys.xmouse - CA.xright + 128, keys.ymouse - CA.yright + 128, -0x00BFFF01) -- Red; 80Red bug end -- Option and reset switches. if Press("insert") then StickyAnalog = not StickyAnalog end if Press("delete") then ResetAnalog() end -- Handle displaying the coordinates. local color= -0x00000001 -- White. 80Red glitch bypass if StickyAnalog then color= 0x00FF80FF end -- Mostly Green GuiTextRight(70, 5,CA.xleft, color) GuiTextRight(70,13,CA.yleft, color) GuiTextRight(90, 5,CA.xright,color) GuiTextRight(90,13,CA.yright,color) end gui.register(ControlAnalog) --***************************************************************************** while true do --***************************************************************************** -- I have observed glitches without this in place. emu.frameadvance() end
Well... That was the main point of my creating this thread, to share this code. But an entire thread dedicated to this one thing felt out of place, so I'll make it a general-purpose thread instead. So, uh... Someone find something to discuss...? I mainly wanted to share that code.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
mklip2001 wrote:
However, I have one question nobody's addressed here. In this game, you can get other weapons in the shop. Do any of those damage bosses more, enough to save time in a run?
All hits to a boss deals 1 damage, no matter the source. The invincibility will not wear off any sooner, either. Therefore, using a new weapon will have no effect. Although, the spiky weapon can knock away projectiles, any possible lag reduction must make up for purchasing it from the shop as well as the time taken to equip it. Other items have not been found to be useful. Even the jet shoes don't help us against any of the bosses, as plain jumps are typically enough to reach most of them, and we can't get enough extra hits against end boss 3, that clown dog, to destroy it before that invincible roll around. Part of why our route is to test items against end bosses, while still making decent progress. Not a single case worked out for us for any item.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
Brandon wrote:
Somewhat interested, but can't commit right now. I think the game choice is fitting, due to the whole Steven Jobs having a hand in making Breakout thing. It'd also be really awesome if it were in fact hexable. Maybe I could sign up and participate only on the weeks I am available to?
You may join whenever you are ready. I'll allow you to join in week increments if you prefer. You are not required to participate since day one. On a side note, I'll probably be joining DarkKobold myself in an attempt to get things rolling, to show things are happening here, if no one else dares show up. Yes, I'm the contest creator here, but does that mean I should automatically invalidate myself? Besides, we were planning on working together on this anyway, but I then decided to turn it into a contest form. EDIT: AngerFist, I will divide my time between this and TGL if it comes to that. Don't worry.
Editor, Experienced Forum User, Published Author, Skilled player (1173)
Joined: 9/27/2008
Posts: 1085
AngerFist wrote:
You sir, will directly and indirectly come up with everything to not work on The Guardian Legend. Good day.
As a host to this contest, and not an actual participant, this means I have very little to do. I still have plenty of time to work on TGL. Don't worry, I'll be making progress soon.