Update to latest template.

This commit is contained in:
Steven Smith 2015-01-22 22:13:12 -08:00
parent 61cc6f21f6
commit 5cea1abb50
13 changed files with 10 additions and 458 deletions

View File

@ -34,7 +34,7 @@ SOURCES := source
DATA := data
INCLUDES := include
ICON := resources/icon48.png
ICON := resources/icon.png
#---------------------------------------------------------------------------------
# options for code generation
@ -63,8 +63,7 @@ LIBS := -lctru -lm
LIBDIRS := $(CTRULIB) ./lib
MAKEROM = $(TOPDIR)/tools/makerom
BANNER_TOOL = $(TOPDIR)/tools/banner
CREATE_BANNER = python create.py
BANNERTOOL = $(TOPDIR)/tools/bannertool
#---------------------------------------------------------------------------------
@ -148,22 +147,20 @@ $(OUTPUT_D) :
$(OUTPUT).3dsx : $(OUTPUT).elf
$(OUTPUT).elf : $(OFILES)
banner.bnr: $(TOPDIR)/resources/icon24.png $(TOPDIR)/resources/icon48.png $(TOPDIR)/resources/banner.png
cd $(BANNER_TOOL); $(CREATE_BANNER) "$(APP_TITLE)" "$(APP_TITLE)" "$(APP_AUTHOR)" $(TOPDIR)/resources/icon24.png $(TOPDIR)/resources/icon48.png $(TOPDIR)/resources/banner.png $(TOPDIR)/$(BUILD)/icon.icn $(TOPDIR)/$(BUILD)/banner.bnr
@echo "built ... banner files"
icon.icn: banner.bnr
banner.bnr: $(TOPDIR)/resources/banner.png $(TOPDIR)/resources/audio.bcwav
$(BANNERTOOL) $(TOPDIR)/resources/banner.png $(TOPDIR)/resources/audio.bcwav $(TOPDIR)/$(BUILD)/banner.bnr
@echo "built ... banner"
stripped.elf: $(OUTPUT).elf
@cp $(OUTPUT).elf stripped.elf
@$(PREFIX)strip stripped.elf
$(OUTPUT).cia: stripped.elf $(TOPDIR)/resources/cia.rsf banner.bnr icon.icn
$(MAKEROM) -f cia -o $(OUTPUT).cia -rsf $(TOPDIR)/resources/cia.rsf -target t -exefslogo -elf stripped.elf -icon icon.icn -banner banner.bnr
$(OUTPUT).cia: stripped.elf $(TOPDIR)/resources/cia.rsf banner.bnr $(OUTPUT).smdh
$(MAKEROM) -f cia -o $(OUTPUT).cia -rsf $(TOPDIR)/resources/cia.rsf -target t -exefslogo -elf stripped.elf -icon $(OUTPUT).smdh -banner banner.bnr
@echo "built ... $(notdir $@)"
$(OUTPUT).3ds: stripped.elf $(TOPDIR)/resources/3ds.rsf banner.bnr icon.icn
$(MAKEROM) -f cci -o $(OUTPUT).3ds -rsf $(TOPDIR)/resources/3ds.rsf -target d -exefslogo -elf stripped.elf -icon icon.icn -banner banner.bnr
$(OUTPUT).3ds: stripped.elf $(TOPDIR)/resources/3ds.rsf banner.bnr $(OUTPUT).smdh
$(MAKEROM) -f cci -o $(OUTPUT).3ds -rsf $(TOPDIR)/resources/3ds.rsf -target d -exefslogo -elf stripped.elf -icon $(OUTPUT).smdh -banner banner.bnr
@echo "built ... $(notdir $@)"
#---------------------------------------------------------------------------------

View File

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

View File

@ -1 +0,0 @@
__pycache__

View File

@ -1,26 +0,0 @@
Copyright (c) 2013, Snailface
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the darm developer(s) nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,255 +0,0 @@
# used http://code.google.com/p/u-lzss/source/browse/trunk/js/lib/ulzss.js as
# a guide
from sys import stderr
from collections import defaultdict
from operator import itemgetter
from struct import pack, unpack
class SlidingWindow:
# The size of the sliding window
size = 4096
# The minimum displacement.
disp_min = 2
# The hard minimum — a disp less than this can't be represented in the
# compressed stream.
disp_start = 1
# The minimum length for a successful match in the window
match_min = 1
# The maximum length of a successful match, inclusive.
match_max = None
def __init__(self, buf):
self.data = buf
self.hash = defaultdict(list)
self.full = False
self.start = 0
self.stop = 0
#self.index = self.disp_min - 1
self.index = 0
assert self.match_max is not None
def next(self):
if self.index < self.disp_start - 1:
self.index += 1
return
if self.full:
olditem = self.data[self.start]
assert self.hash[olditem][0] == self.start
self.hash[olditem].pop(0)
item = self.data[self.stop]
self.hash[item].append(self.stop)
self.stop += 1
self.index += 1
if self.full:
self.start += 1
else:
if self.size <= self.stop:
self.full = True
def advance(self, n=1):
"""Advance the window by n bytes"""
for _ in range(n):
self.next()
def search(self):
match_max = self.match_max
match_min = self.match_min
counts = []
indices = self.hash[self.data[self.index]]
for i in indices:
matchlen = self.match(i, self.index)
if matchlen >= match_min:
disp = self.index - i
#assert self.index - disp >= 0
#assert self.disp_min <= disp < self.size + self.disp_min
if self.disp_min <= disp:
counts.append((matchlen, -disp))
if matchlen >= match_max:
#assert matchlen == match_max
return counts[-1]
if counts:
match = max(counts, key=itemgetter(0))
return match
return None
def match(self, start, bufstart):
size = self.index - start
if size == 0:
return 0
matchlen = 0
it = range(min(len(self.data) - bufstart, self.match_max))
for i in it:
if self.data[start + (i % size)] == self.data[bufstart + i]:
matchlen += 1
else:
break
return matchlen
class NLZ10Window(SlidingWindow):
size = 4096
match_min = 3
match_max = 3 + 0xf
class NLZ11Window(SlidingWindow):
size = 4096
match_min = 3
match_max = 0x111 + 0xFFFF
class NOverlayWindow(NLZ10Window):
disp_min = 3
def _compress(input, windowclass=NLZ10Window):
"""Generates a stream of tokens. Either a byte (int) or a tuple of (count,
displacement)."""
window = windowclass(input)
i = 0
while True:
if len(input) <= i:
break
match = window.search()
if match:
yield match
#if match[1] == -283:
# raise Exception(match, i)
window.advance(match[0])
i += match[0]
else:
yield input[i]
window.next()
i += 1
def packflags(flags):
n = 0
for i in range(8):
n <<= 1
try:
if flags[i]:
n |= 1
except IndexError:
pass
return n
def chunkit(it, n):
buf = []
for x in it:
buf.append(x)
if n <= len(buf):
yield buf
buf = []
if buf:
yield buf
def compress(input, out):
# header
out.write(pack("<L", (len(input) << 8) + 0x10))
# body
length = 0
for tokens in chunkit(_compress(input), 8):
flags = [type(t) == tuple for t in tokens]
out.write(pack(">B", packflags(flags)))
for t in tokens:
if type(t) == tuple:
count, disp = t
count -= 3
disp = (-disp) - 1
assert 0 <= disp < 4096
sh = (count << 12) | disp
out.write(pack(">H", sh))
else:
out.write(pack(">B", t))
length += 1
length += sum(2 if f else 1 for f in flags)
# padding
padding = 4 - (length % 4 or 4)
if padding:
out.write(b'\xff' * padding)
def compress_nlz11(input, out):
# header
out.write(pack("<L", (len(input) << 8) + 0x11))
# body
length = 0
for tokens in chunkit(_compress(input, windowclass=NLZ11Window), 8):
flags = [type(t) == tuple for t in tokens]
out.write(pack(">B", packflags(flags)))
length += 1
for t in tokens:
if type(t) == tuple:
count, disp = t
disp = (-disp) - 1
#if disp == 282:
# raise Exception
assert 0 <= disp <= 0xFFF
if count <= 1 + 0xF:
count -= 1
assert 2 <= count <= 0xF
sh = (count << 12) | disp
out.write(pack(">H", sh))
length += 2
elif count <= 0x11 + 0xFF:
count -= 0x11
assert 0 <= count <= 0xFF
b = count >> 4
sh = ((count & 0xF) << 12) | disp
out.write(pack(">BH", b, sh))
length += 3
elif count <= 0x111 + 0xFFFF:
count -= 0x111
assert 0 <= count <= 0xFFFF
l = (1 << 28) | (count << 12) | disp
out.write(pack(">L", l))
length += 4
else:
raise ValueError(count)
else:
out.write(pack(">B", t))
length += 1
# padding
padding = 4 - (length % 4 or 4)
if padding:
out.write(b'\xff' * padding)
def dump_compress_nlz11(input, out):
# body
length = 0
def dump():
for t in _compress(input, windowclass=NLZ11Window):
if type(t) == tuple:
yield t
from pprint import pprint
pprint(list(dump()))
if __name__ == '__main__':
from sys import stdout, argv
data = open(argv[1], "rb").read()
stdout = stdout.detach()
#compress(data, stdout)
compress_nlz11(data, stdout)
#dump_compress_nlz11(data, stdout)

View File

@ -1,163 +0,0 @@
from PIL import Image, ImageDraw
from io import BytesIO
from compress import compress_nlz11
from struct import pack
import sys
longtitle=sys.argv[1]
shortitle=sys.argv[2]
publisher=sys.argv[3]
# fixed variables; not likely these will be used in this context, but here just in case.
visibility =1
autoBoot =0
use3D =1
requireEULA =0
autoSaveOnExit=0
extendedBanner=0
gameRatings =0
useSaveData =1
recordAppUsage=0
disableSaveBU =0
def make_icon(file, size):
f=open(file,'rb')
image=Image.open(f)
posit=open('map' + str(size) + 'x' + str(size) + '.bin','rb')
w=image.size[0]
h=image.size[1]
n=w*w
i=[0]*(n*2)
if w != h:
print("width, height unequal")
f.close()
sys.exit(1)
if w != size:
print("sides need to be " + str(size) + " pixels")
f.close()
sys.exit(1)
dump=list(image.getdata())
pos=0
for x in range(n):
p1=ord(posit.read(1))
p2=ord(posit.read(1))
pos=p1+(p2<<8)
r=dump[x][0]>>3
g=dump[x][1]>>2
b=dump[x][2]>>3
i[pos<<1]=(g&7)<<5| b
i[(pos<<1)+1]=(r)<<3 | g>>3
f.close()
posit.close()
return bytearray(i)
def make_banner(file):
f=open(file,'rb')
image=Image.open(f)
if image.size[0] != 256 or image.size[1] != 128:
f.close()
print("ERROR: Image must be exactly 256 x 128. Abort.")
sys.exit(4)
hdr=open("header.bin","rb")
posit=open('map256x128.bin','rb')
n=256*128
i=[0]*(n*2)
cbmdhdr=bytearray(b"\x43\x42\x4D\x44\x00\x00\x00\x00\x88"+(b"\x00"*0x7B))
dump=list(image.getdata())
pos=0
for x in range(n):
p1=ord(posit.read(1))
p2=ord(posit.read(1))
pos=p1+(p2<<8)
r=dump[x][0]>>4
g=dump[x][1]>>4
b=dump[x][2]>>4
a=dump[x][3]>>4
i[pos<<1]= (b<<4) | a
i[(pos<<1)+1]= (r<<4) | g
buf=hdr.read()
hdr.close()
out = BytesIO()
compress_nlz11(buf+bytearray(i), out)
l=bytearray(out.getvalue())
length=len(l)+136
pad=16-(length%16)
l+=bytearray([0]*pad)
length+=pad
for c in range(4):
cbmdhdr+=pack("B", length & 255)
length=length>>8
cbmdhdr+=l
f.close()
posit.close()
return bytearray(cbmdhdr)
def make_audio():
# TODO: Convert WAV file.
bcwav1=open("audio.bcwav","rb")
bcwav=bcwav1.read()
bcwav1.close()
return bytearray(bcwav)
ctp1=make_icon(sys.argv[4], 24)
ctp2=make_icon(sys.argv[5], 48)
bcwav=make_audio()
cbmd=make_banner(sys.argv[6])
icn=open(sys.argv[7],"wb")
bnr=open(sys.argv[8],"wb")
header=bytearray(b"\x53\x4D\x44\x48\x00\x00\x00\x00")+bytearray(b"\x00"*0x1FF8)+bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\xFF\xFF\xFF\x7F\x31\x48\x62\x64\x99\x99\x99\x19\x91\x18\x62\x64\xA5\x01\x00\x00\x00\x01\x00\x00\x00\x00\x80\x3F\x32\x41\x79\x24\x00\x00\x00\x00\x00\x00\x00\x00")
header[0x2028]=(visibility | autoBoot<<1 | use3D<<2 | requireEULA<<3 | autoSaveOnExit<<4 | extendedBanner<<5 | gameRatings<<6 | useSaveData<<7)
header[0x2029]=(recordAppUsage | disableSaveBU<<2)
offset=8
pos=0
for x in range(11):
for c in longtitle:
header[offset+pos*2]=ord(longtitle[pos])
pos+=1
pos=0
offset+=0x80
for c in shortitle:
header[offset+pos*2]=ord(shortitle[pos])
pos+=1
pos=0
offset+=0x100
for c in publisher:
header[offset+pos*2]=ord(publisher[pos])
pos+=1
pos=0
offset+=0x80
header+=(ctp1+ctp2)
icn.write(header)
bnr.write(cbmd+bcwav)
bnr.close()
icn.close()

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

BIN
tools/bannertool Executable file

Binary file not shown.