Partial implementation of sprite updating

This commit is contained in:
Kevin Cathcart 2017-11-18 12:22:06 -05:00
parent d31a7d6791
commit 1528489201
1 changed files with 63 additions and 36 deletions

99
Gui.py
View File

@ -3,9 +3,12 @@ from Utils import is_bundled, local_path, output_path, open_file
from argparse import Namespace
from Rom import Sprite
from glob import glob
import json
import random
import os
import shutil
from urllib.parse import urlparse
from urllib.request import urlopen
from tkinter import Checkbutton, OptionMenu, Toplevel, LabelFrame, PhotoImage, Tk, LEFT, RIGHT, BOTTOM, TOP, StringVar, IntVar, Frame, Label, W, E, X, Y, Entry, Spinbox, Button, filedialog, messagebox
@ -70,9 +73,7 @@ def guiMain(args=None):
spriteEntry = Entry(spriteDialogFrame, textvariable=spriteVar)
def SpriteSelect():
#sprite = filedialog.askopenfilename()
#spriteVar.set(sprite)
SpriteSelector(Toplevel(mainWindow), spriteVar.set)
SpriteSelector(mainWindow, spriteVar.set)
spriteSelectButton = Button(spriteDialogFrame, text='Select Sprite', command=SpriteSelect)
@ -287,58 +288,82 @@ class SpriteSelector(object):
if is_bundled():
self.deploy_icons()
self.parent = parent
self.window = Toplevel(parent)
self.callback = callback
parent.wm_title("TAKE ANY ONE YOU WANT")
parent['padx']=5
parent['pady']=5
self.window.wm_title("TAKE ANY ONE YOU WANT")
self.window['padx'] = 5
self.window['pady'] = 5
self.icon_section('Official Sprites', self.official_sprite_dir+'/*', 'Official Sprites not found. Click "Update Official Sprites" to download them.')
self.icon_section('Unofficial Sprites', self.unofficial_sprite_dir+'/*', 'Put sprites in the Sprites/Unofficial folder to have them appear here.')
frame = Frame(parent)
frame = Frame(self.window)
frame.pack(side=BOTTOM, fill=X, pady=5)
button = Button(frame, text="Browse for file...", command=self.browse_for_sprite)
button.pack(side=RIGHT, padx=(5,0))
button.pack(side=RIGHT, padx=(5, 0))
# todo: Actually implement this. Requires a yet-to-be coded API from VT
button = Button(frame, text="Update Official Sprites")
button.pack(side=RIGHT, padx=(5,0))
button = Button(frame, text="Update Official Sprites", command=self.update_official_sprites)
button.pack(side=RIGHT, padx=(5, 0))
button = Button(frame, text="Use Default Sprite", command=self.use_default_sprite)
button.pack(side=LEFT)
set_icon(parent)
set_icon(self.window)
def icon_section(self, frame_label, path, no_results_label):
frame = LabelFrame(self.parent, text=frame_label, padx=5, pady=5)
frame = LabelFrame(self.window, text=frame_label, padx=5, pady=5)
frame.pack(side=TOP, fill=X)
i=0
i = 0
for file in glob(output_path(path)):
image = get_image_for_sprite(file)
if image is None: continue
button = Button(frame, image=image, command=lambda file=file:self.select_sprite(file))
button.image=image
button.grid(row=i//16, column=i%16)
i+=1
button = Button(frame, image=image, command=lambda file=file: self.select_sprite(file))
button.image = image
button.grid(row=i // 16, column=i % 16)
i += 1
if i==0:
if i == 0:
label = Label(frame, text="Put sprites in the Sprites/Unoffical folder to have them appear here.")
label.pack()
def update_official_sprites(self):
# need to wrap in try catch. We don't want errors getting the json or downloading the files to break us.
sprites_arr = json.loads(temp_sprites_json)
current_sprites = [os.path.basename(file) for file in glob('sprites/official/*')]
official_sprites = [(sprite['file'], os.path.basename(urlparse(sprite['file']).path)) for sprite in sprites_arr]
needed_sprites = [(sprite_url, filename) for (sprite_url, filename) in official_sprites if filename not in current_sprites]
for (sprite_url, filename) in needed_sprites:
target = os.path.join('sprites/official',filename)
with urlopen(sprite_url) as response, open(target, 'wb') as out:
shutil.copyfileobj(response, out)
official_filenames = [filename for (_, filename) in official_sprites]
obsolete_sprites = [sprite for sprite in current_sprites if sprite not in official_filenames]
for sprite in obsolete_sprites:
os.remove(os.path.join('sprites/official', sprite))
self.window.destroy()
SpriteSelector(self.parent, self.callback)
def browse_for_sprite(self):
sprite = filedialog.askopenfilename()
self.callback(sprite)
self.parent.destroy()
self.window.destroy()
def use_default_sprite(self):
self.callback("")
self.parent.destroy()
self.window.destroy()
def select_sprite(self, spritename):
self.callback(spritename)
self.parent.destroy()
self.window.destroy()
def deploy_icons(self):
if not os.path.exists(self.unofficial_sprite_dir):
@ -378,30 +403,32 @@ def get_image_for_sprite(filename):
def drawsprite(spr, pal_as_colors, offset):
for y in range(len(spr)):
for x in range(len(spr[y])):
pal_index=spr[y][x]
pal_index = spr[y][x]
if pal_index:
color=pal_as_colors[pal_index-1]
image.put(color_to_hex(color),to=(x+offset[0],y+offset[1]))
color = pal_as_colors[pal_index - 1]
image.put(color_to_hex(color), to=(x + offset[0], y + offset[1]))
shadow_palette = [(40,40,40)]
shadow_palette = [(40, 40, 40)]
shadow = [
[0,0,0,1,1,1,1,1,1,0,0,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,0,0,1,1,1,1,1,1,0,0,0],
]
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
]
drawsprite(shadow, shadow_palette, (2,17))
drawsprite(shadow, shadow_palette, (2, 17))
palettes = sprite.decode_palette()
body = sprite.decode16(0x4C0)
drawsprite(body, palettes[0], (0,8))
drawsprite(body, palettes[0], (0, 8))
head = sprite.decode16(0x40)
drawsprite(head, palettes[0], (0,0))
drawsprite(head, palettes[0], (0, 0))
return image.zoom(2)
temp_sprites_json = '''[{"name":"Link","file":"http:\/\/spr.beegunslingers.com\/link.1.spr"},{"name":"Four Swords Link","file":"http:\/\/spr.beegunslingers.com\/4slink-armors.1.spr"},{"name":"Boo","file":"http:\/\/spr.beegunslingers.com\/boo.2.spr"},{"name":"Boy","file":"http:\/\/spr.beegunslingers.com\/boy.2.spr"},{"name":"Cactuar","file":"http:\/\/spr.beegunslingers.com\/cactuar.1.spr"},{"name":"Cat","file":"http:\/\/spr.beegunslingers.com\/cat.1.spr"},{"name":"Cat Boo","file":"http:\/\/spr.beegunslingers.com\/catboo.1.spr"},{"name":"Cirno","file":"http:\/\/spr.beegunslingers.com\/cirno.1.spr"},{"name":"Dark Boy","file":"http:\/\/spr.beegunslingers.com\/darkboy.2.spr"},{"name":"Dark Girl","file":"http:\/\/spr.beegunslingers.com\/darkgirl.1.spr"},{"name":"Dark Link","file":"http:\/\/spr.beegunslingers.com\/darklink.1.spr"},{"name":"Dark Maple Queen","file":"http:\/\/spr.beegunslingers.com\/shadowsaku.1.spr"},{"name":"Dark Swatchy","file":"http:\/\/spr.beegunslingers.com\/darkswatchy.1.spr"},{"name":"Dark Zelda","file":"http:\/\/spr.beegunslingers.com\/darkzelda.1.spr"},{"name":"Dark Zora","file":"http:\/\/spr.beegunslingers.com\/darkzora.2.spr"},{"name":"Decidueye","file":"http:\/\/spr.beegunslingers.com\/decidueye.1.spr"},{"name":"Demon Link","file":"http:\/\/spr.beegunslingers.com\/demonlink.1.spr"},{"name":"Frog","file":"http:\/\/spr.beegunslingers.com\/froglink.2.spr"},{"name":"Ganondorf","file":"http:\/\/spr.beegunslingers.com\/ganondorf.1.spr"},{"name":"Garfield","file":"http:\/\/spr.beegunslingers.com\/garfield.1.spr"},{"name":"Girl","file":"http:\/\/spr.beegunslingers.com\/girl.2.spr"},{"name":"Headless Link","file":"http:\/\/spr.beegunslingers.com\/headlesslink.1.spr"},{"name":"Invisible Man","file":"http:\/\/spr.beegunslingers.com\/invisibleman.1.spr"},{"name":"Inkling","file":"http:\/\/spr.beegunslingers.com\/inkling.1.spr"},{"name":"Kirby","file":"http:\/\/spr.beegunslingers.com\/kirby-meta.2.spr"},{"name":"Kore8","file":"http:\/\/spr.beegunslingers.com\/kore8.1.spr"},{"name":"Pony","file":"http:\/\/spr.beegunslingers.com\/littlepony.1.spr"},{"name":"Luigi","file":"http:\/\/spr.beegunslingers.com\/luigi.1.spr"},{"name":"Maiden","file":"http:\/\/spr.beegunslingers.com\/maiden.2.spr"},{"name":"Maple Queen","file":"http:\/\/spr.beegunslingers.com\/maplequeen.1.spr"},{"name":"Mario","file":"http:\/\/spr.beegunslingers.com\/mario-classic.1.spr"},{"name":"Marisa","file":"http:\/\/spr.beegunslingers.com\/marisa.1.spr"},{"name":"Mike Jones","file":"http:\/\/spr.beegunslingers.com\/mikejones.2.spr"},{"name":"Minish Cap Link","file":"http:\/\/spr.beegunslingers.com\/minishcaplink.3.spr"},{"name":"Modern Link","file":"http:\/\/spr.beegunslingers.com\/modernlink.1.spr"},{"name":"Mog","file":"http:\/\/spr.beegunslingers.com\/mog.1.spr"},{"name":"Mouse","file":"http:\/\/spr.beegunslingers.com\/mouse.1.spr"},{"name":"Nature Link","file":"http:\/\/spr.beegunslingers.com\/naturelink.1.spr"},{"name":"Negative Link","file":"http:\/\/spr.beegunslingers.com\/negativelink.1.spr"},{"name":"Neon Link","file":"http:\/\/spr.beegunslingers.com\/neonlink.1.spr"},{"name":"Old Man","file":"http:\/\/spr.beegunslingers.com\/oldman.1.spr"},{"name":"Pink Ribbon Link","file":"http:\/\/spr.beegunslingers.com\/pinkribbonlink.1.spr"},{"name":"Popoi","file":"http:\/\/spr.beegunslingers.com\/popoi.1.spr"},{"name":"Pug","file":"http:\/\/spr.beegunslingers.com\/pug.2.spr"},{"name":"Purple Chest","file":"http:\/\/spr.beegunslingers.com\/purplechest-bottle.2.spr"},{"name":"Roy Koopa","file":"http:\/\/spr.beegunslingers.com\/roykoopa.1.spr"},{"name":"Rumia","file":"http:\/\/spr.beegunslingers.com\/rumia.1.spr"},{"name":"Samus","file":"http:\/\/spr.beegunslingers.com\/samus.4.spr"},{"name":"Soda Can","file":"http:\/\/spr.beegunslingers.com\/sodacan.1.spr"},{"name":"Static Link","file":"http:\/\/spr.beegunslingers.com\/staticlink.1.spr"},{"name":"Santa Link","file":"http:\/\/spr.beegunslingers.com\/santalink.1.spr"},{"name":"Super Bunny","file":"http:\/\/spr.beegunslingers.com\/superbunny.1.spr"},{"name":"Swatchy","file":"http:\/\/spr.beegunslingers.com\/swatchy.1.spr"},{"name":"Tingle","file":"http:\/\/spr.beegunslingers.com\/tingle.1.spr"},{"name":"Toad","file":"http:\/\/spr.beegunslingers.com\/toad.1.spr"},{"name":"Valeera","file":"http:\/\/spr.beegunslingers.com\/valeera.1.spr"},{"name":"Vitreous","file":"http:\/\/spr.beegunslingers.com\/vitreous.1.spr"},{"name":"Vivi","file":"http:\/\/spr.beegunslingers.com\/vivi.1.spr"},{"name":"Will","file":"http:\/\/spr.beegunslingers.com\/will.1.spr"},{"name":"Wizzrobe","file":"http:\/\/spr.beegunslingers.com\/wizzrobe.4.spr"},{"name":"Yunica","file":"http:\/\/spr.beegunslingers.com\/yunica.1.spr"},{"name":"Zelda","file":"http:\/\/spr.beegunslingers.com\/zelda.2.spr"},{"name":"Zero Suit Samus","file":"http:\/\/spr.beegunslingers.com\/zerosuitsamus.1.spr"},{"name":"Zora","file":"http:\/\/spr.beegunslingers.com\/zora.1.spr"}]'''
if __name__ == '__main__':
guiMain()