Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Luascript for bizhawk 2.9.1
- -- by mugg1991
- -- Motocross Maniacs gb
- function text(x, y, text, color)
- gui.pixelText(x, y, text,color,0x00000000)
- end
- function drawButton(posx,posy,width,height,label,color,frequency,clickedfunction)
- if X>posx and X<posx+width and Y>posy and Y<posy+height then
- if clicked and clickedFrames%frequency==1 then
- clickedfunction()
- end
- gui.drawBox(posx,posy,posx+width,posy+height,0x00606060,color+0xFF484848)
- else
- gui.drawBox(posx,posy,posx+width,posy+height,0x00606060,color)
- end
- text(posx+2,posy+2,label,0xFFFFFFFF)
- end
- local drawFrameCountAndInput = function(x,y)
- if movie.mode()=="PLAY" then
- text(x, y,emu.framecount().."/"..movie.length(),0xFFFFFFFF)
- else
- text(x, y,emu.framecount(),0xFFFFFFFF)
- end
- if emu.islagged() then
- text(x, y+8,emu.lagcount() .. " *",0xFFF05050)
- else
- text(x, y+8,emu.lagcount(),0xFFF05050)
- end
- local inputtable = {}
- if movie.mode()=="INACTIVE" then
- inputtable = joypad.getimmediate()
- elseif movie.mode()=="PLAY" or movie.mode()=="RECORD" then
- inputtable = movie.getinput(emu.framecount()-1)
- end
- local buttons = {["Up"]="^", ["Down"]="v", ["Left"]="<", ["Right"]=">", ["Select"]="s", ["Start"]="S", ["A"]="A", ["B"]="B", ["L"]="L", ["R"]="R"}
- local s = ""
- for k,v in pairs(inputtable) do
- if v==true then
- s=s..buttons[k]
- end
- end
- text(x,y+16,s,0xFFffffff)
- end
- function hex(num)
- local dig = 2
- local hexstr = '0123456789ABCDEF'
- local s = ''
- --while num > 0 do
- while dig > 0 do -- use digit instead so there is padding
- local mod = math.fmod(num, 16)
- s = string.sub(hexstr, mod+1, mod+1) .. s
- num = math.floor(num / 16)
- dig = dig - 1
- end
- if s == '' then s = '0' end
- return s
- end
- local displayItems = function()
- hiddenjets=0
- items=0
- for i=0,192,8 do
- item_type = memory.read_u8(0xca00+i)
- item_status = memory.read_u8(0xca01+i)
- item_x = memory.read_u8(0xca03+i)+memory.read_u8(0xca04+i)*256
- item_y = memory.read_u8(0xca02+i)
- item_xcam = item_x-Xcam/256
- item_ycam = item_y-Ycam/256+28
- exists=false
- if item_status==3 and item_y~=0 then exists=true end
- if item_type>0 and item_type<8 and exists then
- items=items+1
- end
- if item_type==6 and exists then
- hiddenjets=hiddenjets+1
- end
- if exists then
- for p=0,4096,4096 do --4096 is the length of the course. We want to display items for both laps.
- if item_ycam < 24 then -- don't obscure lua hud
- gui.drawBox(item_xcam+20+p,item_ycam,item_xcam+36+p,item_ycam+16,0x00FF0000,0x40FFFFFF)
- else
- gui.drawBox(item_xcam+20+p,item_ycam,item_xcam+36+p,item_ycam+16,0x60FF0000,0x20FF0000)
- text(item_xcam+21+p,item_ycam+1,itemTable[item_type],0xFF000000)
- end
- end
- end
- end
- text(110,30,"jets: "..hiddenjets,0x80000000)
- text(156,30,"items: "..items,0x80000000)
- end
- function file_exists(name)
- local f=io.open(name,"r")
- local exists=false
- if f~=nil then
- exists=true
- io.close(f)
- else
- exists=false
- end
- return exists
- end
- local writeGhostToFile = function()
- FileName=LevelName.."_Ghost_"..hex(Minutes).."_"..hex(Seconds).."_"..hex(Milliseconds)..".txt"
- if file_exists(FileName) then
- print("NOTE: The ghost file was not written because there already exists a ghost file with the same record time.")
- else
- io.output(FileName)
- table.sort(ghostTable)
- for key,value in pairs(ghostTable) do
- io.write(key.." "..ghostDataTable[value].."\n")
- end
- io.close()
- if file_exists(FileName)==true then
- print("NOTE: File "..FileName.." has been written.")
- elseif file_exists(FileName)==false then
- print("NOTE: File has not been written because of an unknown error.")
- end
- end
- end
- local writeGhostToTable = function()
- ghostFrames=ghostFrames+1
- ghostTable[ghostFrames]=TotalTime
- ghostDataTable[TotalTime]="Time:"..TotalTime.." X:"..Xscreen.." Y:"..Yscreen.." Xcam:"..Xcam.." Ycam:"..Ycam.." Speed:"..Speed2.." Angle:"..Angle.." Nitro:"..Nitros -- extra table because table.sort didn't work in my favor
- if TotalTime>50 then
- if TotalTimeUnchangedCount>20 or recordingGhost==false then --recording finished
- if Xpos~=0 then
- writeGhostToFile()
- else
- print("NOTE: The ghost file wasn't written because you haven't moved.")
- end
- recordingGhost=false
- ghostFrames=0
- end
- end
- end
- function doLine(filename)
- local f = io.open(filename, "r")
- local iterator = function(f, prevLine)
- if f==nil then
- return nil
- else
- local success, line = pcall(function()
- return f:read("*l"):gsub("\n",""):gsub("\r","")
- end)
- if not success or line == nil then
- f:close()
- line = nil
- end
- return line
- end
- end
- return iterator, f, ""
- end
- local readGhostFromFile = function()
- local TimeIndex
- local XscreenIndex
- local YscreenIndex
- local XcamIndex
- local YcamIndex
- local SpeedIndex
- local AngleIndex
- local NitroIndex
- local highestTimeInGhost = 0
- for line in doLine(PlayFilePath) do -- finding the settings and assigning them to variables
- TimeIndex = string.find(line,"Time:")
- XscreenIndex = string.find(line,"X:")
- YscreenIndex = string.find(line,"Y:")
- XcamIndex = string.find(line,"Xcam:")
- YcamIndex = string.find(line,"Ycam:")
- SpeedIndex = string.find(line,"Speed:")
- AngleIndex = string.find(line,"Angle:")
- NitroIndex = string.find(line,"Nitro:")
- Time = tonumber( string.sub(line, TimeIndex + 5, XscreenIndex - 1) )
- Xscreen = tonumber( string.sub(line, XscreenIndex + 2, YscreenIndex - 1) )
- Yscreen = tonumber( string.sub(line, YscreenIndex + 2, XcamIndex - 1) )
- Xcam = tonumber( string.sub(line, XcamIndex + 5, YcamIndex - 1) )
- Ycam = tonumber( string.sub(line, YcamIndex + 5, SpeedIndex - 1) )
- Speed = tonumber( string.sub(line, SpeedIndex + 6, AngleIndex - 1) )
- Angle = tonumber( string.sub(line, AngleIndex + 6, NitroIndex - 1) )
- Nitros = tonumber( string.sub(line, NitroIndex + 6) )
- playTable[Time] = {
- Xscreen = Xscreen,
- Yscreen = Yscreen,
- Xcam = Xcam,
- Ycam = Ycam,
- Speed = Speed,
- Angle = Angle,
- Nitros = Nitros
- }
- if Time > highestTimeInGhost then highestTimeInGhost = Time end
- end
- if TotalTime > highestTimeInGhost then
- playTable = {}
- playingGhost = false
- print("NOTE: Cannot play ghost, since its data is in the past.")
- end
- end
- local readGhostFromTable = function()
- if playTable[2]~=nil then -- ghost is loaded
- if playTable[TotalTime] == nil then
- -- ghost file reached its end
- playTable = {}
- playingGhost = false
- print("NOTE: End of ghost file reached.")
- else
- Xscreen = playTable[TotalTime].Xscreen
- Yscreen = playTable[TotalTime].Yscreen
- Xcam = playTable[TotalTime].Xcam / 256
- Ycam = playTable[TotalTime].Ycam / 256
- Speed = playTable[TotalTime].Speed
- Angle = playTable[TotalTime].Angle
- Nitros = playTable[TotalTime].Nitros
- -- draw ghost
- gui.drawBox(Xcam+20,Ycam,Xcam+36,Ycam+16,0xFFFF0000,0xFFFFFFFF)
- print(Xcam, Ycam, Xscreen, Yscreen)
- end
- else -- ghost not loaded yet
- readGhostFromFile()
- end
- end
- local displayGhosts = function()
- gui.drawBox(200,-1,300,172,0x00000000,0xFF000000)
- gui.drawLine(205,12,296,12,0xFF303030)
- --title lol
- text(205,4,"Ghost menu",0xFFFFFFFF)
- -- mode
- if playingGhost then
- text(205,16,"(playback)",0x60FFFFFF)
- elseif recordingGhost then
- text(205,16,"(recording)",0x60FFFFFF)
- else
- text(205,16,"(idle)",0x60FFFFFF)
- end
- --recording button
- if recordingGhost then
- drawButton(205,52,35,10,"Stop",0xFF484848,20,function()
- recordingGhost=false
- end)
- writeGhostToTable()
- gui.drawEllipse(245,54,6,6,0xFFFF0000,0xFFFF0000)
- else
- drawButton(205,52,35,10,"Record",0xFF484848,20,function()
- if playingGhost then
- print("NOTE: Stop playing back before recording.")
- ghostTable = {}
- ghostDataTable = {}
- recordingGhost=false
- else
- if TotalTime~=0 or Level==0 then
- print("NOTE: Not recording. Click Record before a course starts (time is 0).")
- ghostTable = {}
- ghostDataTable = {}
- recordingGhost=false
- else
- recordingGhost=true
- end
- end
- end)
- end
- -- selected playback file
- if PlayFilePath=="" then
- t="-"
- else
- t=PlayFilePath:sub(-21)
- end
- drawButton(205,82,95,10,t,0xFF181818,20,function()
- FormsSelectedPath = forms.openfile()
- end)
- if FormsSelectedPath ~= nil then PlayFilePath=FormsSelectedPath end
- -- playback buttons
- if playingGhost then
- drawButton(205,70,35,10,"Stop",0xFF484848,20,function()
- playingGhost=false
- end)
- readGhostFromTable()
- gui.drawLine(245,72,245,78,0xFF00FF00)
- gui.drawLine(246,73,246,77,0xFF00FF00)
- gui.drawLine(247,74,247,76,0xFF00FF00)
- gui.drawPixel(248,75,0xFF00FF00)
- else
- drawButton(205,70,35,10,"Play",0xFF484848,20,function()
- if recordingGhost then
- print("NOTE: Stop recording before playing back a ghost.")
- playingGhost=false
- playTable={}
- elseif FormsSelectedPath==nil then
- print("NOTE: Please select a file before playing back.")
- playingGhost=false
- playTable={}
- elseif tostring(PlayFilePath):sub(-4)~=".txt" then
- print("NOTE: The selected file is not a .txt file.")
- playingGhost=false
- playTable={}
- elseif not file_exists(PlayFilePath) then
- print("NOTE: The selected file doesn't exist.")
- playingGhost=false
- playTable={}
- else
- playingGhost=true
- end
- end)
- end
- end
- local getMouse = function()
- X = input.getmouse().X+20
- Y = input.getmouse().Y+28
- clicked = input.getmouse().Left
- if clicked then clickedFrames = clickedFrames + 1
- else clickedFrames = 0 end
- end
- event.onexit(function()
- client.SetGameExtraPadding(0,0,0,0)
- end)
- event.onloadstate(function()
- if recordingGhost then
- recordingGhost=false
- print("NOTE: The recording has stopped because you have loaded a state.")
- end
- end)
- memory.usememorydomain("System Bus")
- itemTable = {
- [-1] = "???",
- [2] = "Speed",
- [3] = "Time",
- [4] = "Nitro",
- [5] = "Rig",
- [6] = "Jet",
- [7] = "Bike",
- }
- difficultyTable = {
- [-1]="?",
- [0]="A",
- [1]="B",
- [2]="C"
- }
- ghostTable = {}
- ghostDataTable = {}
- playTable = {}
- BOOL_items=false
- BOOL_ghosts=false
- X = 0
- Y = 0
- clicked=false
- clickedFrames=0
- recordingGhost=false
- playingGhost=false
- TotalTimeUnchangedCount=0
- TotalTimeBefore=0
- TotalTime=0
- ghostFrames=0
- PlayFilePath="" -- the file path name of the ghost file that should be played back
- if BOOL_ghosts then client.SetGameExtraPadding(20,28,130,0)
- else client.SetGameExtraPadding(20,28,20,0) end
- console.clear()
- -----
- while true do
- ---- Mouse
- getMouse()
- if emu.framecount()>400 then
- --declare values:
- Minutes = memory.read_u8(0xc804)
- Seconds = memory.read_u8(0xc803)
- Milliseconds = memory.read_u8(0xc802)
- MinutesLeft = memory.read_u8(0xc882)
- SecondsLeft = memory.read_u8(0xc881)
- MillisecondsLeft = memory.read_u8(0xc880)
- Speed1 = memory.read_s8(0xc810) -- pixels to advance screen
- Speed2 = memory.read_u16_le(0xc38a)
- Nitros1 = memory.read_u8(0xc792)
- Nitros2 = memory.read_u8(0xc812)
- Indicator = memory.read_u8(0xc780)
- if Indicator==1 then Nitros=Nitros1 else Nitros=Nitros2 end
- Xpos = memory.read_u16_le(0xe903)
- Xcam = memory.read_u24_le(0xc902)
- Ycam = memory.read_u16_le(0xc900)
- Xscreen = memory.read_u8(0xcc01)+8
- Yscreen = memory.read_u8(0xcc00)+8
- Level = memory.read_u8(0xc018)
- Difficulty = memory.read_u8(0xc01B)
- if Difficulty<0 or Difficulty>2 then Difficulty=-1 end
- LevelName=Level..difficultyTable[Difficulty]
- if Level~=0 then
- Angle = memory.read_u8(0xcc02) -- this is upper left corner, value is a pointer for what graphic to load I guess
- if Angle%2==0 then Angle=1+Angle/4
- else Angle=16+(Angle+1)/4 end
- if Speed2==0 then Angle=0 end
- TotalTime = hex(Milliseconds) + hex(Seconds)*100 + hex(Minutes)*6000
- else
- Angle = -1
- TotalTime = -1
- end
- Angle = math.floor(Angle) -- thanks newer Bizhawk lua
- if TotalTimeBefore==TotalTime then
- TotalTimeUnchangedCount=TotalTimeUnchangedCount+1
- else
- TotalTimeUnchangedCount=0
- end
- TotalTimeBefore=TotalTime
- --lines boxes
- gui.drawBox(-1,27,20,172,0x00000000,0xFFFFFFFF)
- gui.drawBox(179,27,201,172,0x00000000,0xFFFFFFFF)
- gui.drawBox(-1,-1,201,28,0x00000000,0xFF202020)
- gui.drawLine(34,0,34,27,0xFF404040)
- gui.drawLine(156,0,156,27,0xFF404040)
- --racetrack visualisation
- gui.drawBox(30,27,160,28,0xFFA0A0A0)--track
- gui.drawLine(30,27,30,28,0xFFa0FF00)--start
- gui.drawLine(95,27,95,28,0xFFa0FF00)--middle
- gui.drawLine(160,27,160,28,0xFFa0FF00)--finish
- Xtrack=30+(Xpos/8192)*130
- gui.drawLine(Xtrack,27,Xtrack,28,0xFFFF0000)--you
- --display values
- text(45,2,"Time",0x80FFFFFF)
- text(49,10,"Gas",0x80FFFFFF)
- text(103,2,"Spd",0x80FFFFFF)
- text(103,10,"Ntr Angl",0x80FFFFFF)
- text(114,18,"pos",0x80FFFFFF)
- text(38,18,"cam",0x80FFFFFF)
- if Level ~=0 then
- text(1,30,"Lv: "..LevelName,0x80000000)
- --text(74,30,TotalTime,0x80000000)
- --text(46,30,Angle,0x80000000)
- text(65,2,hex(Minutes)..":"..hex(Seconds).."."..hex(Milliseconds),0xFFFFFFFF)
- text(65,10,hex(MinutesLeft)..":"..hex(SecondsLeft).."."..hex(MillisecondsLeft),0xFFFFFFFF)
- text(119,2,Speed2,0xFFFFFFFF)
- text(119,10,Nitros,0xFFFFFFFF)
- text(147,10,Angle,0xFFFFFFFF)
- text(134,18,Xpos,0xFFFFFFFF)
- text(53,18,Xcam,0xFFFFFFFF)
- text(88,18,Ycam,0xFFFFFFFF)
- end
- drawButton(160,2,35,10,"ITEMS",0xFF484848,15,function()
- BOOL_items= not BOOL_items
- end)
- drawButton(160,14,35,10,"GHOSTS",0xFF484848,15,function()
- BOOL_ghosts= not BOOL_ghosts
- if BOOL_ghosts then
- client.SetGameExtraPadding(20,28,130,0)
- else
- client.SetGameExtraPadding(20,28,20,0)
- end
- end)
- if BOOL_items==true then
- text(189,4,"o",0xFF00c000)
- displayItems()
- else
- text(189,4,"x",0xFFF05050)
- end
- if BOOL_ghosts==true then
- text(189,16,"o",0xFF00C000)
- displayGhosts()
- else
- text(189,16,"x",0xFFF05050)
- end
- end
- drawFrameCountAndInput(2,2)
- --emu.frameadvance()
- emu.yield()
- end
Advertisement
Add Comment
Please, Sign In to add comment