Merge branch 'gfx-fixes-again' into master.

Various whitespace and formatting changes.
This commit is contained in:
Bryan Bishop
2013-06-25 23:48:44 -05:00
3 changed files with 88 additions and 87 deletions

2
.gitignore vendored
View File

@ -37,3 +37,5 @@ pokecrystal.rtc
# some users are dumping png.py into extras/ # some users are dumping png.py into extras/
extras/png.py extras/png.py
*$py.class

View File

@ -27,23 +27,23 @@ def mkdir_p(path):
else: raise else: raise
def hex_dump(input, debug = True): def hex_dump(input, debug=True):
""" """
Display hex dump in rows of 16 bytes. Display hex dump in rows of 16 bytes.
""" """
dump = '' dump = ''
output = '' output = ''
stream = '' stream = ''
address = 0x00 address = 0x00
margin = 2 + len(hex(len(input))[2:]) margin = 2 + len(hex(len(input))[2:])
# dump # dump
for byte in input: for byte in input:
cool = hex(byte)[2:].zfill(2) cool = hex(byte)[2:].zfill(2)
dump += cool + ' ' dump += cool + ' '
if debug: stream += cool if debug: stream += cool
# convenient for testing quick edits in bgb # convenient for testing quick edits in bgb
if debug: output += stream + '\n' if debug: output += stream + '\n'
@ -52,17 +52,16 @@ def hex_dump(input, debug = True):
chars_per_byte = 3 # '__ ' chars_per_byte = 3 # '__ '
chars_per_line = bytes_per_line * chars_per_byte chars_per_line = bytes_per_line * chars_per_byte
num_lines = int(ceil(float(len(dump)) / float(chars_per_line))) num_lines = int(ceil(float(len(dump)) / float(chars_per_line)))
# top # top
# margin # margin
for char in range(margin): for char in range(margin):
output += ' ' output += ' '
#
for byte in range(bytes_per_line): for byte in range(bytes_per_line):
output += hex(byte)[2:].zfill(2) + ' ' output += hex(byte)[2:].zfill(2) + ' '
output = output[:-1] # last space output = output[:-1] # last space
# print hex # print hex
for line in range(num_lines): for line in range(num_lines):
# address # address
@ -72,7 +71,7 @@ def hex_dump(input, debug = True):
end = chars_per_line + start - 1 # ignore last space end = chars_per_line + start - 1 # ignore last space
output += dump[start:end] output += dump[start:end]
address += 0x10 address += 0x10
return output return output
@ -83,7 +82,7 @@ def get_tiles(image):
tiles = [] tiles = []
tile = [] tile = []
bytes_per_tile = 16 bytes_per_tile = 16
cur_byte = 0 cur_byte = 0
for byte in image: for byte in image:
# build tile # build tile
@ -113,7 +112,7 @@ def transpose(tiles):
""" """
Transpose a tile arrangement along line y=x. Transpose a tile arrangement along line y=x.
""" """
# horizontal <-> vertical # horizontal <-> vertical
# 00 01 02 03 04 05 00 06 0c 12 18 1e # 00 01 02 03 04 05 00 06 0c 12 18 1e
# 06 07 08 09 0a 0b 01 07 0d 13 19 1f # 06 07 08 09 0a 0b 01 07 0d 13 19 1f
@ -122,7 +121,7 @@ def transpose(tiles):
# 18 19 1a 1b 1c 1d 04 0a 10 16 1c 22 # 18 19 1a 1b 1c 1d 04 0a 10 16 1c 22
# 1e 1f 20 21 22 23 05 0b 11 17 1d 23 # 1e 1f 20 21 22 23 05 0b 11 17 1d 23
# etc # etc
flipped = [] flipped = []
t = 0 # which tile we're on t = 0 # which tile we're on
w = int(sqrt(len(tiles))) # assume square image w = int(sqrt(len(tiles))) # assume square image
@ -196,18 +195,18 @@ lowmax = 1 << 5 # standard 5-bit param
class Compressed: class Compressed:
""" """
Compress 2bpp data. Compress 2bpp data.
""" """
def __init__(self, image = None, mode = 'horiz', size = None): def __init__(self, image=None, mode='horiz', size=None):
assert image, 'need something to compress!' assert image, 'need something to compress!'
image = list(image) image = list(image)
self.image = image self.image = image
self.pic = [] self.pic = []
self.animtiles = [] self.animtiles = []
# only transpose pic (animtiles were never transposed in decompression) # only transpose pic (animtiles were never transposed in decompression)
if size != None: if size != None:
for byte in range((size*size)*16): for byte in range((size*size)*16):
@ -221,7 +220,7 @@ class Compressed:
self.tiles = get_tiles(self.pic) self.tiles = get_tiles(self.pic)
self.tiles = transpose(self.tiles) self.tiles = transpose(self.tiles)
self.pic = connect(self.tiles) self.pic = connect(self.tiles)
self.image = self.pic + self.animtiles self.image = self.pic + self.animtiles
self.end = len(self.image) self.end = len(self.image)
@ -326,15 +325,15 @@ class Compressed:
def scanRepeats(self): def scanRepeats(self):
""" """
Works, but doesn't do flipped/reversed streams yet. Works, but doesn't do flipped/reversed streams yet.
This takes up most of the compress time and only saves a few bytes This takes up most of the compress time and only saves a few bytes
it might be more feasible to exclude it entirely. it might be more feasible to exclude it entirely.
""" """
self.repeats = [] self.repeats = []
self.flips = [] self.flips = []
self.reverses = [] self.reverses = []
# make a 5-letter word list of the sequence # make a 5-letter word list of the sequence
letters = 5 # how many bytes it costs to use a repeat over a literal letters = 5 # how many bytes it costs to use a repeat over a literal
# any shorter and it's not worth the trouble # any shorter and it's not worth the trouble
@ -345,7 +344,7 @@ class Compressed:
for j in range(letters): for j in range(letters):
word.append( ord(self.image[i+j]) ) word.append( ord(self.image[i+j]) )
words.append((word, i)) words.append((word, i))
zeros = [] zeros = []
for zero in range(letters): for zero in range(letters):
zeros.append( 0 ) zeros.append( 0 )
@ -405,13 +404,13 @@ class Compressed:
else: # no more overlaps else: # no more overlaps
buffer.append(match) buffer.append(match)
else: # last match, so there's nothing to check else: # last match, so there's nothing to check
buffer.append(match) buffer.append(match)
matches = buffer matches = buffer
# remove alternating sequences # remove alternating sequences
buffer = [] buffer = []
for match in matches: for match in matches:
for i in range(6 if letters > 6 else letters): for i in range(6 if letters > 6 else letters):
if match[0][i] != match[0][i&1]: if match[0][i] != match[0][i&1]:
buffer.append(match) buffer.append(match)
break break
@ -422,7 +421,7 @@ class Compressed:
def doRepeats(self): def doRepeats(self):
"""doesn't output the right values yet""" """doesn't output the right values yet"""
unusedrepeats = [] unusedrepeats = []
for repeat in self.repeats: for repeat in self.repeats:
if self.address >= repeat[2]: if self.address >= repeat[2]:
@ -598,7 +597,7 @@ class Decompressed:
data can be fed in from rom if [start] is specified data can be fed in from rom if [start] is specified
""" """
def __init__(self, lz = None, mode = None, size = None, start = 0): def __init__(self, lz=None, mode=None, size=None, start=0):
# todo: play nice with Compressed # todo: play nice with Compressed
assert lz, 'need something to compress!' assert lz, 'need something to compress!'
@ -734,7 +733,7 @@ class Decompressed:
def doFlip(self): def doFlip(self):
""" """
Repeat flipped bytes from 2bpp output. Repeat flipped bytes from 2bpp output.
eg 11100100 -> 00100111 eg 11100100 -> 00100111
quat 3 2 1 0 -> 0 2 1 3 quat 3 2 1 0 -> 0 2 1 3
""" """
@ -831,7 +830,7 @@ unowns = 0x124000
num_unowns = 26 num_unowns = 26
unown_dex = 201 unown_dex = 201
def decompress_monster_by_id(id = 0, type = front): def decompress_monster_by_id(id=0, type=front):
# no unowns here # no unowns here
if id + 1 == unown_dex: return None if id + 1 == unown_dex: return None
# get size # get size
@ -847,7 +846,7 @@ def decompress_monster_by_id(id = 0, type = front):
monster = Decompressed(rom, 'vert', size, address) monster = Decompressed(rom, 'vert', size, address)
return monster return monster
def decompress_monsters(type = front): def decompress_monsters(type=front):
for id in range(num_monsters): for id in range(num_monsters):
# decompress # decompress
monster = decompress_monster_by_id(id, type) monster = decompress_monster_by_id(id, type)
@ -865,7 +864,7 @@ def decompress_monsters(type = front):
to_file(folder+filename, monster.pic) to_file(folder+filename, monster.pic)
def decompress_unown_by_id(letter, type = front): def decompress_unown_by_id(letter, type=front):
# get size # get size
if type == front: if type == front:
size = sizes[unown_dex-1] size = sizes[unown_dex-1]
@ -879,7 +878,7 @@ def decompress_unown_by_id(letter, type = front):
unown = Decompressed(rom, 'vert', size, address) unown = Decompressed(rom, 'vert', size, address)
return unown return unown
def decompress_unowns(type = front): def decompress_unowns(type=front):
for letter in range(num_unowns): for letter in range(num_unowns):
# decompress # decompress
unown = decompress_unown_by_id(letter, type) unown = decompress_unown_by_id(letter, type)
@ -993,7 +992,7 @@ def decompress_misc():
gfx = Decompressed( rom, mode, None, address ) gfx = Decompressed( rom, mode, None, address )
to_file(filename, gfx.output) to_file(filename, gfx.output)
def decompress_all(debug = False): def decompress_all(debug=False):
""" """
Decompress all known compressed data in baserom. Decompress all known compressed data in baserom.
""" """
@ -1028,7 +1027,7 @@ def decompress_all(debug = False):
return return
def decompress_from_address(address, mode='horiz', filename = 'de.2bpp', size = None): def decompress_from_address(address, mode='horiz', filename='de.2bpp', size=None):
""" """
Write decompressed data from an address to a 2bpp file. Write decompressed data from an address to a 2bpp file.
""" """
@ -1036,7 +1035,7 @@ def decompress_from_address(address, mode='horiz', filename = 'de.2bpp', size =
to_file(filename, image.pic) to_file(filename, image.pic)
def decompress_file(filein, fileout, mode = 'horiz', size = None): def decompress_file(filein, fileout, mode='horiz', size=None):
f = open(filein, 'rb') f = open(filein, 'rb')
image = f.read() image = f.read()
f.close() f.close()
@ -1046,7 +1045,7 @@ def decompress_file(filein, fileout, mode = 'horiz', size = None):
to_file(fileout, de.pic) to_file(fileout, de.pic)
def compress_file(filein, fileout, mode = 'horiz'): def compress_file(filein, fileout, mode='horiz'):
f = open(filein, 'rb') f = open(filein, 'rb')
image = f.read() image = f.read()
f.close() f.close()
@ -1099,7 +1098,7 @@ def hex_to_rgb(word):
blue = word & 0b11111 blue = word & 0b11111
return (red, green, blue) return (red, green, blue)
def grab_palettes(address, length = 0x80): def grab_palettes(address, length=0x80):
output = '' output = ''
for word in range(length/2): for word in range(length/2):
color = ord(rom[address+1])*0x100 + ord(rom[address]) color = ord(rom[address+1])*0x100 + ord(rom[address])
@ -1228,7 +1227,7 @@ def dmg2rgb(word):
blue = word & 0b11111 blue = word & 0b11111
alpha = 255 alpha = 255
return ((red<<3)+0b100, (green<<3)+0b100, (blue<<3)+0b100, alpha) return ((red<<3)+0b100, (green<<3)+0b100, (blue<<3)+0b100, alpha)
def rgb_to_dmg(color): def rgb_to_dmg(color):
word = (color['r'] / 8) word = (color['r'] / 8)
word += (color['g'] / 8) << 5 word += (color['g'] / 8) << 5
@ -1556,8 +1555,8 @@ def lz_to_png_by_file(filename):
def dump_tileset_pngs(): def dump_tileset_pngs():
""" """
Convert .lz format tilesets into .png format tilesets. Convert .lz format tilesets into .png format tilesets.
Also, leaves a bunch of wonderful .2bpp files everywhere for your amusement. Also, leaves a bunch of wonderful .2bpp files everywhere for your amusement.
""" """
for tileset_id in range(37): for tileset_id in range(37):
@ -1581,7 +1580,7 @@ def decompress_frontpic_anim(lz_file):
def expand_pic_palettes(): def expand_pic_palettes():
""" """
Add white and black to palette files with fewer than 4 colors. Add white and black to palette files with fewer than 4 colors.
Pokemon Crystal only defines two colors for a pic palette to Pokemon Crystal only defines two colors for a pic palette to
save space, filling in black/white at runtime. save space, filling in black/white at runtime.
Instead of managing palette files of varying length, black Instead of managing palette files of varying length, black
@ -1601,7 +1600,7 @@ def expand_pic_palettes():
if __name__ == "__main__": if __name__ == "__main__":
debug = False debug = False
argv = [None] * 5 argv = [None] * 5
for i, arg in enumerate(sys.argv): for i, arg in enumerate(sys.argv):
argv[i] = arg argv[i] = arg
@ -1667,7 +1666,7 @@ if __name__ == "__main__":
filein = argv[2] filein = argv[2]
fileout = argv[3] fileout = argv[3]
compress_file(filein, fileout) compress_file(filein, fileout)
elif argv[1] == '2bpp-to-png': elif argv[1] == '2bpp-to-png':
to_png(argv[2]) to_png(argv[2])

View File

@ -119,9 +119,9 @@ if not os.path.exists(rom_path):
def _check_java_library_path(): def _check_java_library_path():
""" """
Returns the value of java.library.path. Returns the value of java.library.path.
The vba-clojure library must be compiled The vba-clojure library must be compiled
and linked from this location. and linked from this location.
""" """
return System.getProperty("java.library.path") return System.getProperty("java.library.path")
@ -159,8 +159,8 @@ a, b, r, l, u, d, select, start, restart = "a", "b", "r", "l", "u", "d", "select
def button_combiner(buttons): def button_combiner(buttons):
""" """
Combines multiple button presses into an integer. Combines multiple button presses into an integer.
This is used when sending a keypress to the emulator. This is used when sending a keypress to the emulator.
""" """
result = 0 result = 0
@ -196,8 +196,8 @@ def button_combiner(buttons):
def load_rom(path=None): def load_rom(path=None):
""" """
Starts the emulator with a certain ROM. Starts the emulator with a certain ROM.
Defaults to rom_path if no parameters are given. Defaults to rom_path if no parameters are given.
""" """
if path == None: if path == None:
@ -215,8 +215,8 @@ def load_rom(path=None):
def shutdown(): def shutdown():
""" """
Stops the emulator. Closes the window. Stops the emulator. Closes the window.
The "opposite" of this is the load_rom function. The "opposite" of this is the load_rom function.
""" """
Gb.shutdown() Gb.shutdown()
@ -251,8 +251,8 @@ def translate_chars(charz):
def _create_byte_buffer(data): def _create_byte_buffer(data):
""" """
Converts data into a ByteBuffer. Converts data into a ByteBuffer.
This is useful for interfacing with the Gb class. This is useful for interfacing with the Gb class.
""" """
buf = ByteBuffer.allocateDirect(len(data)) buf = ByteBuffer.allocateDirect(len(data))
@ -266,11 +266,11 @@ def _create_byte_buffer(data):
def set_state(state, do_step=False): def set_state(state, do_step=False):
""" """
Injects the given state into the emulator. Injects the given state into the emulator.
Use do_step if you want to call step(), which also allows Use do_step if you want to call step(), which also allows
SDL to render the latest frame. Note that the default is to SDL to render the latest frame. Note that the default is to
not step, and that the screen (if it is enabled) will appear not step, and that the screen (if it is enabled) will appear
as if it still has the last state loaded. This is normal. as if it still has the last state loaded. This is normal.
""" """
Gb.loadState(_create_byte_buffer(state)) Gb.loadState(_create_byte_buffer(state))
@ -289,8 +289,8 @@ def get_state():
def save_state(name, state=None, override=False): def save_state(name, state=None, override=False):
""" """
Saves the given state to save_state_path. Saves the given state to save_state_path.
The file format must be ".sav" The file format must be ".sav"
(and this will be appended to your string if necessary). (and this will be appended to your string if necessary).
""" """
@ -313,8 +313,8 @@ def save_state(name, state=None, override=False):
def load_state(name): def load_state(name):
""" """
Reads a state from file based on name. Reads a state from file based on name.
Looks in save_state_path for a file Looks in save_state_path for a file
with this name (".sav" is optional). with this name (".sav" is optional).
""" """
@ -340,8 +340,8 @@ def generate_root():
def get_root(): def get_root():
""" """
Loads the root state. Loads the root state.
(Or restarts the emulator and creates a new root state.) (Or restarts the emulator and creates a new root state.)
""" """
try: try:
@ -397,16 +397,16 @@ def get_memory():
def set_memory(memory): def set_memory(memory):
""" """
Sets memory in the emulator. Sets memory in the emulator.
Use get_memory() to retrieve the current state. Use get_memory() to retrieve the current state.
""" """
Gb.writeMemory(memory) Gb.writeMemory(memory)
def get_pixels(): def get_pixels():
""" """
Returns a list of pixels on the screen display. Returns a list of pixels on the screen display.
Broken, probably. Use screenshot() instead. Broken, probably. Use screenshot() instead.
""" """
sys.stderr.write("ERROR: seems to be broken on VBA's end? Good luck. Use" sys.stderr.write("ERROR: seems to be broken on VBA's end? Good luck. Use"
@ -418,9 +418,9 @@ def get_pixels():
def screenshot(filename, literal=False): def screenshot(filename, literal=False):
""" """
Saves a PNG screenshot to the file at filename. Saves a PNG screenshot to the file at filename.
Use literal if you want to store it in the current directory. Use literal if you want to store it in the current directory.
Default is to save it to screenshots/ under the project. Default is to save it to screenshots/ under the project.
""" """
screenshots_path = os.path.join(project_path, "screenshots/") screenshots_path = os.path.join(project_path, "screenshots/")
@ -453,17 +453,17 @@ def get_memory_range(start_address, byte_count):
def set_memory_at(address, value): def set_memory_at(address, value):
""" """
Sets a byte at a certain address in memory. Sets a byte at a certain address in memory.
This directly sets the memory instead of copying This directly sets the memory instead of copying
the memory from the emulator. the memory from the emulator.
""" """
Gb.setMemoryAt(address, value) Gb.setMemoryAt(address, value)
def press(buttons, holdsteps=1, aftersteps=1): def press(buttons, holdsteps=1, aftersteps=1):
""" """
Press a button. Press a button.
Use steplimit to say for how many steps you want to press Use steplimit to say for how many steps you want to press
the button (try leaving it at the default, 1). the button (try leaving it at the default, 1).
""" """
@ -483,8 +483,8 @@ def press(buttons, holdsteps=1, aftersteps=1):
def get_buttons(): def get_buttons():
""" """
Returns the currentButtons[0] value Returns the currentButtons[0] value
(an integer with bits set for which (an integer with bits set for which
buttons are currently pressed). buttons are currently pressed).
""" """
@ -773,11 +773,11 @@ class crystal:
@staticmethod @staticmethod
def walk_through_walls(): def walk_through_walls():
""" """
Lets the player walk all over the map. Lets the player walk all over the map.
These values are probably reset by some of the map/collision These values are probably reset by some of the map/collision
functions when you move on to a new location, so this needs functions when you move on to a new location, so this needs
to be executed each step/tick if continuous walk-through-walls to be executed each step/tick if continuous walk-through-walls
is desired. is desired.
""" """
set_memory_at(0xC2FA, 0) set_memory_at(0xC2FA, 0)
@ -793,7 +793,7 @@ class crystal:
def nstep(steplimit=500): def nstep(steplimit=500):
""" """
Steps the CPU forward and calls some functions in between each step. Steps the CPU forward and calls some functions in between each step.
(For example, to manipulate memory.) This is pretty slow. (For example, to manipulate memory.) This is pretty slow.
""" """
for step_counter in range(0, steplimit): for step_counter in range(0, steplimit):
@ -848,9 +848,9 @@ class crystal:
@staticmethod @staticmethod
def menu_select(id=1): def menu_select(id=1):
""" """
Sets the cursor to the given pokemon in the player's party. Sets the cursor to the given pokemon in the player's party.
This is under Start -> PKMN. This is useful for selecting a This is under Start -> PKMN. This is useful for selecting a
certain pokemon with fly or another skill. certain pokemon with fly or another skill.
This probably works on other menus. This probably works on other menus.
@ -936,8 +936,8 @@ class crystal:
@staticmethod @staticmethod
def get_text(): def get_text():
""" """
Returns alphanumeric text on the screen. Returns alphanumeric text on the screen.
Other characters will not be shown. Other characters will not be shown.
""" """
output = "" output = ""