Advertisement
Guest User

boom-plus.lua

a guest
Jul 21st, 2017
8
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.39 KB | None | 0 0
  1. --
  2. -- ░█▀▄░█▀█░█▀█░█▄█░░░░█░░░█░█░█▀█
  3. -- ░█▀▄░█░█░█░█░█░█░░░░█░░░█░█░█▀█
  4. -- ░▀▀░░▀▀▀░▀▀▀░▀░▀░▀░░▀▀▀░▀▀▀░▀░▀
  5. --
  6. --
  7. -- Fair warning: this code is about as bad as the things it does to games.
  8. -- GBA support experimental and frankly quite boring.
  9.  
  10.  
  11. --Original NES Braidulator by Antony Lavelle 2009 got_wot@hotmail.com http://www.the-exp.net
  12.  
  13.  
  14.  
  15. --Change these settings to adjust options
  16.  
  17.  
  18. --Which key you would like to function as the "rewind key"
  19.  
  20.     local rewindKey = 'W' -- Hold this to go back in time!
  21.  
  22.     --hacks                     = false;
  23.     hacks                   = 'wario4'
  24.     wario4_tileset          = true;
  25.     wario1_tileset          = false;
  26.     wario1_levelload        = false;
  27.     wario4_levelid          = false;
  28.  
  29. -- Keys. Feel free to change them to something convenient, because I have a weird keyboard layout
  30.  
  31.     randomkey       = "A"   -- Just your standard fare. One random WRAM byte.
  32.     plusminuskey    = "S"   -- +/- on one random WRAM byte. Probably the safest you can do which still has some effect.
  33.     powerkey        = "D"   -- Power corruption! 16 random bytes. The most fun key you can press.
  34.     highkey         = "F"   -- On GB, random byte from HRAM, may have drastic consequences. On GBA, power corruption on IRAM
  35.     vramkey         = "G"   -- Messes up vram (graphics). Purely visual - totally safe.
  36.  
  37.     freezekey = "H" -- Freezes a random byte in memory indefinedly. May have totally different effects from regular corruption.
  38.     unfreezekey = "J" -- Unfreezes every frozen byte. This also happens automatically when rewinding.
  39.      
  40.     savetileskey = "K" -- Save current tiles.
  41.     restoretileskey = "L" -- Restore saved tiles. Purely visual, can be used to copy tiles from game to game etc.
  42.     wrammap = "Q" -- Display an interactive memory map, one pixel per byte.
  43.     -- Opacity = value. Blue = byte changed this frame. Green = HRAM.
  44.     -- Left: +1 Right: -1 Middle: set to $FF
  45.     -- Warning: SLOW! PARTLY BROKEN FOR GBA!
  46.  
  47.     rewindon = "E" -- Switches rewinding on and off. May save some 15%, depending on your computer.
  48.      
  49.     debugkey = "\\" -- Displays some boring CPU info.
  50.  
  51.  
  52.  
  53.     --How much rewind power would you like? (The higher the number the further back in time you can go, but more computer memory is used up)
  54.     --Do not set to 0!
  55.     local saveMax = 2000;
  56.  
  57.  
  58.  
  59.     funtimes    = 0;
  60.     txttime     = 0;
  61.  
  62.  
  63.  
  64. --The stuff below is for more advanced users, enter at your own peril!
  65.     print("Boom loaded!")
  66.     if hacks then
  67.         print("Hack mode: ", hacks)
  68.     end
  69.  
  70.     function rainbowcolor(ri)
  71.         freq = 0.15
  72.         r = math.sin(freq*ri)   * 127 + 128
  73.         g = math.sin(freq*ri+2) * 127 + 128
  74.         b = math.sin(freq*ri+4) * 127 + 128
  75.         return {r, g, b}
  76.     end
  77.      
  78.     function randmemory(from, to) -- gets a random memory offset, avoiding the stack
  79.         if gb then
  80.             while (true) do
  81.                 bang = math.random(from, to)
  82.                 if bang < sp or bang > stack then
  83.                 break
  84.             end
  85.         end
  86.         return bang
  87.     else
  88.         return math.random(from, to)
  89.         end
  90.     end
  91.      
  92.     frozen = {}
  93.     crashi = 0
  94.      
  95.     vram = {}
  96.     wram = {}
  97.     prevwram = {}
  98.     s = {0xff, 0xff, 0x00, 0x00, 0xbb, 0xbb, 0x8b, 0x8b, 0x68, 0x68, 0x8b, 0x8b, 0xeb, 0xeb, 0x18, 0x18}
  99.      
  100.     stack = -1
  101.      
  102.     -- dumb format for speed/convenience
  103.     invalid_opcodes = {[0xd3]= true, [0xdb]= true, [0xdd]= true, [0xe3]= true, [0xe4]= true, [0xeb]= true, [0xec]= true, [0xed]= true, [0xfd]= true, [0xf4]= true}
  104.      
  105.     local saveArray = {};--the Array in which the save states are stored
  106.     local saveCount = 1;--used for finding which array position to cycle through
  107.     local save; -- the variable used for storing the save state
  108.     local rewindCount = 0;--this stops you looping back around the array if theres nothing at the end
  109.     local savePreventBuffer = 1;--Used for more control over when save states will be saved, not really used in this version much.
  110.      
  111.     local saveFrequency = 10; -- look at me mom, I'm editing LIVE!
  112.     local timer = -1;
  113.      
  114.     local rewind = true
  115.  
  116.     if hacks == 'wario1' then
  117.         memory.writebyte(0xA8C7, 0x01);
  118.     end
  119.  
  120.     if hacks == 'wario1' and wario1_tileset == true then
  121.         --preliminary block writing in memory
  122.         print('Writing tileset blocks on the level...');
  123.         blockCUR = 0x00;
  124.         for layoutRAM = 0xC000, 0xC200 do
  125.             memory.writebyte(layoutRAM, 0x7F);
  126.         end
  127.         layoutRAM = 0xC200;
  128.         for blockCUR = 0x00, 0x80 do
  129.             memory.writebyte(layoutRAM,blockCUR);
  130.             layoutRAM = layoutRAM + 0x01;
  131.         end
  132.         for layoutRAM = 0xC280, 0xC500 do
  133.             memory.writebyte(layoutRAM, 0x7F);
  134.         end
  135.         for layoutRAM = 0xC500, 0xC600 do
  136.             memory.writebyte(layoutRAM, 0x00);
  137.         end
  138.     end
  139.  
  140.     if hacks == 'wario4' and wario4_levelid then
  141.         memory.writebyte(0x03000023,wario4_levelid);
  142.         print('Level ID Set to ', wario4_levelid)
  143.     end
  144.  
  145.     if hacks == 'wario4' and wario4_tileset == true then
  146.         --preliminary block writing in memory
  147.         print('Writing tileset blocks on the level...');
  148.         memory.writebyte(0x03000C3C, 0x08);
  149.         blockCUR = 0x0000;
  150.     --  for layoutRAM = 0x02000430, 0x201042F do
  151.     --      memory.writeword(layoutRAM, 0x7F);
  152.     --  end
  153.     --  layoutRAM = 0x020000E4;
  154.         -- Set room width
  155.         memory.writebyte(0x03000060,0x29);
  156.         memory.writebyte(0x03000068,0x29);
  157.         --height
  158.         memory.writebyte(0x03000062,0x17);
  159.         memory.writebyte(0x0300006A,0x17);
  160.        
  161.        
  162.         layoutRAM = 0x020000E4 - 0x0050 - 0x0050;
  163.        
  164.         counter = 0;
  165.         counter2 = 0;
  166.         counter3 = 1;
  167.     --  for blockCUR = 0x0000, 0x01FF do
  168.         for blockCUR = 0x0000, 0x02FF do
  169.             if (counter==8) then
  170.                 layoutRAM = layoutRAM + 0x0042;
  171.                 counter = 0;
  172.                 counter2 = counter2 + 1;
  173.             end
  174.             if (counter2==22) then
  175.                 layoutRAM = (0x020000E4-0x0050-0x0050) + (0x0010*counter3);
  176.                 counter2 = 0;
  177.                 counter3 = counter3 + 1;
  178.             end
  179.             memory.writeword(layoutRAM,blockCUR);
  180.             layoutRAM = layoutRAM + 0x0002;
  181.             counter = counter + 1;
  182.         end
  183.     --  for layoutRAM = 0xC280, 0xC500 do
  184.     --      memory.writebyte(layoutRAM, 0x7F);
  185.     --  end
  186.     --  for layoutRAM = 0xC500, 0xC600 do
  187.     --      memory.writebyte(layoutRAM, 0x00);
  188.     --  end
  189.         print('Remember tileset address is 0xFINDMEPLEASE');
  190.     end
  191.  
  192.     if hacks == 'wario1' and wario1_levelload == true then
  193.         print('Loading Level from wario.dat...');
  194.         open_level = io.open('wario.dat', "rb") or false;
  195.         if open_level == false then
  196.             print('Can\'t open wario.dat');
  197.         else
  198.             load_level = open_level:read("*all");
  199.             print('COMING SOON');
  200.     --      load_status == 1;
  201.     --      if load_level[0x1FFF] or load_level[0x2000] then
  202.     --          load_status = 0;
  203.     --      end
  204.             print(load_level:read(1));
  205.             if load_level[0x1FFF] then
  206.                 layoutRAM = 0xC000;
  207.                 for i = 0x0000, 0x1FFF do
  208.                     memory.writebyte(layoutRAM, load_level:read(i));
  209.                 end
  210.             else
  211.                 print('ERROR: A level has to be 0x1FFF bytes long.');
  212.             end
  213.             open_level:close();
  214.         end
  215.     end
  216.  
  217.     while (true) do
  218.     keys = input.get();
  219.      
  220.     timer = timer + 1;
  221.     savePreventBuffer = savePreventBuffer-1;
  222.     if savePreventBuffer==0 then
  223.     savePreventBuffer = 1;
  224.     end;
  225.     if hacks =='wario1' then
  226.     --  memory.writebyte(0xA8C5, 0x01); -- Debug
  227.         memory.writebyte(0xA99D, 0x10); -- Free camera
  228.     --  memory.writebyte(0xA61C, 0x00); -- override music thing
  229.         action = memory.readbyte(0xA91A);
  230.         pause = memory.readbyte(0xA908);
  231.         if action == 0x09 and pause == 0x00 then -- death action
  232.             memory.writebyte(0xA91A, 0x00); -- Prevent death
  233.         end
  234.  
  235.     --  memory.writebyte(0x94E2, 0x03); -- NOT Free camera
  236.        
  237.     end
  238.     keys = input.get();
  239.     if keys[rewindKey] then
  240.     savePreventBuffer = 5;
  241.  
  242.  
  243.     if rewindCount==0 then
  244.     --makes sure you can't go back too far could also include other things in here, left empty for now.
  245.     else
  246.     savestate.load(saveArray[saveCount]);
  247.     saveCount = saveCount-1;
  248.     rewindCount = rewindCount-1;
  249.     if saveCount==0 then
  250.     saveCount = saveMax-1;
  251.     end;
  252.     end;
  253.     local HUDMATH = rewindCount / saveMax;--Making the rewind time a percentage.
  254.     gui.text(1,0, string.format("%.2f%%", HUDMATH * 100));--Displaying the time onscreen.
  255.     if math.fmod(timer, 30) <= 15 then
  256.     gui.text(138,8*2, "<<"); -- picky, picky
  257.     end;
  258.     end;
  259.     if rewind and savePreventBuffer==1 and math.fmod(timer, saveFrequency) == 0 then
  260.     -- gui.text(80,15,"");
  261.     saveCount=saveCount+1;
  262.     if saveCount==saveMax then
  263.     saveCount = 1;
  264.     end
  265.     rewindCount = rewindCount+1;
  266.     if rewindCount==saveMax-1 then
  267.     rewindCount = saveMax-2;
  268.     end;
  269.     save = savestate.create();
  270.     savestate.save(save);
  271.     saveArray[saveCount] = save;
  272.     end;
  273.     if math.fmod(timer, 32) == 0 then
  274.     header = memory.readbyte(0x133) -- last byte of logo on GB
  275.     if header == 0x3e then
  276.     gb = true
  277.     gba = false
  278.     else
  279.     gb = false
  280.     gba = true
  281.     end
  282.     end
  283.     if gb then
  284.     pc = memory.getregister('pc')
  285.     op = memory.readbyte(pc)
  286.     is_invalid = invalid_opcodes[op]
  287.     sp = memory.getregister('sp')
  288.     if crashi <= 1 then
  289.     if stack == -1 and sp < 0xe000 and sp >= 0xc000 then
  290.     stack = (math.ceil(sp / 0x10) * 0x10)-1
  291.     print(string.format("sp=%04X, stack detected at %04X", sp, stack))
  292.     elseif sp > 0xFF00 then
  293.     --print("Stack detected in HRAM, restart?")
  294.     stack = -1
  295.     end
  296.     end
  297.     --if sp <=
  298.     end
  299.     if keys[debugkey] then
  300.     if gb then
  301.     debugtext = string.format("pc=%04X sp=%04X", pc, sp)
  302.     gui.text(160-(string.len(debugtext)*4),0, debugtext, 'green');
  303.     debugtext = string.format("opcode %02X", op)
  304.     gui.text(160-(string.len(debugtext)*4),8, debugtext, 'green');
  305.     else
  306.     debugtext = string.format("GBA")
  307.     gui.text(240-(string.len(debugtext)*4),0, debugtext, 'green');
  308.     end
  309.     end
  310.     if gb then
  311.     if pc >= 0x8000 or sp < 0x8000 or is_invalid or pc == 0x39 then
  312.     crashi = crashi + 1
  313.     if crashi >= 2 then
  314.     gui.text(1,8, crashi, 'red');
  315.     if crashi > 10 then info = "Crashed" else info = "Clinical death" end
  316.     crashtext = string.format(info.." pc=%04X sp=%04X", pc, sp)
  317.     gui.text(160-(string.len(crashtext)*4),0, crashtext, 'red');
  318.     crashtext = ""
  319.     if is_invalid then
  320.     crashtext = string.format("Invalid opcode %02X", op)
  321.     elseif pc == 0x39 then
  322.     crashtext = string.format("Stuck in rst 38", op)
  323.     end
  324.     gui.text(160-(string.len(crashtext)*4),8, crashtext, 'red');
  325.     end
  326.     else
  327.     crashi = 0
  328.     end
  329.     -- print(string.format('%04X', memory.getregister('pc')))
  330.     end
  331.     if keys[randomkey] then
  332.      
  333.     gui.text(1,137, "Random bytes"); -- picky, picky
  334.     if gb then
  335.     bang1 = randmemory(0x9800, 0xFEFF)
  336.     elseif gba then
  337.     bang1 = randmemory(0x2000000, 0x0203FFFF)
  338.     end
  339.     bang2 = math.random(0, 0xFF);
  340.     memory.writebyte(bang1, bang2);
  341.      
  342.     --print(string.format("%04X => %02X", bang1, bang2));
  343.     end;
  344.     if keys[plusminuskey] then
  345.     if gb then
  346.     bang1 = randmemory(0x9800, 0xFEFF)
  347.     elseif gba then
  348.     bang1 = randmemory(0x2000000, 0x0203FFFF)
  349.     end
  350.     bang2 = AND(memory.readbyte(bang1) + math.random(-1, 1), 0xFF);
  351.     memory.writebyte(bang1, bang2);
  352.     gui.text(1,137, string.format("%04X +/- 1", bang1)); -- picky, picky
  353.     --print(string.format("%04X => %02X", bang1, bang2));
  354.     end;
  355.      
  356.     -- KABLOOEY
  357.     if keys[powerkey] then
  358.     gui.text(1,137, "Power corruption!", rainbowcolor(timer)); -- picky, picky
  359.     for i = 0, 0xF do
  360.     if gb then
  361.     bang1 = randmemory(0xA000, 0xFEFF)
  362.     elseif gba then
  363.     --if math.random(1) then
  364.     bang1 = randmemory(0x2000000, 0x0203FFFF)
  365.     --else
  366.     -- bang1 = randmemory(0x3000000, 0x0303FFFF)
  367.     --end
  368.     end
  369.     bang2 = math.random(0x00, 0xFF);
  370.     memory.writebyte(bang1, bang2);
  371.     --print(string.format("%04X => %02X", bang1, bang2));
  372.     end;
  373.     end;
  374.      
  375.     -- KABLOOEY
  376.     if keys[highkey] then
  377.     if gb then
  378.     gui.text(1,137, "HRAM corruption!"); -- picky, picky
  379.     bang1 = randmemory(0xFF8C, 0xFFFE)
  380.     bang2 = math.random(0, 0xFF);
  381.     memory.writebyte(bang1, bang2);
  382.     end
  383.     if gba then
  384.     gui.text(1,137, "Power corruption INT!", rainbowcolor(timer)); -- picky, picky
  385.     for i = 0, 0xF do
  386.     bang1 = randmemory(0x3000000, 0x0300FFFF)
  387.     bang2 = math.random(0x00, 0xFF);
  388.     memory.writebyte(bang1, bang2);
  389.     end;
  390.     end
  391.     end;
  392.      
  393.     if keys[vramkey] then
  394.     rand = math.random(0, 16)
  395.     if gb then
  396.     if rand >= 3 then
  397.     gui.text(1,137, "Trashing VRAM");
  398.     bang1 = math.random(0x8000, 0x9FFF)
  399.     bang2 = math.random(0, 0xFF);
  400.     memory.writebyte(bang1, bang2);
  401.     --elseif rand >= 3 then -- I hate you vba
  402.     -- gui.text(1,137, "Trashing palettes");
  403.     -- bang1 = math.random(0, 0xFF);
  404.     -- bang2 = math.random(0, 0xFF);
  405.     -- memory.writebyte(0xFF68, bang1);
  406.     -- memory.writebyte(0xFF69, bang2);
  407.     elseif rand >= 1 then
  408.     gui.text(1,137, "Mixing up tiles");
  409.     bang1 = math.random(0x8000, 0x9700)
  410.     tile = memory.readbyterange(bang1, 0x10)
  411.     bang2 = math.random(0x8000, 0x9700)
  412.     for i,byte in pairs(tile) do
  413.     memory.writebyte(bang2+i, byte)
  414.     end
  415.     memory.writebyte(bang1, bang2);
  416.     else
  417.     gui.text(1,137, "Trashing OAM");
  418.     bang1 = math.random(0xFE00, 0xFE90)
  419.     bang2 = math.random(0, 0xFF);
  420.     memory.writebyte(bang1, bang2);
  421.     end
  422.     rand2 = math.random(0, 10000)
  423.     if rand2 == 0 then
  424.     bang = math.random(0x8000, 0x9700)
  425.     bang = AND(bang, 0xfff0)
  426.     for i,byte in pairs(s) do
  427.     memory.writebyte(bang-1+i, byte)
  428.     end
  429.     gui.text(1,137, "4");
  430.     end
  431.     elseif gba then
  432.     for i = 0, 0x8 do -- larger screen, larger corruption
  433.     if rand >= 3 then
  434.     gui.text(1,137, "Trashing VRAM");
  435.     bang1 = math.random(0x6000000, 0x6017fff)
  436.     bang2 = math.random(0, 0xFF);
  437.     memory.writebyte(bang1, bang2);
  438.     else
  439.     gui.text(1,137, "Trashing palettes");
  440.     bang1 = math.random(0x5000000, 0x5000400)
  441.     bang2 = math.random(0, 0xFF);
  442.     memory.writebyte(bang1, bang2);
  443.     end
  444.     end
  445.     end
  446.     --print(string.format("%04X => %02X", bang1, bang2));
  447.     end;
  448.      
  449.     if keys[freezekey] then
  450.      
  451.     gui.text(1,137, "Freeze"); -- picky, picky
  452.     for i = 0, 0xF do
  453.     if gb then
  454.     bang1 = randmemory(0xC000, 0xDFFF)
  455.     elseif gba then
  456.     bang1 = randmemory(0x2000000, 0x0203FFFF)
  457.     end
  458.     --bang2 = math.random(0x00, 0xFF);
  459.     frozen[bang1] = memory.readbyte(bang1);
  460.     --print(string.format("%04X => %02X", bang1, bang2));
  461.     end;
  462.     end;
  463.     if keys[unfreezekey] or keys[rewindKey] then
  464.     gui.text(1,137, "Unfreeze")
  465.     frozen = {}
  466.     end
  467.      
  468.     if keys[savetileskey] then
  469.     if gb then
  470.     gui.text(1,137, "Saved tiles"); -- picky, picky
  471.     vram = memory.readbyterange(0x8000, 0x1700)
  472.     end
  473.     end;
  474.     if keys[restoretileskey] then
  475.     if gb then
  476.     gui.text(1,137, "Restored tiles")
  477.     for i,v in pairs(vram) do
  478.     memory.writebyte(0x8000-1+i, v);
  479.     end
  480.     end
  481.     end
  482.      
  483.     if keys[rewindon] and not lastkeys[rewindon] then rewind = not rewind end
  484.     if keys[rewindon] then
  485.     if rewind then text = "Rewind ON!" else text = "Rewind OFF!" end
  486.     gui.text(1,137, text)
  487.     end
  488.     if keys[wrammap] and not lastkeys[wrammap] then showwram = not showwram; end
  489.      
  490.     if showwram then
  491.     --gui.text(1,137, "Live WRAM")
  492.     if gb then
  493.     wram = memory.readbyterange(0xC000, 0x2000)
  494.     for k,v in pairs(memory.readbyterange(0xFF00, 0xFF)) do wram[0x2000+k] = v end
  495.     width = 64
  496.     elseif gba then
  497.     wram = memory.readbyterange(0x2000000, 0x3FFFF)
  498.     width = 64*3
  499.     end
  500.     for i,v in pairs(wram) do
  501.     --memory.writebyte(0x8000-1+i, v);
  502.     if prevwram[i] ~= wram[i] then
  503.     color = {0, 0, 255, v}
  504.     elseif frozen[0xC000+i-1] then
  505.     color = {0, 255, 255, v}
  506.     elseif i > 0x2000 then
  507.     color = {0, 255, 0, v}
  508.     else
  509.     color = {255, 0, 0, v}
  510.     end
  511.     gui.pixel((i-1)%width, math.floor((i-1)/width), color)
  512.     end
  513.     prevwram = wram
  514.     xmouse, ymouse, left, right, middle = keys['xmouse'], keys['ymouse'], keys['leftclick'], keys['rightclick'], keys['middleclick']
  515.     if left or right or middle and xmouse <= width then
  516.     offset = 0xC000 + (xmouse%width) + (ymouse*width)
  517.     if left then
  518.     memory.writebyte(offset, AND(memory.readbyte(offset) + 1, 0xFF))
  519.     elseif right then
  520.     memory.writebyte(offset, AND(memory.readbyte(offset) - 1, 0xFF))
  521.     else
  522.     memory.writebyte(offset, 0xff)
  523.     end
  524.     end
  525.     end
  526.     for i,v in pairs(frozen) do
  527.     memory.writebyte(i, v);
  528.     end
  529.     lastkeys = keys
  530.     emu.frameadvance();
  531.     end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement