Created
June 3, 2015 18:35
-
-
Save spiiin/a5ec2c7c9e5b6ba59039 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--загружаем библиотеку gd | |
require "gd" | |
--начальный адрес для коррапта (сразу от заголовка образа ROM) | |
START_ADDR = 0x10 | |
--конечный адрес для коррапта (зависит от маппера, на котором сделан картридж, можно просто выставить размер файла) | |
END_ADDR = 0x20010 | |
CUR_ADDR = START_ADDR | |
--конечный номер кадра, после которого нужно сделать скриншот (когда игровой экран уже отображается для игрока, номер замерен для созданного сохранения) | |
FRAME_FOR_SCREEN = 7035 | |
--тестовое значение, которым будет записано вместо байта игры | |
WRITE_VALUE = 0x33 | |
--шаг, с которым будет производиться коррапт, для экономии времени поиска | |
--(изменять каждый байт на экране не нужно, на экране может отображаться большое количество макроблоков, достаточно обнаружить хотя бы один из них). | |
STEP = 8 | |
--таблица для сохранения хешей всех уникальных скриншотов | |
shas = {} | |
--запомнить значение, которое будет испорчено корраптом, чтобы потом его восстановить | |
lastValue = rom.readbyte(START_ADDR) | |
--загрузить предварительно заготовленное сохранение из ПЕРВОГО слота (нумерация слотов в эмуляторе начинается с 0, а в LUA - с 1). | |
s = savestate.create(2) | |
savestate.load(s) | |
while (true) do | |
--если экран загрузился и уже отображается | |
if (emu.framecount() > FRAME_FOR_SCREEN) then | |
--сохранить скриншот в памяти | |
local gdStr = gui.gdscreenshot(); | |
--подсчитать его хеш | |
local hash = emu.calchash(gdStr, string.len(gdStr)); | |
--если такого скриншота ещё не было | |
if (not shas[hash]) then | |
print("Found new screen "..tostring(hash)); | |
local fname = string.format("%05X", CUR_ADDR)..".png"; | |
local gdImg = gd.createFromGdStr(gdStr); | |
--сохранить скриншот на диск с указанием в имени адреса изменённого байта | |
gdImg:png(fname) | |
shas[hash] = true; | |
end; | |
--восстановить значение предыдущего байта | |
rom.writebyte(CUR_ADDR, lastValue); | |
CUR_ADDR = CUR_ADDR + STEP; | |
--коррапт следующего байта | |
lastValue = rom.readbyte(CUR_ADDR); | |
rom.writebyte(CUR_ADDR, WRITE_VALUE); | |
--снова загрузка сохранения, чтобы дать возможность игре загрузить из нового образа данные в память | |
s = savestate.create(2) | |
--отображение прогресса | |
savestate.load(s) | |
gui.text(20,20, string.format("%05X", CUR_ADDR)); | |
--когда все адреса будут обработаны, остановить эмулятор | |
if (CUR_ADDR > END_ADDR) then | |
emu.pause(); | |
end | |
end; | |
--проматываем эмуляцию до следующего кадра | |
emu.frameadvance(); | |
end; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import Image | |
def cutBlock(pp): | |
im = Image.open(pp) | |
X = 96 #загрузить скриншот в любой графический редактор, чтобы посмотреть координаты начала блока | |
Y = 96 | |
imCut = im.crop((X,Y,X+32,Y+32)) #вырезать из скриншота блок по заданным координатам | |
imCut.save("_" + pp) | |
for x in xrange(256): | |
cutBlock(r"%03d.png"%x) | |
BLOCK_COUNT = 102 | |
MAX_BLOCK_COUNT = 256 | |
imBig = Image.new("RGB", (32*MAX_BLOCK_COUNT,32)) | |
for x in xrange(BLOCK_COUNT): | |
im = Image.open("_%03d.png"%x) | |
imBig.paste(im, (32*x,0,32*x+32,32)) | |
imBig64 = imBig.resize((MAX_BLOCK_COUNT*64,64)) #увеличение размера макроблока до 64x64, требование для использования с редактором CadEditor | |
imBig64.save("outStrip.png") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CadEditor; | |
using System; | |
using System.Collections.Generic; | |
using System.Drawing; | |
public class Data | |
{ | |
public OffsetRec getScreensOffset() { return new OffsetRec(0x10625 - 16 * 96, 1, 16*96); } | |
public int getScreenWidth() { return 16; } | |
public int getScreenHeight() { return 96; } | |
public int getBigBlocksCount() { return 256; } | |
public string getBlocksFilename() { return "jackal_1.png"; } | |
public GetBigTileNoFromScreenFunc getBigTileNoFromScreenFunc() { return getBigTileNoFromScreen; } | |
public SetBigTileToScreenFunc setBigTileToScreenFunc() { return setBigTileToScreen; } | |
public bool isBigBlockEditorEnabled() { return false; } | |
public bool isBlockEditorEnabled() { return false; } | |
public bool isEnemyEditorEnabled() { return false; } | |
public int getBigTileNoFromScreen(int[] screenData, int index) | |
{ | |
int w = getScreenWidth(); | |
int noY = index / w; | |
noY = (noY/8)*8 + 7 - (noY%8); | |
int noX = index % w; | |
return screenData[noY*w + noX]; | |
} | |
public void setBigTileToScreen(int[] screenData, int index, int value) | |
{ | |
int w = getScreenWidth(); | |
int noY = index / w; | |
noY = (noY/8)*8 + 7 - (noY%8); | |
int noX = index % w; | |
screenData[noY*w + noX] = value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment