From e69bcd5df44198a4aa2c376c72d812e80735b8bf Mon Sep 17 00:00:00 2001 From: Squideo Kojima Date: Tue, 17 Nov 2015 21:34:26 -0800 Subject: [PATCH] Hello World --- .gitignore | 6 + Makefile | 31 + README.md | 25 + art/bluefin.nam | Bin 0 -> 1024 bytes art/bluefin_depot_nametable.bmp | Bin 0 -> 30838 bytes art/bluefin_depot_nametable.nam | Bin 0 -> 1024 bytes art/combined_chr.chr | Bin 0 -> 4096 bytes art/combined_tiles.bmp | Bin 0 -> 8310 bytes art/endgame.nam | Bin 0 -> 1024 bytes art/inkling_tiles.bmp | Bin 0 -> 8310 bytes art/kelp_dome_nametable.bmp | Bin 0 -> 30838 bytes art/kelp_dome_nametable.nam | Bin 0 -> 1024 bytes art/map_tiles.bmp | Bin 0 -> 8310 bytes art/palette.pal | 1 + art/saltspray_rig.bmp | Bin 0 -> 30838 bytes art/saltspray_rig.nam | Bin 0 -> 1024 bytes art/test_map.nam | Bin 0 -> 1024 bytes crt0.s | 259 ++++++ famitone2.s | 1236 ++++++++++++++++++++++++++++ game.c | 1357 +++++++++++++++++++++++++++++++ levels/bluefin.h | 40 + levels/endgame.h | 1 + levels/kelpdome.h | 40 + levels/saltspray.h | 40 + levels/splat_title.h | 37 + levels/twofish.h | 40 + music.s | 653 +++++++++++++++ neslib.h | 296 +++++++ neslib.s | 1245 ++++++++++++++++++++++++++++ nrom.cfg | 59 ++ runtime.lib | Bin 0 -> 107045 bytes sound/music.ftm | Bin 0 -> 11041 bytes sound/sounds.ftm | Bin 0 -> 1577 bytes sounds.s | 52 ++ tileset.chr | Bin 0 -> 8192 bytes util/bin-to-h.py | 33 + util/credits.sh | 26 + util/ebcdic.py | 9 + 38 files changed, 5486 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 art/bluefin.nam create mode 100644 art/bluefin_depot_nametable.bmp create mode 100644 art/bluefin_depot_nametable.nam create mode 100644 art/combined_chr.chr create mode 100644 art/combined_tiles.bmp create mode 100644 art/endgame.nam create mode 100644 art/inkling_tiles.bmp create mode 100644 art/kelp_dome_nametable.bmp create mode 100644 art/kelp_dome_nametable.nam create mode 100644 art/map_tiles.bmp create mode 100644 art/palette.pal create mode 100644 art/saltspray_rig.bmp create mode 100644 art/saltspray_rig.nam create mode 100644 art/test_map.nam create mode 100644 crt0.s create mode 100644 famitone2.s create mode 100644 game.c create mode 100644 levels/bluefin.h create mode 100644 levels/endgame.h create mode 100644 levels/kelpdome.h create mode 100644 levels/saltspray.h create mode 100644 levels/splat_title.h create mode 100644 levels/twofish.h create mode 100644 music.s create mode 100644 neslib.h create mode 100644 neslib.s create mode 100644 nrom.cfg create mode 100644 runtime.lib create mode 100644 sound/music.ftm create mode 100644 sound/sounds.ftm create mode 100644 sounds.s create mode 100644 tileset.chr create mode 100644 util/bin-to-h.py create mode 100644 util/credits.sh create mode 100644 util/ebcdic.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f90d69 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o +*.nes +*~ +game.s +.DS_Store +*.swp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7854aa5 --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +ROM_CONFIG = nrom.cfg +CRT_OBJ = crt0.o +GAME_OBJ = game.o +RUNTIME_LIB = runtime.lib + +EXECUTABLE = splatood.nes + +ASM = ca65 +CC = cc65 +LD = ld65 + + +all: $(EXECUTABLE) ${CRT_OBJ} + +crt0.o: *.s + +%.s: %.c *.h + $(CC) -Oi $< --add-source + +%.o: %.s + $(ASM) $< + +$(EXECUTABLE): $(GAME_OBJ) $(ROM_CONFIG) $(CRT_OBJ) $(RUNTIME_LIB) + $(LD) -C $(ROM_CONFIG) -o $(EXECUTABLE) $(CRT_OBJ) $(GAME_OBJ) $(RUNTIME_LIB) + +clean: + rm -f game.s *.o *.nes + + +.SECONDARY: # suppress removal of intermediate build files +%.o: %.c # suppress built in rule to build .o from .c diff --git a/README.md b/README.md new file mode 100644 index 0000000..9daf734 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# SplatooD: A Splatoon demake for NES + +![screenshot](http://i.imgur.com/jGOvsaF.png) + +## Controls + +D-pad to move, A to flick roller, START to pause. Menus accept D-pad to move cursor and START to select an item. + +## Building + +Install [cc65](ftp://ftp.musoftware.de/pub/uz/cc65/cc65-sources-2.13.3.tar.bz2) v2.13.3 or thereabouts and then run `make`. + +Assets were created in NESST and Famitracker. + +### Updating Strings + +All strings in SplatooD are formatted as EBCDIC with an offset. Use the Python script in `util/ebcdic.py` to convert ASCII to appropriate arrays. + +### Updating Nametable Headers + +There is a tool to convert binary nametables into C headers in `util/bin-to-h.py`. + +## Cartridge Details + +We target an NROM256 cartridge with two 16kB PRG ROMs and one 8kB CHR ROM. diff --git a/art/bluefin.nam b/art/bluefin.nam new file mode 100644 index 0000000000000000000000000000000000000000..1c7b3c0cc5c43e08ef96be948345d1fab94dd84b GIT binary patch literal 1024 zcmb`E%L>9U5Jd~!2GlWPARke6~Z_8f3+d3I)zS2rx5PxDM=pcmAYr! U+-l`gr_x&0p&{OW;wX#s2CJ&7od5s; literal 0 HcmV?d00001 diff --git a/art/bluefin_depot_nametable.bmp b/art/bluefin_depot_nametable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ad440dae3e125fbdd9866f880f81ca5a9124ed8f GIT binary patch literal 30838 zcmeI4J(43;5QKYUIKZxrfr~j2vcSaOGhi*aSQ~hloPr||#2Ppl+-7}lFsRk~B+b`q zvfi7~jKPyJ)mfF5*{c52U(a{%KmI%&9v}CAzn+)gOw&Jy@WqU#=~$l^-_C!Ij}Jfo zF#YlA)AaE0aLD}j)igc){(gG+{MW*G_hFj8{d4;M*QGvvvrqr@0Q`>Acr|Gy`|pte}ld*hZa`Ds}=2D0ba>r3BR>H5;$-JHL_zh1rl@ppG{ zUjANN2cAc7yry}XyE|NAcdz&ScW>UkdprCux5?#l?{=r}QtR6C-I)K_|Hkq6zd8SL zULbP(gME%5-y2tYO588!pTkvnUs}Bm==G&fcDviN&xd+TxKJk;w;-|&Atfy41W=6`(xFS7r! zXI>t6n{0|@o|BC zYqX9r{?2dV;omlatvQk(^Pi9Z_4$tZIJQlHS{=vM8}lFYf8G6W-lJb}|36%M*VlU= zC*Ws4{=(<3_!6Jn|9FCk=ZTy7ADPY)lc76eJh{(s1tj2di(Gt_UiQZ;Y;k* z>FvXp*sIgqhcB^Lr?(GZVy{kbAHKw1o!<iM=|#efSc4b$a{oCHCs{_TfwH)#>fS zm)NV*+lMc)SEsiRUt+ILZy&zIUY*`Pe2M5JY@Ye9C+z-&t!KXL3A;aG>zVI*!tPJl zdgi;Hu=^9Xp82jP?EZwUXTIwRyFX#;neTeS?oZfy=DVJ-`xCaF`K~AI{)DY(zUv9Q zKVj>c?|Q=SPuP0qyPmN76SkiDt|#pNgso@3>j}F*Ve6Uidcy8c*m~x>p7H%O@tw+^ zob;%th%XU7c>kNZ#rM(o*DvUg@BU-V`GaI0>-AhJy|?82`lvFb_WYYNU@y9~fUEdGnm7o+5oj_+WgA zM7Dkgb&7-NZvf>si#OE5k44SB6;(ir=B8xMEGEQIS$C1 z=REZk=_A4i<4YuOp7YdGq>l(6eDXaE;`PqIJFWxA74v$szT~TsJ|cbKv+wI(f4yD_ zv;OdiX)-&Jrgx#O8^~`rYVfQC& zJ@Z{p*!>Ax&wSStc7MXwGvD=u-Jh`a%y&Iu_a|&U^IcEa{RvyoeAg3pf5O%?-}Qvu zpRo1JcRgYECu}|QT~FBk30u#6*Aw3A-|8cuVpX@wOMb3bb*nt@ctG@7(FZFc)KRk4+ zk-ij{U*P87;Z}X&C12|4{(pGrRwI2WR)2?I^@W#wsSp4C2e^g%FqmsKGT#)({Kx#q z{+I6qsUCOc`S^34h)Xo)Wqbb9FyP)n|(*yK(>j=@%kQY(D?6yxtF~^v2cv z$Nm4;?>%3B#^M{IS6i!fJB;~1p1|RJx3vYXybfxexA~9Vcf0fd-?%*P=z4+Uk3CG^ zn=k9Rejmb`^~Tln=a*8C{_hH`d)AJ`v+w_0V07KVk23iA{f~q6b(i^`jE@WCd!zNh z_=C4%uP=RDy2JlAult!ham@ev1jhb1_P<-a@8q~6Uf=t89k9OMn~zR!v>y0YpF4Uz z@pHV@=dM-%TYc_a_CFFm7h~(SV(YcyRzLGw{mi#sE4E%MZuK+2)z5tEwPNeF;#NQN zTm8(pUMsd$PI*wc=Jk^IQGQw_Yo@UMp_(Gr!f(eCxGh>$T!mKl5At j%(q@Ewq7f4^)tWK&wT3*JSH$EFeWf2FeWf2FedOX*b3){ literal 0 HcmV?d00001 diff --git a/art/bluefin_depot_nametable.nam b/art/bluefin_depot_nametable.nam new file mode 100644 index 0000000000000000000000000000000000000000..43772af025458e44f6f5abfea2097263059e5b7f GIT binary patch literal 1024 zcmbu6-3@~<421idEiC#M!5eL*6t-f7N|}IRSg$^eaT=hi=sh5u&v#B_=k}?~Y?Nsq zFOC|s?!R2W@xq_Z-up3Q&0mM`yg$MX8Qt(oUZAN&Hlb%}i}8ANqmC07=A88qxhPfS zfK@)73P+FhVIKO&6V8x&$%ldGGw=JdO1a+#j)AFfom74JXj{!@m3a7ZU?aoztGmz4Z= OmcPaGykG0XpLzo~(qr-f literal 0 HcmV?d00001 diff --git a/art/combined_chr.chr b/art/combined_chr.chr new file mode 100644 index 0000000000000000000000000000000000000000..e9daa461b996028f2ccbc32630a47eee1e0bc6d3 GIT binary patch literal 4096 zcmeHDJx{_=6uqU;*M#usWD|mvpI~BQ7%=u{xY>lo!NliOw$?x3Z{R1e;b1~1CI>f1 z-&PZ}VKR+E@!khGh#wo%J9+KxdGDOpdk+AsRG90sy4`5l-addF4CFMEGw1Zw$vXgM zsf4TUb&rp`trq+U@)NwKIyT5p$ZxmhiSOf@<=wlxZoj{MzS|wwbuEhlRLabM6QFzQW zjFlW6%VitkIJTvT;*MP|mrE%56C3?+6`L2AXD2|-Q^n@_+xr}-d8+7R>EkG*pU8)y zKrYkiYet+^YkWO^xSC#w_4t_@9$%q+b>3xy_K`OWLMbf4-43|lf6Hwv>maEF$E|v6@==X-2 zEFkY%vWplnW?=DWc0SJVQB>nk=ND&A>;mlvJeSk+%Duq|b|$SfZx2IveRJbVDe}<$ z{k?PL>fDvvUlR4@^=H?9ymIC8Z>7GzbME&y_v6n`=gmw3Q@|831xx``z!WeAOaW8C z6fgx$0aL&fFa=BjQ@|831xx``;KeC`{~L(u#zJXg+?1@n`b){)hf?AYBcFqR;-@ZG zJ}6(^XfxLhCwTx2$|W!k-Biav9&Q%K+#N>q{2?Ls^T{VPyEc`vjO;!BlHw3v{66wszD!J&@>=diGj$9^H*fv@wmyx+&TMR1z-k3qtl#QYJ1MQiu_?RH0= qtH6Yp(f)t%$Lp8;tLoQ!aghYlx$I49n>K#{3vbxC3BtglXjF*GA;3Tou(Gmp;Z_6y Dl3!0! literal 0 HcmV?d00001 diff --git a/art/inkling_tiles.bmp b/art/inkling_tiles.bmp new file mode 100644 index 0000000000000000000000000000000000000000..514f982d4b1836f0093b8f8e2872c83b6e99c6eb GIT binary patch literal 8310 zcmeH`u}uUq5Jiok0H6XwS|CMUJ0in-4eX8sBqFaZksM{v1-b@kfKv)Q9u8GX^5f}4eSd1PWpgpt z%a@O@@6C;==561yMZo|JzyJ)u01UtY48Q;kzyJ)u01UtY48Q;kzyJ)u01UtY48Q;k z{2K#~T1}StV`*|!a>+DlAGq;OP8fubIUd1V>z7^PIoV>vJ-6*y+h54Qye&Qrf^(Mh z^c6ejV+sw5$!9%nhggb$j+WM5@^O4vgml!~4{;ZAJ4ts5-oIo<9d&5SI+}G!KfZvY z)DR!TB3WBr-plH~`JT1BokJLTGp+CE1@SLQjk|ds$4PiOg{$#>shR)E|9*c>=XK9| VU&pU*b>#h7eE+v@{FZfB_yoj2!w3KX literal 0 HcmV?d00001 diff --git a/art/kelp_dome_nametable.bmp b/art/kelp_dome_nametable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f19f14e2f474a984fff86354a1a5569c97d486c4 GIT binary patch literal 30838 zcmeI4zmnuM5XOBqJiu&BKuS1O6G2FR&p>pL5?zrI@)SG*MO{Ebz}sBT8!Wc$pXBbA z+!~K;{+uS*w)#_lpVX3NOS8M*ynX-U5I*n6pI=T_Z-(KoU_P5l!?57f<#qb8eBOQk z-SFFo55w#0Yw-N?#W1}7`gVBz_{Uu1<=rrR{rm9k&oe%JHM)QJd>H=xX<_K5XP{@G zXP{@GXP{@`Q_8^I`5c`KNB-XRkIg{O|8@qB&HgZKtKa+lKX?Fo{D6lG`Nz@?z93 zH)^!BmwNp}X5iiEhxBI#;BsG(IX`WFUc0`Ye?9+UYMBM#toc{G|EKwXWwct@iOR zdEKJESFaX_kA8S@)c5Mu;_!9-IRjqa$d^~I7Kg9rzvq9-fH!ZLFJ8S`9KQd~{0muX z_5ggi|3SIkF63eT@Jzh@WBp$ys5?)Ont!$P^eFvWUh3)g>hh!G4{xp2(A!} zX}+3r@%^v1huih$J2l;}rhK%1I4`)z`}JbVh4=66ZdIdivQ7I4%F`{o!o=)1N=f`p*2j6=A zIbT!WSS;#`bN;km5I8@_&8TG@^ZG)Zwq^Y>j?Z{LnT-SYY$hJQt}oYr1~BA>yk_zz zaO#z8Ccfu?&cNpUi|71>`5$pctz>O{RsQ4muXeSW+nqU}hFDk|54_!fZu`vo8=h<6 zu$8Qhr{=bPJm)u$n5ZIsve6T9xFN*@aT5qFNJ$} zDNg(0>H0DQ8r20_XdyO!_n#bG6UqLls^wI#c4l0QoWBqdC~cz z?BUe&EId8`G6UqLls^wI#c4l0QvKgI|GoBUoPKIQW$@bm>lY}!uUB|1#tQ^z8{M_~ zX1}lY^%76-o6=7sR=7HUCqJ}{2=fN5_Vp4^rE~?;WRn*ibg}q}vip7ce3p3HZ%9Av zYkXt>x!N~|_UQd(2`~AH*Z5ebWmwz)v7P#(dB98l65jQD{+W1-wewF^2*ve%w8q!| z>Hb<{)3wGc=6`mpy;?^EzVe6lO>dJmUZJlk!osv#M+Ls}XU_>V?(4?~1`FbBqdQ(G z|1yrEbz_xSopIJ9gdaJLQ!e57;h{d(!-=EbUhDCI(=IIjy}HDCJmBbJ@x!y%dOYCh zV)5_QCC=jkM;D79p1s!N0Y?{$f3Gfa9uGLWSp4wpwH^;Rx>)>sb&2zMz|qCxhi9+# zc)-!c;@_)FoW}!>E*3vLd#%RZvVya2N0FB@|+;*$N0MaKXKU5KK9d| zUG2xS@fG`T;;>yma~@I}hn|0Pw~G0*cmA1ueeV97d}+U*=I^?$zyBo;JFgFVTMMdf zTx}vCJ?Za{Y1Pbc+YP~to3sKeoA&zvas3UB^!L|~>Brv>fVO0L+(cYCkd3yk|90FW zfx3vo%Y}kXQR`Cy9*yIF)}o{Nmwd&vY5ZAT;!FDTd`a`@bp0^Z(_M4Ae&P4_$y+O1 z%)k15fb;t=-($MI%ts&pHW?_-{|QOY!})u)RBof5{=bx--}B0|T7T4fbhv(a)mW{+ zs(iG*e*Wn4;rh$OK!m$@OnJdYpy>F$M=U)JC4%V?+>TzSKhCO^)sc-{+xl<>t8Kj&wtPVlmX@o^Wj+wpIvpvU;SAfBcZd@Um-T~ z5fA75CMKMJCmE?9hpW0;!AM_Ny2hjiLOX^c zd9Ocn4jt0J8UT74=HFhOQe4+JH&oAmm@HTB<~0AfYH96xLGk`GBSj0JvFZE(mZE;c zr4Oz9J)Iv!Ut#@qH;R$qp$kh}c>c5;^);7mZT|VYj%j&q^`)n!R*p-m*-|d1rOzr# zPfM*FmsGQ*Tue)!Rg|8VS~)JMW=px4mOiT}JuS6zTvE-JaxpD^R#AFdYUQ}3nl0sG zTKcS_^t9B%Eh$wSw-n-sg>iBYPOV%Y3Z|y($i8a$0gNlDHqdyJp(-hJp(-h MJp(-h|L+X^4c3rk%>V!Z literal 0 HcmV?d00001 diff --git a/art/kelp_dome_nametable.nam b/art/kelp_dome_nametable.nam new file mode 100644 index 0000000000000000000000000000000000000000..7e7b63992c1cb8ddc7292e52e0c5ce4b602f1b0c GIT binary patch literal 1024 zcmcIh(F%hw4BV$wJFDo6ILAc4v;VtXVw!GtAZ$AjORmY?H8K7NZpWwT#@Af|9(+GI z7h||D2h1(_bz}a4^D6@Ls8N4`pKf|z_?qO&JetMVI2 ze&JQEs`P}qYyJn{41@px literal 0 HcmV?d00001 diff --git a/art/map_tiles.bmp b/art/map_tiles.bmp new file mode 100644 index 0000000000000000000000000000000000000000..27ee45f794e5026cae1271d9292fcae296d58b3e GIT binary patch literal 8310 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 literal 0 HcmV?d00001 diff --git a/art/saltspray_rig.nam b/art/saltspray_rig.nam new file mode 100644 index 0000000000000000000000000000000000000000..683a3a07be891cfc27551e2646497fdaa31fb4f1 GIT binary patch literal 1024 zcmcgqZ4QDk3|-=1lIaOtP!J>j0m1Khbq_$oRk*?ITDk(p{m{g>WbNLgZ{1kF&x7N3 z50ClIm>gg{+)8k{hILPj$<6WFjoNZU^#=hcZOj;c_A-zu4$BWMgQ00zNV7DKz~7sMksM?mz`pU!D54z01hIhC@#<(u-*| z-H|Inf2@^^cv=fP%*1`j{`3D~%l_SQKg7z+JV#O%KfZr*`+igUR>G{5h4_SE8{|zF=?1>mJzhg0r%C_- literal 0 HcmV?d00001 diff --git a/art/test_map.nam b/art/test_map.nam new file mode 100644 index 0000000000000000000000000000000000000000..bc5a86fe5b47026bc6f9d0d1e470284d557f0f4f GIT binary patch literal 1024 zcmbtS*-lhJ5G^mD;yNfQl2%V*03#Z}xZp0zd;keoqN2XY2Po?|fD4-V=mP2xd;|9t zHORn&Tf&&Qpy1$NnBb|pGjjnGUOe}9b#7p7q>x?z`5LW;3(qqpu%eJzzbvq4XdSht)Ga@hh2}AyJ+qT~BiI_r&CM zf%5#c9<>I@JWsO32&DN8rw(#tzARX%9tA-r=McGz7R!>QTnC3EWauqp14i;ztjuQv zDzBgIL0>cY;OsAL4{bn(7*m@;k=`d!T(T*}z&4YhG>d^K5nry$S)%TnI+QC0lQv+ubWBKu(-dIB-dimPbSgau@ Fg}-met&;!% literal 0 HcmV?d00001 diff --git a/crt0.s b/crt0.s new file mode 100644 index 0000000..8002161 --- /dev/null +++ b/crt0.s @@ -0,0 +1,259 @@ +; Startup code for cc65 and Shiru's NES library +; based on code by Groepaz/Hitmen , Ullrich von Bassewitz + + +FT_DPCM_OFF = $c000 ;$c000..$ffc0, 64-byte steps +FT_SFX_STREAMS = 4 ;number of sound effects played at once, 1..4 + +.define FT_DPCM_ENABLE 1 ;undefine to exclude all DMC code +.define FT_SFX_ENABLE 1 ;undefine to exclude all sound effects code + + + + .export _exit,__STARTUP__:absolute=1 + .import initlib,push0,popa,popax,_main,zerobss,copydata + +; Linker generated symbols + .import __RAM_START__ ,__RAM_SIZE__ + .import __ROM0_START__ ,__ROM0_SIZE__ + .import __STARTUP_LOAD__,__STARTUP_RUN__,__STARTUP_SIZE__ + .import __CODE_LOAD__ ,__CODE_RUN__ ,__CODE_SIZE__ + .import __RODATA_LOAD__ ,__RODATA_RUN__ ,__RODATA_SIZE__ + .import NES_MAPPER,NES_PRG_BANKS,NES_CHR_BANKS,NES_MIRRORING + .include "zeropage.inc" + + + +FT_BASE_ADR =$0100 ;page in RAM, should be $xx00 + +.define FT_THREAD 1 ;undefine if you call sound effects in the same thread as sound update +.define FT_PAL_SUPPORT 1 ;undefine to exclude PAL support +.define FT_NTSC_SUPPORT 1 ;undefine to exclude NTSC support + + +PPU_CTRL =$2000 +PPU_MASK =$2001 +PPU_STATUS =$2002 +PPU_OAM_ADDR=$2003 +PPU_OAM_DATA=$2004 +PPU_SCROLL =$2005 +PPU_ADDR =$2006 +PPU_DATA =$2007 +PPU_OAM_DMA =$4014 +PPU_FRAMECNT=$4017 +DMC_FREQ =$4010 +CTRL_PORT1 =$4016 +CTRL_PORT2 =$4017 + +OAM_BUF =$0200 +PAL_BUF =$01c0 + + + +.segment "ZEROPAGE" + +NTSC_MODE: .res 1 +FRAME_CNT1: .res 1 +FRAME_CNT2: .res 1 +VRAM_UPDATE: .res 1 +NAME_UPD_ADR: .res 2 +NAME_UPD_ENABLE: .res 1 +PAL_UPDATE: .res 1 +PAL_BG_PTR: .res 2 +PAL_SPR_PTR: .res 2 +SCROLL_X: .res 1 +SCROLL_Y: .res 1 +SCROLL_X1: .res 1 +SCROLL_Y1: .res 1 +PAD_STATE: .res 2 ;one byte per controller +PAD_STATEP: .res 2 +PAD_STATET: .res 2 +PPU_CTRL_VAR: .res 1 +PPU_CTRL_VAR1: .res 1 +PPU_MASK_VAR: .res 1 +RAND_SEED: .res 2 +FT_TEMP: .res 3 + +TEMP: .res 11 + +PAD_BUF =TEMP+1 + +PTR =TEMP ;word +LEN =TEMP+2 ;word +NEXTSPR =TEMP+4 +SCRX =TEMP+5 +SCRY =TEMP+6 +SRC =TEMP+7 ;word +DST =TEMP+9 ;word + +RLE_LOW =TEMP +RLE_HIGH =TEMP+1 +RLE_TAG =TEMP+2 +RLE_BYTE =TEMP+3 + + + +.segment "HEADER" + + .byte $4e,$45,$53,$1a + .byte (__RAM_START__+__RAM_SIZE__) + sta sp+1 ; Set argument stack ptr + + jsr initlib + + lda #%10000000 + sta music_data + lda sounds_data + jsr FamiToneSfxInit + .endif + + lda #$fd + sta >6 + + +;zero page variables + +FT_TEMP_PTR = FT_TEMP ;word +FT_TEMP_PTR_L = FT_TEMP_PTR+0 +FT_TEMP_PTR_H = FT_TEMP_PTR+1 +FT_TEMP_VAR1 = FT_TEMP+2 + + +;envelope structure offsets, 5 bytes per envelope, grouped by variable type + +FT_ENVELOPES_ALL = 3+3+3+2 ;3 for the pulse and triangle channels, 2 for the noise channel +FT_ENV_STRUCT_SIZE = 5 + +FT_ENV_VALUE = FT_BASE_ADR+0*FT_ENVELOPES_ALL +FT_ENV_REPEAT = FT_BASE_ADR+1*FT_ENVELOPES_ALL +FT_ENV_ADR_L = FT_BASE_ADR+2*FT_ENVELOPES_ALL +FT_ENV_ADR_H = FT_BASE_ADR+3*FT_ENVELOPES_ALL +FT_ENV_PTR = FT_BASE_ADR+4*FT_ENVELOPES_ALL + + +;channel structure offsets, 7 bytes per channel + +FT_CHANNELS_ALL = 5 +FT_CHN_STRUCT_SIZE = 9 + +FT_CHN_PTR_L = FT_BASE_ADR+0*FT_CHANNELS_ALL +FT_CHN_PTR_H = FT_BASE_ADR+1*FT_CHANNELS_ALL +FT_CHN_NOTE = FT_BASE_ADR+2*FT_CHANNELS_ALL +FT_CHN_INSTRUMENT = FT_BASE_ADR+3*FT_CHANNELS_ALL +FT_CHN_REPEAT = FT_BASE_ADR+4*FT_CHANNELS_ALL +FT_CHN_RETURN_L = FT_BASE_ADR+5*FT_CHANNELS_ALL +FT_CHN_RETURN_H = FT_BASE_ADR+6*FT_CHANNELS_ALL +FT_CHN_REF_LEN = FT_BASE_ADR+7*FT_CHANNELS_ALL +FT_CHN_DUTY = FT_BASE_ADR+8*FT_CHANNELS_ALL + + +;variables and aliases + +FT_ENVELOPES = FT_BASE_ADR +FT_CH1_ENVS = FT_ENVELOPES+0 +FT_CH2_ENVS = FT_ENVELOPES+3 +FT_CH3_ENVS = FT_ENVELOPES+6 +FT_CH4_ENVS = FT_ENVELOPES+9 + +FT_CHANNELS = FT_ENVELOPES+FT_ENVELOPES_ALL*FT_ENV_STRUCT_SIZE +FT_CH1_VARS = FT_CHANNELS+0 +FT_CH2_VARS = FT_CHANNELS+1 +FT_CH3_VARS = FT_CHANNELS+2 +FT_CH4_VARS = FT_CHANNELS+3 +FT_CH5_VARS = FT_CHANNELS+4 + + +FT_CH1_NOTE = FT_CH1_VARS+.lobyte(FT_CHN_NOTE) +FT_CH2_NOTE = FT_CH2_VARS+.lobyte(FT_CHN_NOTE) +FT_CH3_NOTE = FT_CH3_VARS+.lobyte(FT_CHN_NOTE) +FT_CH4_NOTE = FT_CH4_VARS+.lobyte(FT_CHN_NOTE) +FT_CH5_NOTE = FT_CH5_VARS+.lobyte(FT_CHN_NOTE) + +FT_CH1_INSTRUMENT = FT_CH1_VARS+.lobyte(FT_CHN_INSTRUMENT) +FT_CH2_INSTRUMENT = FT_CH2_VARS+.lobyte(FT_CHN_INSTRUMENT) +FT_CH3_INSTRUMENT = FT_CH3_VARS+.lobyte(FT_CHN_INSTRUMENT) +FT_CH4_INSTRUMENT = FT_CH4_VARS+.lobyte(FT_CHN_INSTRUMENT) +FT_CH5_INSTRUMENT = FT_CH5_VARS+.lobyte(FT_CHN_INSTRUMENT) + +FT_CH1_DUTY = FT_CH1_VARS+.lobyte(FT_CHN_DUTY) +FT_CH2_DUTY = FT_CH2_VARS+.lobyte(FT_CHN_DUTY) +FT_CH3_DUTY = FT_CH3_VARS+.lobyte(FT_CHN_DUTY) +FT_CH4_DUTY = FT_CH4_VARS+.lobyte(FT_CHN_DUTY) +FT_CH5_DUTY = FT_CH5_VARS+.lobyte(FT_CHN_DUTY) + +FT_CH1_VOLUME = FT_CH1_ENVS+.lobyte(FT_ENV_VALUE)+0 +FT_CH2_VOLUME = FT_CH2_ENVS+.lobyte(FT_ENV_VALUE)+0 +FT_CH3_VOLUME = FT_CH3_ENVS+.lobyte(FT_ENV_VALUE)+0 +FT_CH4_VOLUME = FT_CH4_ENVS+.lobyte(FT_ENV_VALUE)+0 + +FT_CH1_NOTE_OFF = FT_CH1_ENVS+.lobyte(FT_ENV_VALUE)+1 +FT_CH2_NOTE_OFF = FT_CH2_ENVS+.lobyte(FT_ENV_VALUE)+1 +FT_CH3_NOTE_OFF = FT_CH3_ENVS+.lobyte(FT_ENV_VALUE)+1 +FT_CH4_NOTE_OFF = FT_CH4_ENVS+.lobyte(FT_ENV_VALUE)+1 + +FT_CH1_PITCH_OFF = FT_CH1_ENVS+.lobyte(FT_ENV_VALUE)+2 +FT_CH2_PITCH_OFF = FT_CH2_ENVS+.lobyte(FT_ENV_VALUE)+2 +FT_CH3_PITCH_OFF = FT_CH3_ENVS+.lobyte(FT_ENV_VALUE)+2 + + +FT_VARS = FT_CHANNELS+FT_CHANNELS_ALL*FT_CHN_STRUCT_SIZE + +FT_PAL_ADJUST = FT_VARS+0 +FT_SONG_LIST_L = FT_VARS+1 +FT_SONG_LIST_H = FT_VARS+2 +FT_INSTRUMENT_L = FT_VARS+3 +FT_INSTRUMENT_H = FT_VARS+4 +FT_TEMPO_STEP_L = FT_VARS+5 +FT_TEMPO_STEP_H = FT_VARS+6 +FT_TEMPO_ACC_L = FT_VARS+7 +FT_TEMPO_ACC_H = FT_VARS+8 +FT_SONG_SPEED = FT_CH5_INSTRUMENT +FT_PULSE1_PREV = FT_CH3_DUTY +FT_PULSE2_PREV = FT_CH5_DUTY +FT_DPCM_LIST_L = FT_VARS+9 +FT_DPCM_LIST_H = FT_VARS+10 +FT_DPCM_EFFECT = FT_VARS+11 +FT_OUT_BUF = FT_VARS+12 ;11 bytes + + +;sound effect stream variables, 2 bytes and 15 bytes per stream +;when sound effects are disabled, this memory is not used + +FT_SFX_ADR_L = FT_VARS+23 +FT_SFX_ADR_H = FT_VARS+24 +FT_SFX_BASE_ADR = FT_VARS+25 + +FT_SFX_STRUCT_SIZE = 15 +FT_SFX_REPEAT = FT_SFX_BASE_ADR+0 +FT_SFX_PTR_L = FT_SFX_BASE_ADR+1 +FT_SFX_PTR_H = FT_SFX_BASE_ADR+2 +FT_SFX_OFF = FT_SFX_BASE_ADR+3 +FT_SFX_BUF = FT_SFX_BASE_ADR+4 ;11 bytes + + +;aliases for sound effect channels to use in user calls + +FT_SFX_CH0 = FT_SFX_STRUCT_SIZE*0 +FT_SFX_CH1 = FT_SFX_STRUCT_SIZE*1 +FT_SFX_CH2 = FT_SFX_STRUCT_SIZE*2 +FT_SFX_CH3 = FT_SFX_STRUCT_SIZE*3 + + +;aliases for the APU registers + +APU_PL1_VOL = $4000 +APU_PL1_SWEEP = $4001 +APU_PL1_LO = $4002 +APU_PL1_HI = $4003 +APU_PL2_VOL = $4004 +APU_PL2_SWEEP = $4005 +APU_PL2_LO = $4006 +APU_PL2_HI = $4007 +APU_TRI_LINEAR = $4008 +APU_TRI_LO = $400a +APU_TRI_HI = $400b +APU_NOISE_VOL = $400c +APU_NOISE_LO = $400e +APU_NOISE_HI = $400f +APU_DMC_FREQ = $4010 +APU_DMC_RAW = $4011 +APU_DMC_START = $4012 +APU_DMC_LEN = $4013 +APU_SND_CHN = $4015 + + +;aliases for the APU registers in the output buffer + + .if(!FT_SFX_ENABLE) ;if sound effects are disabled, write to the APU directly +FT_MR_PULSE1_V = APU_PL1_VOL +FT_MR_PULSE1_L = APU_PL1_LO +FT_MR_PULSE1_H = APU_PL1_HI +FT_MR_PULSE2_V = APU_PL2_VOL +FT_MR_PULSE2_L = APU_PL2_LO +FT_MR_PULSE2_H = APU_PL2_HI +FT_MR_TRI_V = APU_TRI_LINEAR +FT_MR_TRI_L = APU_TRI_LO +FT_MR_TRI_H = APU_TRI_HI +FT_MR_NOISE_V = APU_NOISE_VOL +FT_MR_NOISE_F = APU_NOISE_LO + .else ;otherwise write to the output buffer +FT_MR_PULSE1_V = FT_OUT_BUF +FT_MR_PULSE1_L = FT_OUT_BUF+1 +FT_MR_PULSE1_H = FT_OUT_BUF+2 +FT_MR_PULSE2_V = FT_OUT_BUF+3 +FT_MR_PULSE2_L = FT_OUT_BUF+4 +FT_MR_PULSE2_H = FT_OUT_BUF+5 +FT_MR_TRI_V = FT_OUT_BUF+6 +FT_MR_TRI_L = FT_OUT_BUF+7 +FT_MR_TRI_H = FT_OUT_BUF+8 +FT_MR_NOISE_V = FT_OUT_BUF+9 +FT_MR_NOISE_F = FT_OUT_BUF+10 + .endif + + + +;------------------------------------------------------------------------------ +; reset APU, initialize FamiTone +; in: A 0 for PAL, not 0 for NTSC +; X,Y pointer to music data +;------------------------------------------------------------------------------ + +FamiToneInit: + + stx FT_SONG_LIST_L ;store music data pointer for further use + sty FT_SONG_LIST_H + stx 0 + ldx #FT_SFX_CH0 + jsr _FT2SfxUpdate + .endif + .if FT_SFX_STREAMS>1 + ldx #FT_SFX_CH1 + jsr _FT2SfxUpdate + .endif + .if FT_SFX_STREAMS>2 + ldx #FT_SFX_CH2 + jsr _FT2SfxUpdate + .endif + .if FT_SFX_STREAMS>3 + ldx #FT_SFX_CH3 + jsr _FT2SfxUpdate + .endif + + + ;send data from the output buffer to the APU + + lda FT_OUT_BUF ;pulse 1 volume + sta APU_PL1_VOL + lda FT_OUT_BUF+1 ;pulse 1 period LSB + sta APU_PL1_LO + lda FT_OUT_BUF+2 ;pulse 1 period MSB, only applied when changed + cmp FT_PULSE1_PREV + beq @no_pulse1_upd + sta FT_PULSE1_PREV + sta APU_PL1_HI +@no_pulse1_upd: + + lda FT_OUT_BUF+3 ;pulse 2 volume + sta APU_PL2_VOL + lda FT_OUT_BUF+4 ;pulse 2 period LSB + sta APU_PL2_LO + lda FT_OUT_BUF+5 ;pulse 2 period MSB, only applied when changed + cmp FT_PULSE2_PREV + beq @no_pulse2_upd + sta FT_PULSE2_PREV + sta APU_PL2_HI +@no_pulse2_upd: + + lda FT_OUT_BUF+6 ;triangle volume (plays or not) + sta APU_TRI_LINEAR + lda FT_OUT_BUF+7 ;triangle period LSB + sta APU_TRI_LO + lda FT_OUT_BUF+8 ;triangle period MSB + sta APU_TRI_HI + + lda FT_OUT_BUF+9 ;noise volume + sta APU_NOISE_VOL + lda FT_OUT_BUF+10 ;noise period + sta APU_NOISE_LO + + .endif + + .if(FT_THREAD) + pla + sta FT_TEMP_PTR_H + pla + sta FT_TEMP_PTR_L + .endif + + rts + + +;internal routine, sets up envelopes of a channel according to current instrument +;in X envelope group offset, A instrument number + +_FT2SetInstrument: + asl a ;instrument number is pre multiplied by 4 + tay + lda FT_INSTRUMENT_H + adc #0 ;use carry to extend range for 64 instruments + sta > 8) + 3, 0xc0 + palette_address, palette_state[palette_address]); +} + +void reset_palette_state() { + unsigned char i; + for (i = 0; i < 64; i++) { + palette_state[i] = 0; + } +} + +/* Player scores */ +static unsigned int player_score[2] = { 0 }; + +/** + * Calculate a player's score from map data. + */ +unsigned int score_player(unsigned char player_id) { + unsigned char mask; + unsigned char intermediate; + unsigned int score = 0; + unsigned char i; + mask = player_id + 1; + mask = ((mask << 2) | mask ); + mask = ((mask << 4) | mask ); + for (i = 0; i < 64; i++) { + intermediate = palette_state[i] ^ (~ mask); + intermediate = 0x55 & intermediate & (intermediate >> 1); + intermediate = (intermediate >> 4) + (intermediate & 0x0f); + score += (intermediate >> 2) + (intermediate & 0x03); + } + return score; +} + +/** + * Determine if a given map tile can be inked. + */ +unsigned char can_ink(unsigned char map_type) { + if (map_type == 0x2c || + map_type == 0x2d || + map_type == 0x3c || + map_type == 0x3d || + map_type == 0x2a || + map_type == 0x2b || + map_type == 0x3a || + map_type == 0x3b) { + return FALSE; + } + return TRUE; +} + +/* Make sure this stays a multiple of 2 */ +#define TITLE_ROLL_HEIGHT 110 + +/** + * Used on title and credits screens to + * delay while waiting for "START" to be pressed. + * + * Allows for skippable animations. + */ +#define WAIT_WITH_SKIP(w) \ + wait = w; \ + while (1) { \ + if (wait == 0) break; \ + wait--; \ + ppu_wait_frame(); \ + if ((pad_trigger(0) | pad_trigger(1)) & PAD_START) { \ + goto _skip_title; \ + } \ + } + +/** + * Show title screen. + */ +void show_title(void) { + /* Ensure we have the write CHR bank set for the title, and reset scroll to 0. */ + ppu_off(); + bank_bg(0); + scroll(0,TITLE_ROLL_HEIGHT); + + /* Load title screen into NAME A */ + vram_adr(NAMETABLE_A); + vram_write(splat_title,sizeof(splat_title)); + + /* Clear nametable C to avoid artifacts when bouncing. */ + vram_adr(NAMETABLE_C); + vram_fill(0,1024); + + pal_bright(4); + pal_bg(palTitleA); + ppu_on_bg(); + WAIT_WITH_SKIP(20); + + frame_cnt=0; + wait=10; + + /* Scroll */ + while (1) { + frame_cnt += 2; + scroll(0,TITLE_ROLL_HEIGHT-frame_cnt); + + if (frame_cnt == TITLE_ROLL_HEIGHT) break; + + ppu_wait_frame(); + + if ((pad_trigger(0) | pad_trigger(1)) & PAD_START) { + goto _skip_title; + } + } + + scroll(0,0); + + /* Splat splat splat */ + WAIT_WITH_SKIP(20); + sfx_play(SFX_ITEM,0); + pal_bg(palTitleB); + WAIT_WITH_SKIP(20); + sfx_play(SFX_ITEM,0); + pal_bg(palTitleC); + WAIT_WITH_SKIP(20); + sfx_play(SFX_ITEM,0); + pal_bg(palTitle); + WAIT_WITH_SKIP(20); + music_play(MUSIC_TITLE); + + pal_col(15,0x30); + + wait = 10; + frame_cnt = 0; + + while (1) { + + /* Flash start between white and gray. */ + wait--; + if (!wait) { + pal_col(15,(frame_cnt&1)?0x30:0x20); + wait = 10; + frame_cnt++; + } + + ppu_wait_frame(); + + /* Wait for input to start game. */ + if ((pad_trigger(0) | pad_trigger(1)) & PAD_START) { + break; + } + } + +_skip_title: + scroll(0,0); + pal_bg(palTitle); + + music_stop(); + + sfx_play(SFX_START,0); + + /* Blink rapidly. */ + for (i=0;i<16;++i) { + pal_col(15, (i & 1) ? 0x0f : 0x20); + delay(4); + } + +} + +/* Where numbers start in the EBCDIC tileset */ +#define NUM_START 0xB0 + +/** + * Put a number into the vram nametable when not rendering. + * Cheaper than an update table, but only use this when + * initializing VRAM and not during play. + */ +void put_num(unsigned int adr,unsigned int num,unsigned char len) { + vram_adr(adr); + + if (len>2) vram_put(NUM_START+(num/100)%10); + if (len>1) vram_put(NUM_START+(num/10)%10); + vram_put(NUM_START+(num%10)); +} + +/** + * Print a string (EBCDIC) into VRAM. + * Use only between frames! + */ +void print_str(unsigned int adr, const unsigned char * str) { + vram_adr(adr); + while (*str) { + vram_put(*str); + str++; + } +} + +/** + * Map select screen. + */ +void show_select() { + /* Use bank 1 to get full characterset tiles */ + bank_bg(1); + bank_spr(1); + music_play(MUSIC_STAGE_SELECT); + + while (1) { + /* We disable the PPU while we draw text. */ + ppu_off(); + pal_bg(palEndgame); + + /* We don't use an existing nametable, but instead clear out NAMETABLE_A */ + vram_adr(NAMETABLE_A); + vram_fill(0xa0,1024-64); + vram_fill(0,64); + + /* "Select Map" */ + print_str(NAMETABLE_A+0x0EB,select_map); + + /* Map names */ + for (i = 0; i < LEVELS_ALL; ++i) { + print_str(NAMETABLE_A+0x148+0x20*i,levelList[i*LEVEL_ENTRY+3]); + } + + /* + * An asterisk represents the current selection. + * TODO: use something nicer in 1.1 + */ + print_str(NAMETABLE_A+0x146+0x20*game_level,selector); + ppu_on_bg(); + + /* Loop waiting for input. */ + while (1) { + ppu_wait_frame(); + j = pad_trigger(0) | pad_trigger(1); + /* Start - Select map */ + if (j & PAD_START) return; + /* Up - move cursor up */ + if (j & PAD_UP) { + if (game_level == 0) { + game_level = LEVELS_ALL-1; + } else { + game_level -= 1; + } + + break; + } + /* Select or Down - move cursor down */ + if (j & PAD_SELECT || j & PAD_DOWN) { + game_level += 1; + if (game_level == LEVELS_ALL) game_level = 0; + break; + } + } + + } +} + +/** + * Credits sequence. + */ +void show_credits() { + bank_bg(1); + bank_spr(1); + + /* Clear the screen. */ + ppu_off(); + pal_bg(palEndgame); + + /* Write credits. */ + i = 0; + + while (i < 17) { /* 4 6 A C */ + ppu_off(); + vram_adr(NAMETABLE_A); + vram_fill(0xa0,1024-64); + vram_fill(0,64); + ppu_on_bg(); + + /* + * This works much the same as the map select screen. + * + * We turn off the PPU and render text. Then we'll delay + * a bit before writing the next line. + * + * We show four lines per screen, which usually means + * two people, with their titles. + */ + + ppu_off(); + print_str(NAMETABLE_A+0x122, credits[i]); + ppu_on_bg(); + WAIT_WITH_SKIP(50); + + ppu_off(); + print_str(NAMETABLE_A+0x162, credits[i+1]); + ppu_on_bg(); + WAIT_WITH_SKIP(50); + + ppu_off(); + print_str(NAMETABLE_A+0x1C2, credits[i+2]); + ppu_on_bg(); + WAIT_WITH_SKIP(50); + + ppu_off(); + print_str(NAMETABLE_A+0x202, credits[i+3]); + ppu_on_bg(); + WAIT_WITH_SKIP(50); + i+=4; + } + WAIT_WITH_SKIP(200); + +_skip_title: + delay(20); +} + +/** + * Post Game Screen + * + * Shows Judd pointing to the winner, + * inked % of map, total inked cells, + * and a gauge. + */ +void show_endgame(void) { + bank_bg(1); + bank_spr(1); + + /* Set up the background (meter, "Game Over") */ + ppu_off(); + vram_adr(NAMETABLE_A); + vram_write(endgame,1024); + pal_bg(palEndgame); + pal_spr(palJudd); + oam_clear(); + + /* We're going to use the update lists to set background palettes */ + clear_update_list(); + + /* Give players with no points a freebie to help with the math. */ + if (player_score[0] == 0) player_score[0] = 1; + if (player_score[1] == 0) player_score[1] = 1; + + /* + * We calculate percentages and bar gauge based on total inked + * not total available for inking. This is a bit different from + * the real deal. + */ + sum = (player_score[0] + player_score[1]); + + /* Calculate percentage for player 1 */ + div = player_score[0] * 100; + div /= sum; + if (div == 100) div = 99; + if (div == 0) div = 1; + put_num(NAMETABLE_A+0x1EA,div,2); + + /* Player 2 must be 100% - (player 1) */ + div = 100 - div; + put_num(NAMETABLE_A+0x1F4,div,2); + + /* Convert Player 2's percentage to a gauge width */ + div *= 9; + div /= 100; + + /* Print the victory message. */ + if (player_score[0] > player_score[1]) { + print_str(NAMETABLE_A+0x1C9,victoryMsg); + oam_meta_spr(0x68,0x48,0,judd_left); + } else if (player_score[0] == player_score[1]) { + /* If both players have the same score, it was a tie. */ + print_str(NAMETABLE_A+0x1CB,tieMsg); + oam_meta_spr(0x70,0x48,0,judd_tie); + } else { + print_str(NAMETABLE_A+0x1CF,victoryMsg); + oam_meta_spr(0x70,0x48,0,judd_right); + } + + /* Print raw player scores below the gauge */ + put_num(NAMETABLE_A+0x24A,player_score[0],3); + put_num(NAMETABLE_A+0x253,player_score[1],3); + + /* Enable the background */ + ppu_on_all(); + + /* Play the post-game music. */ + music_play(MUSIC_WELL_DONE); + + /* Set the gauge palettes. */ + clear_update_list(); + for (i = 4; i < 12 - div; ++i) { + /* Player 1 on the left. */ + set_tile_palette(i,8,1); + } + for (i = 12 - div; i <= 11; ++i) { + /* Player 2 on the right. */ + set_tile_palette(i,8,2); + + } + set_vram_update(update_list); + + while (1) { + /* Wait for someone to hit start. */ + ppu_wait_frame(); + clear_update_list(); + if ((pad_trigger(0) | pad_trigger(1)) & PAD_START) break; + } + reset_palette_state(); + oam_clear(); +} + +/* + * Move a projectile if the is no wall + */ +void projectile_move(unsigned char id) { + unsigned char map_type = 0; + unsigned char dir = projectile_dir[id]; + + /* + * Reset speed; if the last direction we check is valid, we'll set speed, but we + * shouldn't let players input a valid direction that sets speed plus a higher priority + * invalid direction to let them move in the invalid direction + */ + projectile_cnt[id]=0; + projectile_dist[id]-=1; + + if (projectile_dist[id] == 0) { + projectile_dir[id]=DIR_NONE; + return; + } + + px=projectile_x[id]>>(TILE_SIZE_BIT+FP_BITS); + py=projectile_y[id]>>(TILE_SIZE_BIT+FP_BITS); + + switch (dir) { + case DIR_NONE: return; break; + case DIR_LEFT: --px; break; + case DIR_RIGHT: ++px; break; + case DIR_UP: --py; break; + case DIR_DOWN: ++py; break; + } + + + if (px > MAP_WDT-1) { + projectile_dir[id]=DIR_NONE; + return; + } + + if (py > MAP_HGT-1) { + projectile_dir[id]=DIR_NONE; + return; + } + + map_type = map[MAP_ADR(px, py)]; + + if (can_ink(map_type)) { + set_tile_palette(px, py, id+1); + } + + if ((map_type >= 0x22 && map_type <= 0x29) || (map_type >= 0x32 && map_type <= 0x39)) { + projectile_dir[id]=DIR_NONE; + return; + } + + projectile_cnt[id]=TILE_SIZE<>(TILE_SIZE_BIT+FP_BITS); + py=player_y[id]>>(TILE_SIZE_BIT+FP_BITS); + + switch (dir) { + case DIR_LEFT: --px; break; + case DIR_RIGHT: ++px; break; + case DIR_UP: --py; break; + case DIR_DOWN: ++py; break; + } + + + if (px > MAP_WDT-1) { + return; + } + + if (py > MAP_HGT-1) { + return; + } + + /* + * Wall tiles: + * 0x22~0x29 + * 0x32~0x39 + */ + map_type = map[MAP_ADR(px, py)]; + + if (can_ink(map_type)) { + set_tile_palette(px, py, id+1); + } + + if ((map_type >= 0x22 && map_type <= 0x29) || (map_type >= 0x32 && map_type <= 0x39)) { + return; + } + + player_cnt[id]=TILE_SIZE<>FP_BITS; + + if (player_wait[i]) { + if (player_wait[i]>=16||player_wait[i]&2) py=240; + } + + px = player_x[i]>>FP_BITS; + + anim_index = i * WALK_CYCLE + (player_anim_cnt[i] / FRAMES_PER_STEP) % WALK_CYCLE; + + switch (player_dir[i]) { + case DIR_NONE: + case DIR_DOWN: oam_meta_spr(px,py,spr,sprListPlayerDown[anim_index]); break; + case DIR_LEFT: oam_meta_spr(px,py,spr,sprListPlayerLeft[anim_index]); break; + case DIR_RIGHT: oam_meta_spr(px,py,spr,sprListPlayerRight[anim_index]); break; + case DIR_UP: oam_meta_spr(px,py,spr,sprListPlayerUp[anim_index]); break; + } + spr-=16; + } + + /* Wait for the next frame. */ + ppu_wait_frame(); + clear_update_list(); + + /* Tick the timer */ + ++frame_cnt; + if (!game_paused && (frame_cnt % TIMER_CYCLE == 0)) { + timer--; + } + /* And update it on screen. */ + insert_into_update_list(0x20,0x4f,timer/10 + 0xb0); + insert_into_update_list(0x20,0x50,timer%10 + 0xb0); + + + /* Read both inputs for "START" in trigger mode. */ + i = pad_trigger(0); + i |= pad_trigger(1); + + /* Pause the game if someone hit start. */ + if (i & PAD_START) { + game_paused ^= TRUE; + if (game_paused) { + /* When the game is paused, we switch to a grayscale palette */ + pal_bg(palPaused); + pal_spr(palCharPaused); + } else { + /* Switch back to level palette. */ + pal_bg(levelList[game_level*LEVEL_ENTRY+1]); + pal_spr(levelList[game_level*LEVEL_ENTRY+2]); + } + music_pause(game_paused); + sfx_play(SFX_ITEM,0); + } + + /* Skip processing inputs when the game is paused. */ + if (game_paused) continue; + + /* + * When players spawn, they flash a bit. + * We don't start the music until they are done flashing. + */ + if (wait) { + --wait; + + if (!wait) { + music_play(MUSIC_GAME); + } + } + + /* When the timer reaches 0, the game is over. */ + if (timer == 0) { + music_play(MUSIC_CLEAR); + game_done = TRUE; + } + + /* + * Process player actions. + */ + for (i = 0; i < player_all; ++i) { + /* Flash respawning players, and prevent them from providing input. */ + if (player_wait[i]) { + if (player_wait[i] == 16) { + sfx_play(i?SFX_RESPAWN2:SFX_RESPAWN1,i); + } + --player_wait[i]; + continue; + } + + if (wait) continue; /* Avoid processing input during initial spawn. */ + + /* This player is moving, so animate their movement. */ + if (player_cnt[i]) { + switch (player_dir[i]) { + case DIR_RIGHT: player_x[i]+=player_speed[i]; break; + case DIR_LEFT: player_x[i]-=player_speed[i]; break; + case DIR_DOWN: player_y[i]+=player_speed[i]; break; + case DIR_UP: player_y[i]-=player_speed[i]; break; + } + + player_cnt[i]-=player_speed[i]; + + /* Finish movement. */ + if (player_cnt[i] <= 0) { + if (player_cnt[i] < 0) { + player_cnt[i] = 0; + + /* Align player to grid. */ + player_x[i]=(player_x[i]&0xff00)+(player_dir[i]==DIR_LEFT?0x100:0); + player_y[i]=(player_y[i]&0xff00)+(player_dir[i]==DIR_UP ?0x100:0); + } + + } else { + /* Continue animating movement. */ + player_anim_cnt[i] += 1; + } + } + + /* No current movement, accept input. */ + if (!player_cnt[i]) { + + /* Read pad state. */ + j = pad_state(i); + + if (player_cooldown[i]) { + player_cooldown[i] -= 1; + } + + if (j & player_dir[i] && player_diag_flip[i]) { + /* Give priority new new direction (useful for cornering) */ + j &= ~player_dir[i]; + player_diag_flip[i] = 0; + player_move(i, player_dir[i]); + } + + if (j&PAD_LEFT) player_move(i,DIR_LEFT); + if (j&PAD_RIGHT) player_move(i,DIR_RIGHT); + if (j&PAD_UP) player_move(i,DIR_UP); + if (j&PAD_DOWN) player_move(i,DIR_DOWN); + if (j&PAD_A) player_make_projectile(i); + } + + /* If this player has a projectile, move it as well. */ + if (projectile_cnt[i]) { + if (projectile_cnt[i] <= 0) { + if (projectile_cnt[i] < 0) { + projectile_cnt[i] = 0; + + /* Projectiles also lock to tiles, like players. */ + + projectile_x[i]=(projectile_x[i]&0xff00)+(projectile_dir[i]==DIR_LEFT?0x100:0); + projectile_y[i]=(projectile_y[i]&0xff00)+(projectile_dir[i]==DIR_UP ?0x100:0); + } + } + } + + if (!projectile_cnt[i]) { + projectile_move(i); + } + + if (projectile_cnt[i]) { + switch (projectile_dir[i]) { + case DIR_RIGHT: projectile_x[i]+=projectile_speed[i]; break; + case DIR_LEFT: projectile_x[i]-=projectile_speed[i]; break; + case DIR_DOWN: projectile_y[i]+=projectile_speed[i]; break; + case DIR_UP: projectile_y[i]-=projectile_speed[i]; break; + } + + projectile_cnt[i]-=projectile_speed[i]; + } + + } + + /* Kill players that collide with eachother. */ + for (i = 0; i < player_all; ++i) { + for (j = i + 1; j < player_all; ++j) { + if (player_x[i] == player_x[j] && player_y[i] == player_y[j]) { + /* + * Since all players have rollers and move at the same speed, if you + * share a space you must have run into each other, so you both die. + */ + player_die(i); + player_die(j); + } + if (projectile_dir[j] != DIR_NONE && + (player_x[i] >> (TILE_SIZE_BIT+FP_BITS)) == (projectile_x[j] >> (TILE_SIZE_BIT+FP_BITS)) && + (player_y[i] >> (TILE_SIZE_BIT+FP_BITS)) == (projectile_y[j] >> (TILE_SIZE_BIT+FP_BITS))) { + /* Player j kills player i using a projectile */ + player_die(i); + } + if (projectile_dir[i] != DIR_NONE && + (player_x[j] >> (TILE_SIZE_BIT+FP_BITS)) == (projectile_x[i] >> (TILE_SIZE_BIT+FP_BITS)) && + (player_y[j] >> (TILE_SIZE_BIT+FP_BITS)) == (projectile_y[i] >> (TILE_SIZE_BIT+FP_BITS))) { + /* Player i kills player j using a projectile */ + player_die(j); + } + } + } + + /* Kill players that fall in water. */ + for ( i = 0; i < player_all; ++i) { + px = player_x[i] >> (TILE_SIZE_BIT + FP_BITS); + py = player_y[i] >> (TILE_SIZE_BIT + FP_BITS); + map_type = map[MAP_ADR(px, py)]; + /* Water tiles are 0x2c, 0x2d, 0x3c, 0x3d */ + if (map_type == 0x2c || map_type == 0x2d || map_type == 0x3c || map_type == 0x3d) { + player_die(i); + } + } + } + + /* Game is over, calculate score. */ + for (i = 0; i < player_all; ++i) { + player_score[i] = score_player(i); + } + + reset_palette_state(); + delay(100); +} + + + +void main(void) { + while (1) { + /* Show the main title. */ + show_title(); + + /* Select a map. */ + show_select(); + + /* Start the game. */ + game_loop(); + + /* Show the final scores. */ + show_endgame(); + + /* Play the credits. */ + show_credits(); + + /* Loop back to the title... */ + } +} diff --git a/levels/bluefin.h b/levels/bluefin.h new file mode 100644 index 0000000..19b829f --- /dev/null +++ b/levels/bluefin.h @@ -0,0 +1,40 @@ +const unsigned char bluefin_depot[ 1024 ] = { +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x22,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x26,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x22,0x29,0x24,0x25,0x28,0x29,0x28,0x23,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x32,0x39,0x38,0x39,0x34,0x35,0x38,0x33,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x32,0x33,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x3c,0x3d, +0x11,0x2b,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x10,0x2b, +0x3a,0x3b,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x3a,0x3b, +0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x22,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x26,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x22,0x29,0x24,0x25,0x28,0x29,0x28,0x23,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x32,0x39,0x38,0x39,0x34,0x35,0x38,0x33,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x32,0x33,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, + +0xff,0xff,0x0f,0x0f,0x0f,0x0f,0xff,0xff, +0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff, +0x3f,0x03,0x30,0x00,0x00,0xc0,0x0c,0xcf, +0x13,0x33,0xc3,0xfc,0xf3,0x3c,0xcc,0x8c, +0x33,0x03,0x33,0x0c,0x03,0xcc,0x0c,0xcc, +0xff,0xf3,0x00,0x00,0x00,0x00,0xfc,0xff, +0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff, +0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f }; diff --git a/levels/endgame.h b/levels/endgame.h new file mode 100644 index 0000000..0285432 --- /dev/null +++ b/levels/endgame.h @@ -0,0 +1 @@ +const unsigned char endgame[ 1024 ] = { 0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xc7,0xe1,0xed,0xe5,0xa0,0xef,0xf6,0xe5,0xf2,0xa1,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa5,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa5,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0x22,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x23,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0x32,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x33,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xb1,0xb2,0xb3,0xf0,0xa0,0xa0,0xa0,0xa0,0xa0,0xb0,0xb1,0xb2,0xf0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,0x05,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; diff --git a/levels/kelpdome.h b/levels/kelpdome.h new file mode 100644 index 0000000..a2dd7a9 --- /dev/null +++ b/levels/kelpdome.h @@ -0,0 +1,40 @@ +const unsigned char kelpdome[ 1024 ] = { +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31, +0x2c,0x2d,0x22,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x23,0x20,0x21,0x20,0x21,0x10,0x2b,0x20,0x21, +0x3c,0x3d,0x26,0x35,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x34,0x27,0x30,0x31,0x30,0x31,0x3a,0x3b,0x30,0x31, +0x2c,0x2d,0x36,0x37,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x3c,0x3d,0x26,0x37,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x32,0x33,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31, +0x2c,0x2d,0x36,0x37,0x20,0x21,0x22,0x23,0x20,0x21,0x22,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x3c,0x3d,0x26,0x37,0x30,0x31,0x32,0x33,0x30,0x31,0x26,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31, +0x2c,0x2d,0x36,0x37,0x20,0x21,0x20,0x21,0x20,0x21,0x36,0x25,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x23,0x20,0x21,0x20,0x21,0x22,0x28,0x29,0x23,0x2c,0x2d, +0x3c,0x3d,0x26,0x37,0x30,0x31,0x30,0x31,0x30,0x31,0x32,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x34,0x27,0x30,0x31,0x30,0x31,0x32,0x38,0x34,0x27,0x3c,0x3d, +0x2c,0x2d,0x36,0x37,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x2c,0x2d, +0x3c,0x3d,0x26,0x37,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x27,0x3c,0x3d, +0x2c,0x2d,0x36,0x37,0x20,0x21,0x22,0x28,0x29,0x28,0x29,0x23,0x20,0x21,0x22,0x28,0x29,0x23,0x20,0x21,0x26,0x25,0x28,0x29,0x28,0x23,0x20,0x21,0x26,0x27,0x2c,0x2d, +0x3c,0x3d,0x26,0x37,0x30,0x31,0x32,0x38,0x39,0x38,0x34,0x27,0x30,0x31,0x32,0x38,0x39,0x33,0x30,0x31,0x32,0x38,0x39,0x38,0x39,0x33,0x30,0x31,0x36,0x27,0x3c,0x3d, +0x2c,0x2d,0x36,0x37,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x2c,0x2d, +0x3c,0x3d,0x26,0x37,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x27,0x3c,0x3d, +0x2c,0x2d,0x36,0x25,0x28,0x23,0x20,0x21,0x20,0x21,0x26,0x25,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x2c,0x2d, +0x3c,0x3d,0x32,0x38,0x39,0x33,0x30,0x31,0x30,0x31,0x32,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x34,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x27,0x3c,0x3d, +0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x22,0x23,0x20,0x21,0x26,0x27,0x2c,0x2d, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x32,0x33,0x30,0x31,0x32,0x33,0x30,0x31,0x36,0x27,0x3c,0x3d, +0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x22,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x2c,0x2d, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x26,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x27,0x3c,0x3d, +0x20,0x21,0x11,0x2b,0x20,0x21,0x20,0x21,0x36,0x25,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x28,0x29,0x24,0x27,0x2c,0x2d, +0x30,0x31,0x3a,0x3b,0x30,0x31,0x30,0x31,0x32,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x38,0x39,0x33,0x3c,0x3d, +0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, + +0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x0f, +0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x01, +0x33,0x00,0x00,0x00,0x00,0x00,0x00,0xc0, +0x33,0x00,0x00,0x00,0x00,0x00,0x00,0xcc, +0x33,0x00,0x00,0x00,0x00,0x00,0x00,0xcc, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcc, +0x08,0x00,0xf0,0xf0,0xf0,0xf0,0xf0,0xfc, +0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f }; diff --git a/levels/saltspray.h b/levels/saltspray.h new file mode 100644 index 0000000..c2040d2 --- /dev/null +++ b/levels/saltspray.h @@ -0,0 +1,40 @@ +const unsigned char saltspray[ 1024 ] = { +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x10,0x2b,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3a,0x3b,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x22,0x28,0x29,0x23,0x20,0x21, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x26,0x35,0x34,0x27,0x30,0x31, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x36,0x25,0x24,0x37,0x20,0x21, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x32,0x38,0x39,0x33,0x30,0x31, +0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31, +0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x22,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x26,0x27,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x20, +0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x36,0x25,0x28,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x26,0x35,0x38,0x33,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x20, +0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x20,0x21,0x36,0x37,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x30,0x31,0x32,0x33,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x20, +0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x22,0x28,0x29,0x23,0x20,0x21, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x26,0x35,0x34,0x27,0x30,0x31, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x20,0x21,0x36,0x25,0x24,0x37,0x20,0x21, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x30,0x31,0x32,0x38,0x39,0x33,0x30,0x31, +0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31, +0x11,0x2b,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3a,0x3b,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, + +0x1f,0xff,0x0f,0x0f,0xcf,0xff,0xff,0xff, +0xf0,0xf0,0xcc,0x3f,0x0c,0xcf,0x00,0x00, +0x0f,0xff,0x0c,0x33,0x00,0xcc,0x00,0x00, +0x00,0x0f,0x03,0x33,0x00,0x00,0x00,0x00, +0x00,0xff,0x03,0x33,0x00,0xc0,0x00,0x00, +0xff,0xff,0xcc,0x33,0x00,0xcc,0x00,0x00, +0x20,0xf0,0x0c,0x0f,0xcc,0xff,0xf0,0xf0, +0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f }; diff --git a/levels/splat_title.h b/levels/splat_title.h new file mode 100644 index 0000000..d658ca4 --- /dev/null +++ b/levels/splat_title.h @@ -0,0 +1,37 @@ +const unsigned char splat_title[1024]={ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x05,0x00,0x06,0x00,0x07,0x08,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x0a,0x0b,0x00,0x0c,0x0d,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x02,0x00,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x19,0x1a,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d,0x1e,0x1f,0x20,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x03,0x21,0x22,0x23,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x26,0x27,0x28,0x00,0x00, + 0x00,0x00,0x00,0x00,0x04,0x05,0x00,0x29,0x2a,0x2b,0x2b,0x2c,0x2d,0x00,0x2e,0x2f,0x30,0x31,0x32,0x33,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1d,0x34,0x35,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x09,0x36,0x2b,0x2b,0x2b,0x2b,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x1c,0x1c,0x41,0x42,0x43,0x1c,0x1c,0x44,0x45,0x00,0x00, + 0x00,0x00,0x0e,0x02,0x00,0x46,0x47,0x2b,0x2b,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x1c,0x5a,0x5b,0x5c,0x5d, + 0x00,0x00,0x18,0x19,0x1a,0x5e,0x5f,0x2b,0x2b,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x02,0x73,0x74,0x75, + 0x00,0x00,0x00,0x25,0x1c,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x1c,0x8b,0x8c,0x8d,0x8e,0x00, + 0x30,0x31,0x8f,0x90,0x1c,0x1c,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x00,0x9e,0x9f,0xa0,0x1c,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0x00, + 0xa8,0x00,0x00,0xa9,0x1c,0x1c,0x1c,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0x00,0x00,0x00, + 0xba,0xbb,0xbc,0xbd,0x1c,0x1c,0x1c,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0x5b,0x5c,0x5d,0x00,0x00,0x00,0xc4,0xc5,0xc6,0xc7,0x00,0xc8,0xc9,0x00,0x00,0x00,0x00,0x00,0x00, + 0xca,0xcb,0xcc,0xcd,0xce,0x1c,0x1c,0xcf,0xd0,0xd1,0xd2,0xd3,0x02,0x73,0x74,0x75,0x00,0x00,0x00,0xd4,0xd5,0x00,0x00,0x00,0xd6,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xd7,0xd8,0x00,0xd9,0xda,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x8b,0x8c,0x8d,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x9e,0x9f,0xa0,0x1c,0x1c,0xdc,0xa3,0xa4,0xa5,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xc4,0xc5,0xc6,0xc7,0x00,0xc8,0xc9,0x00,0x00,0x00,0xe0,0xe1,0xe2,0xe3,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xd4,0xd5,0x00,0x00,0x00,0xd6,0x00,0x00,0x00,0x00,0x00,0xe3,0xe4,0xe5,0xe1,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x05,0x00,0x06,0x00,0x07,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x0a,0x0b,0x00,0x0c,0x0d,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x02,0x00,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x19,0x1a,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d,0x1e,0x1f,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x26,0x27,0x28,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdd,0x30,0x31,0x8f,0x90,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1d,0x34,0x35,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xde,0xa8,0x00,0x00,0xa9,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x44,0x45,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xba,0xbb,0xbc,0xbd,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x5a,0x5b,0x5c, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xcb,0xcc,0xcd,0xce,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x72,0x02,0x73,0x74, + + 0x0,0x30,0x0,0x0,0x55,0x55,0x55,0x5d,0xc,0x0,0x0,0x4c,0x57,0x55,0x55,0xd5,0x0,0x0,0x0,0x4c,0x55,0x55,0x55,0x55,0x0,0x0,0x0,0x0,0x77,0x55,0x55,0xd5,0x0,0x0,0xc0, + 0xfc,0xff,0xff,0xbf,0xaa,0xc0,0xfc,0x3f,0xcf,0xaf,0xaa,0xaa,0xaa,0xcc,0x0,0x80,0xaf,0xaa,0xaa,0xaa,0xaa,0x0,0x0,0x8,0xa,0xa,0xa,0xa,0xa +}; + + diff --git a/levels/twofish.h b/levels/twofish.h new file mode 100644 index 0000000..510d533 --- /dev/null +++ b/levels/twofish.h @@ -0,0 +1,40 @@ +const unsigned char twofish[ 1024 ] = { +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x22,0x23,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x22,0x23,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x36,0x37,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x37,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x26,0x27,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x26,0x27,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x36,0x37,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x36,0x37,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x26,0x27,0x20,0x21,0x22,0x29,0x28,0x29,0x28,0x23,0x20,0x21,0x20,0x21,0x22,0x29,0x28,0x29,0x28,0x23,0x20,0x21,0x26,0x27,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x32,0x33,0x30,0x31,0x32,0x38,0x39,0x38,0x34,0x37,0x30,0x31,0x30,0x31,0x36,0x35,0x39,0x38,0x39,0x33,0x30,0x31,0x32,0x33,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x37,0x30,0x31,0x30,0x31,0x36,0x37,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x11,0x2b,0x26,0x27,0x20,0x21,0x20,0x21,0x26,0x27,0x10,0x2b,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3a,0x3b,0x36,0x37,0x30,0x31,0x30,0x31,0x36,0x37,0x3a,0x3b,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x36,0x37,0x30,0x31,0x30,0x31,0x36,0x37,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x22,0x23,0x20,0x21,0x22,0x29,0x28,0x29,0x24,0x27,0x20,0x21,0x20,0x21,0x26,0x25,0x28,0x29,0x28,0x23,0x20,0x21,0x22,0x23,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x36,0x37,0x30,0x31,0x32,0x38,0x39,0x38,0x39,0x33,0x30,0x31,0x30,0x31,0x32,0x38,0x39,0x38,0x39,0x33,0x30,0x31,0x36,0x37,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x26,0x27,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x20,0x21,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x20,0x21,0x26,0x27,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x36,0x37,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x30,0x31,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x30,0x31,0x36,0x37,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x26,0x27,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x26,0x27,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x32,0x33,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x32,0x33,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x20,0x21,0x2c,0x2d, +0x3c,0x3d,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x31,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, +0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d,0x2c,0x2d, +0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d,0x3c,0x3d, + +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0x33,0x00,0x00,0x00,0x00,0x00,0x00,0xcc, +0x33,0x00,0x0f,0x03,0x0c,0x0f,0x00,0xcc, +0x33,0x00,0x40,0x00,0x00,0x20,0x00,0xcc, +0x33,0x00,0x00,0x00,0x00,0x00,0x00,0xcc, +0x33,0x00,0x0f,0x03,0x0c,0x0f,0x00,0xcc, +0xf3,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xfc, +0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f }; diff --git a/music.s b/music.s new file mode 100644 index 0000000..92cf279 --- /dev/null +++ b/music.s @@ -0,0 +1,653 @@ +;this file for FamiTone2 library generated by text2data tool + +fork_music_data: + .byte 7 + .word @instruments + .word @samples-3 + .word @song0ch0,@song0ch1,@song0ch2,@song0ch3,@song0ch4,307,256 + .word @song1ch0,@song1ch1,@song1ch2,@song1ch3,@song1ch4,245,204 + .word @song2ch0,@song2ch1,@song2ch2,@song2ch3,@song2ch4,307,256 + .word @song3ch0,@song3ch1,@song3ch2,@song3ch3,@song3ch4,307,256 + .word @song4ch0,@song4ch1,@song4ch2,@song4ch3,@song4ch4,204,170 + .word @song5ch0,@song5ch1,@song5ch2,@song5ch3,@song5ch4,307,256 + .word @song6ch0,@song6ch1,@song6ch2,@song6ch3,@song6ch4,280,233 + +@instruments: + .byte $30 ;instrument $00 + .word @env1,@env0,@env0 + .byte $00 + .byte $30 ;instrument $01 + .word @env2,@env13,@env0 + .byte $00 + .byte $30 ;instrument $02 + .word @env3,@env14,@env0 + .byte $00 + .byte $30 ;instrument $03 + .word @env4,@env15,@env0 + .byte $00 + .byte $30 ;instrument $04 + .word @env5,@env16,@env0 + .byte $00 + .byte $70 ;instrument $05 + .word @env6,@env17,@env0 + .byte $00 + .byte $30 ;instrument $06 + .word @env7,@env18,@env24 + .byte $00 + .byte $30 ;instrument $07 + .word @env8,@env0,@env0 + .byte $00 + .byte $30 ;instrument $08 + .word @env9,@env0,@env0 + .byte $00 + .byte $30 ;instrument $09 + .word @env9,@env0,@env0 + .byte $00 + .byte $70 ;instrument $0a + .word @env9,@env0,@env0 + .byte $00 + .byte $b0 ;instrument $0b + .word @env9,@env0,@env0 + .byte $00 + .byte $b0 ;instrument $0c + .word @env9,@env0,@env0 + .byte $00 + .byte $30 ;instrument $0d + .word @env10,@env0,@env0 + .byte $00 + .byte $70 ;instrument $0e + .word @env10,@env0,@env0 + .byte $00 + .byte $70 ;instrument $0f + .word @env11,@env0,@env0 + .byte $00 + .byte $30 ;instrument $10 + .word @env1,@env19,@env25 + .byte $00 + .byte $30 ;instrument $11 + .word @env1,@env20,@env0 + .byte $00 + .byte $b0 ;instrument $12 + .word @env9,@env21,@env0 + .byte $00 + .byte $30 ;instrument $14 + .word @env12,@env22,@env0 + .byte $00 + .byte $70 ;instrument $15 + .word @env5,@env23,@env0 + .byte $00 + .byte $b0 ;instrument $16 + .word @env5,@env23,@env0 + .byte $00 + .byte $70 ;instrument $17 + .word @env5,@env23,@env0 + .byte $00 + +@samples: +@env0: + .byte $c0,$00,$00 +@env1: + .byte $cf,$00,$00 +@env2: + .byte $c7,$c1,$c2,$c3,$c4,$c5,$c6,$c6,$c5,$02,$c4,$02,$c3,$02,$c2,$02 + .byte $c1,$02,$c0,$00,$12 +@env3: + .byte $c7,$c4,$c2,$c1,$c1,$c0,$00,$05 +@env4: + .byte $c9,$c6,$c5,$c4,$c3,$c3,$c2,$02,$c1,$03,$c0,$00,$0a +@env5: + .byte $c6,$c5,$c5,$c4,$c4,$c3,$c4,$c6,$c5,$c4,$c3,$c3,$c2,$00,$0c +@env6: + .byte $cb,$cb,$c8,$c7,$c5,$c5,$c1,$04,$c0,$00,$08 +@env7: + .byte $cf,$06,$c0,$00,$02 +@env8: + .byte $cf,$c0,$00,$01 +@env9: + .byte $c4,$c7,$02,$c6,$c5,$00,$04 +@env10: + .byte $c8,$c6,$02,$c5,$00,$03 +@env11: + .byte $c4,$00,$00 +@env12: + .byte $c7,$c7,$ca,$02,$c9,$c7,$c6,$c4,$c2,$00,$08 +@env13: + .byte $c0,$c4,$00,$01 +@env14: + .byte $c0,$c2,$c4,$00,$02 +@env15: + .byte $c0,$c7,$c9,$cb,$00,$03 +@env16: + .byte $c0,$c2,$05,$c0,$c2,$c4,$00,$05 +@env17: + .byte $c0,$c4,$bc,$00,$02 +@env18: + .byte $ea,$e3,$dd,$da,$d6,$d4,$d1,$00,$06 +@env19: + .byte $c0,$bf,$be,$00,$02 +@env20: + .byte $c0,$c1,$c1,$c2,$c2,$c3,$c3,$c4,$c4,$c5,$c5,$c6,$c6,$c7,$c7,$c8 + .byte $c8,$c9,$c9,$ca,$ca,$cb,$cb,$cc,$cc,$00,$18 +@env21: + .byte $c0,$c0,$c7,$c7,$c0,$c0,$c7,$c7,$c0,$c0,$00,$09 +@env22: + .byte $c0,$c3,$c8,$00,$00 +@env23: + .byte $c0,$c0,$cc,$cc,$00,$00 +@env24: + .byte $ac,$00,$00 +@env25: + .byte $c0,$c0,$c1,$c2,$c4,$c7,$cc,$d1,$00,$07 + + +@song0ch0: + .byte $fb,$04 +@song0ch0loop: +@ref0: + .byte $a0,$4a,$83,$00,$4a,$83,$00,$ef + .byte $fd + .word @song0ch0loop + +@song0ch1: +@song0ch1loop: +@ref1: + .byte $f9,$85 + .byte $fd + .word @song0ch1loop + +@song0ch2: +@song0ch2loop: +@ref2: + .byte $f9,$85 + .byte $fd + .word @song0ch2loop + +@song0ch3: +@song0ch3loop: +@ref3: + .byte $f9,$85 + .byte $fd + .word @song0ch3loop + +@song0ch4: +@song0ch4loop: +@ref4: + .byte $f9,$85 + .byte $fd + .word @song0ch4loop + + +@song1ch0: + .byte $fb,$04 +@song1ch0loop: +@ref5: + .byte $9c,$2d,$33,$37,$2c,$8b,$00,$9a,$28,$85,$28,$85,$34,$8f,$00,$9c + .byte $2d,$33,$37,$2c,$8b,$00,$9a,$28,$85,$28,$85,$22,$91 + .byte $ff,$19 + .word @ref5 + .byte $ff,$19 + .word @ref5 + .byte $ff,$19 + .word @ref5 +@ref9: + .byte $90,$49,$96,$4f,$53,$98,$48,$8b,$00,$90,$44,$85,$98,$44,$85,$92 + .byte $50,$8f,$00,$90,$49,$4f,$94,$53,$90,$48,$8b,$00,$44,$85,$98,$44 + .byte $85,$92,$3e,$87,$00,$87 + .byte $ff,$1b + .word @ref9 + .byte $fd + .word @song1ch0loop + +@song1ch1: +@song1ch1loop: +@ref11: + .byte $81,$9a,$2d,$33,$37,$2c,$89,$00,$9c,$1e,$85,$1e,$85,$12,$8f,$01 + .byte $9a,$2d,$33,$37,$2c,$89,$00,$9c,$1e,$85,$1e,$85,$18,$91 + .byte $ff,$1a + .word @ref11 +@ref13: + .byte $9e,$61,$5d,$59,$52,$a7,$00,$4f,$53,$61,$5d,$59,$52,$87,$00,$4d + .byte $52,$93,$00,$a2,$60,$89 +@ref14: + .byte $9e,$79,$75,$71,$6a,$a5,$01,$67,$6b,$79,$75,$71,$6a,$89,$65,$6a + .byte $9f,$00 +@ref15: + .byte $90,$31,$96,$37,$3b,$98,$30,$8b,$00,$90,$2c,$85,$98,$2c,$85,$92 + .byte $38,$8f,$00,$90,$31,$37,$94,$3b,$90,$30,$8b,$00,$2c,$85,$98,$2c + .byte $85,$92,$26,$87,$00,$87 + .byte $ff,$1b + .word @ref15 + .byte $fd + .word @song1ch1loop + +@song1ch2: +@song1ch2loop: +@ref17: + .byte $00,$99,$80,$11,$01,$11,$01,$1c,$8f,$00,$9b,$11,$01,$11,$01,$0a + .byte $8b,$00,$83 +@ref18: + .byte $00,$99,$11,$01,$11,$01,$1c,$8f,$00,$9b,$11,$01,$11,$01,$0a,$8b + .byte $00,$83 +@ref19: + .byte $61,$5d,$59,$52,$a7,$00,$4f,$53,$61,$5d,$59,$52,$87,$00,$4d,$52 + .byte $93,$00,$a2,$52,$89 +@ref20: + .byte $80,$79,$75,$71,$6a,$a5,$01,$67,$6b,$9e,$79,$80,$75,$71,$6a,$89 + .byte $65,$6a,$9f,$00 +@ref21: + .byte $9e,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18 + .byte $00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14 + .byte $00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18 + .byte $00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14 + .byte $81 +@ref22: + .byte $18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00 + .byte $14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00 + .byte $18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00,$18,$00 + .byte $14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$00,$14,$81 + .byte $fd + .word @song1ch2loop + +@song1ch3: +@song1ch3loop: +@ref23: + .byte $82,$17,$84,$17,$8a,$0d,$84,$17,$82,$17,$84,$17,$8a,$0d,$84,$17 + .byte $82,$17,$84,$17,$8a,$0d,$84,$17,$82,$17,$84,$17,$8a,$0d,$84,$17 + .byte $82,$17,$84,$17,$8a,$0d,$84,$17,$82,$17,$84,$17,$8a,$0d,$84,$17 + .byte $82,$17,$84,$17,$8a,$0d,$84,$17,$82,$17,$84,$17,$8a,$0d,$8c,$16 + .byte $81 + .byte $ff,$21 + .word @ref23 + .byte $ff,$21 + .word @ref23 + .byte $ff,$21 + .word @ref23 + .byte $ff,$21 + .word @ref23 + .byte $ff,$21 + .word @ref23 + .byte $fd + .word @song1ch3loop + +@song1ch4: +@song1ch4loop: +@ref29: + .byte $f9,$85 +@ref30: + .byte $f9,$85 +@ref31: + .byte $f9,$85 +@ref32: + .byte $f9,$85 +@ref33: + .byte $f9,$85 +@ref34: + .byte $f9,$85 + .byte $fd + .word @song1ch4loop + + +@song2ch0: + .byte $fb,$06 +@song2ch0loop: +@ref35: + .byte $00,$f9,$83 + .byte $fd + .word @song2ch0loop + +@song2ch1: +@song2ch1loop: +@ref36: + .byte $00,$f9,$83 + .byte $fd + .word @song2ch1loop + +@song2ch2: +@song2ch2loop: +@ref37: + .byte $00,$f9,$83 + .byte $fd + .word @song2ch2loop + +@song2ch3: +@song2ch3loop: +@ref38: + .byte $00,$f9,$83 + .byte $fd + .word @song2ch3loop + +@song2ch4: +@song2ch4loop: +@ref39: + .byte $00,$f9,$83 + .byte $fd + .word @song2ch4loop + + +@song3ch0: + .byte $fb,$06 +@song3ch0loop: +@ref40: + .byte $00,$f9,$83 + .byte $fd + .word @song3ch0loop + +@song3ch1: +@song3ch1loop: +@ref41: + .byte $00,$f9,$83 + .byte $fd + .word @song3ch1loop + +@song3ch2: +@song3ch2loop: +@ref42: + .byte $00,$f9,$83 + .byte $fd + .word @song3ch2loop + +@song3ch3: +@song3ch3loop: +@ref43: + .byte $00,$f9,$83 + .byte $fd + .word @song3ch3loop + +@song3ch4: +@song3ch4loop: +@ref44: + .byte $00,$f9,$83 + .byte $fd + .word @song3ch4loop + + +@song4ch0: + .byte $fb,$04 +@song4ch0loop: +@ref45: + .byte $94,$4a,$85,$01,$8e,$45,$94,$45,$92,$47,$01,$90,$41,$00,$9d +@ref46: + .byte $98,$4a,$85,$01,$8e,$45,$94,$45,$47,$01,$92,$41,$00,$89,$94,$3d + .byte $92,$3d,$94,$41,$41,$00,$81 +@ref47: + .byte $4e,$85,$01,$8e,$49,$94,$49,$92,$4b,$01,$90,$45,$00,$9d +@ref48: + .byte $98,$4e,$85,$01,$8e,$49,$94,$49,$4b,$01,$92,$45,$00,$91,$94,$51 + .byte $4f,$4c,$81 + .byte $fd + .word @song4ch0loop + +@song4ch1: +@song4ch1loop: +@ref49: + .byte $96,$1a,$85,$01,$8e,$15,$96,$15,$17,$01,$11,$00,$9d +@ref50: + .byte $1a,$85,$01,$8e,$15,$96,$15,$17,$01,$11,$00,$89,$0d,$98,$0d,$96 + .byte $11,$11,$00,$81 +@ref51: + .byte $1e,$85,$01,$8e,$19,$96,$19,$1b,$01,$15,$00,$9d +@ref52: + .byte $1e,$85,$01,$8e,$19,$96,$19,$1b,$01,$15,$00,$91,$94,$39,$37,$34 + .byte $81 + .byte $fd + .word @song4ch1loop + +@song4ch2: +@song4ch2loop: +@ref53: + .byte $8c,$02,$85,$01,$8e,$2d,$8c,$03,$80,$2f,$01,$29,$8c,$02,$8d,$02 + .byte $8d +@ref54: + .byte $02,$85,$01,$8e,$2d,$8c,$03,$80,$2f,$01,$29,$8c,$02,$89,$80,$25 + .byte $8c,$03,$80,$29,$29,$00,$81 +@ref55: + .byte $8c,$02,$85,$01,$8e,$31,$8c,$03,$80,$33,$01,$2d,$8c,$02,$8d,$02 + .byte $8d +@ref56: + .byte $02,$85,$01,$8e,$31,$8c,$03,$80,$33,$01,$2d,$8c,$02,$8d,$03,$94 + .byte $39,$37,$34,$81 + .byte $fd + .word @song4ch2loop + +@song4ch3: +@song4ch3loop: +@ref57: + .byte $8e,$0c,$85,$8a,$15,$84,$17,$8e,$0d,$84,$17,$8a,$15,$84,$17,$8e + .byte $0c,$85,$8a,$15,$84,$17,$8e,$0d,$86,$19,$8a,$15,$84,$16,$81 + .byte $ff,$11 + .word @ref57 + .byte $ff,$11 + .word @ref57 + .byte $ff,$11 + .word @ref57 + .byte $fd + .word @song4ch3loop + +@song4ch4: +@song4ch4loop: +@ref61: + .byte $bf +@ref62: + .byte $bf +@ref63: + .byte $bf +@ref64: + .byte $bf + .byte $fd + .word @song4ch4loop + + +@song5ch0: + .byte $fb,$06 +@ref65: + .byte $96,$38,$85,$01,$92,$35,$90,$38,$85,$01,$94,$34,$81 +@ref66: + .byte $90,$38,$85,$01,$92,$35,$90,$39,$a4,$39,$94,$2f,$96,$34,$81 +@ref67: + .byte $90,$38,$85,$01,$92,$35,$96,$38,$85,$01,$92,$34,$81 +@ref68: + .byte $94,$39,$96,$3f,$43,$47,$38,$85,$01,$34,$81 +@ref69: + .byte $38,$85,$01,$35,$38,$85,$01,$34,$81 +@ref70: + .byte $38,$85,$01,$35,$39,$a4,$39,$96,$2f,$34,$81 +@ref71: + .byte $39,$01,$39,$35,$2f,$01,$2f,$34,$81 +@ref72: + .byte $39,$3f,$43,$47,$4d,$47,$43,$3e,$81 +@song5ch0loop: +@ref73: + .byte $92,$50,$4c,$46,$42,$46,$42,$3e,$38,$3e,$38,$34,$2e,$34,$2e,$2a + .byte $26 +@ref74: + .byte $50,$4c,$46,$42,$46,$42,$3e,$38,$3e,$38,$34,$2e,$34,$2e,$2a,$26 + .byte $ff,$10 + .word @ref74 + .byte $ff,$10 + .word @ref74 + .byte $fd + .word @song5ch0loop + +@song5ch1: +@ref77: + .byte $9e,$26,$8d,$2a,$8d +@ref78: + .byte $20,$9d +@ref79: + .byte $26,$8d,$2a,$8d +@ref80: + .byte $20,$8d,$1a,$8d +@ref81: + .byte $26,$8d,$2a,$8d +@ref82: + .byte $20,$9d +@ref83: + .byte $1a,$9d +@ref84: + .byte $18,$8d,$1c,$8d +@song5ch1loop: +@ref85: + .byte $9a,$20,$83,$26,$83,$2b,$2e,$83,$34,$83,$38,$81 +@ref86: + .byte $20,$83,$26,$83,$2b,$2e,$83,$34,$83,$38,$81 + .byte $ff,$0b + .word @ref86 +@ref88: + .byte $21,$21,$27,$2b,$2f,$2e,$34,$83,$38,$81 + .byte $fd + .word @song5ch1loop + +@song5ch2: +@ref89: + .byte $8c,$02,$9d +@ref90: + .byte $9b,$02,$81 +@ref91: + .byte $02,$9d +@ref92: + .byte $97,$02,$02,$02,$02 +@ref93: + .byte $02,$9d +@ref94: + .byte $9b,$02,$81 +@ref95: + .byte $02,$9d + .byte $ff,$05 + .word @ref92 +@song5ch2loop: +@ref97: + .byte $8c,$02,$85,$02,$85,$02,$85,$02,$85 +@ref98: + .byte $02,$85,$02,$85,$02,$85,$02,$85 + .byte $ff,$08 + .word @ref98 + .byte $ff,$08 + .word @ref98 + .byte $fd + .word @song5ch2loop + +@song5ch3: +@ref101: + .byte $9f +@ref102: + .byte $9f +@ref103: + .byte $9f +@ref104: + .byte $9f +@ref105: + .byte $9f +@ref106: + .byte $9f +@ref107: + .byte $9f +@ref108: + .byte $9f +@song5ch3loop: +@ref109: + .byte $83,$86,$1e,$85,$1e,$85,$1e,$85,$1e,$81 +@ref110: + .byte $83,$1e,$85,$1e,$85,$1e,$85,$1e,$81 + .byte $ff,$09 + .word @ref110 + .byte $ff,$09 + .word @ref110 + .byte $fd + .word @song5ch3loop + +@song5ch4: +@ref113: + .byte $9f +@ref114: + .byte $9f +@ref115: + .byte $9f +@ref116: + .byte $9f +@ref117: + .byte $9f +@ref118: + .byte $9f +@ref119: + .byte $9f +@ref120: + .byte $9f +@song5ch4loop: +@ref121: + .byte $9f +@ref122: + .byte $9f +@ref123: + .byte $9f +@ref124: + .byte $9f + .byte $fd + .word @song5ch4loop + + +@song6ch0: +@song6ch0loop: + .byte $fb,$03 +@ref125: + .byte $af +@ref126: + .byte $8f,$a6,$32,$8b,$a8,$42,$83,$aa,$42,$8d,$a8,$3e,$87,$aa,$3e,$83 + .byte $a8,$3e,$89,$a6,$32,$bd,$2e,$91,$a8,$34,$87,$34,$83,$34,$87,$aa + .byte $34,$83,$a8,$3e,$89,$a6,$2e,$ad +@ref127: + .byte $8f,$32,$8b,$a8,$42,$83,$aa,$42,$8d,$a8,$3e,$87,$aa,$3e,$83,$a8 + .byte $3e,$89,$a6,$32,$bd,$2e,$91,$aa,$3e,$87,$3e,$83,$ac,$3e,$87,$a8 + .byte $42,$83,$46,$89,$a6,$2e,$ab + .byte $fd + .word @song6ch0loop + +@song6ch1: +@song6ch1loop: +@ref128: + .byte $af +@ref129: + .byte $8f,$a6,$32,$87,$a8,$42,$83,$aa,$42,$8d,$a8,$3e,$87,$aa,$3e,$83 + .byte $a8,$3e,$8d,$aa,$38,$ad,$00,$8d,$a6,$2e,$8d,$a8,$34,$87,$34,$83 + .byte $34,$87,$aa,$34,$83,$a8,$3e,$8d,$38,$ad +@ref130: + .byte $00,$8d,$a6,$32,$87,$a8,$42,$83,$42,$8d,$aa,$3e,$87,$a8,$3e,$83 + .byte $3e,$8d,$ac,$46,$ad,$00,$8d,$a6,$2e,$8d,$aa,$3e,$87,$3e,$83,$ac + .byte $3e,$87,$a8,$42,$83,$46,$8d,$aa,$42,$9d,$00,$8b + .byte $fd + .word @song6ch1loop + +@song6ch2: +@song6ch2loop: +@ref131: + .byte $97,$8c,$02,$85,$02,$85,$02,$85 +@ref132: + .byte $9f,$8c,$02,$bd,$02,$bd,$02,$bd,$02,$9d +@ref133: + .byte $9f,$02,$bd,$02,$bd,$02,$bd,$02,$9b + .byte $fd + .word @song6ch2loop + +@song6ch3: +@song6ch3loop: +@ref134: + .byte $8a,$18,$84,$14,$88,$18,$84,$14,$8a,$18,$84,$14,$88,$18,$84,$14 + .byte $8a,$18,$9d +@ref135: + .byte $82,$14,$8d,$84,$14,$9d,$14,$9d,$14,$9d,$14,$9d,$14,$9d,$14,$9d + .byte $14,$9d,$14,$87,$8a,$16,$16,$81 +@ref136: + .byte $16,$8d,$84,$14,$9d,$14,$9d,$14,$9d,$14,$9d,$14,$9d,$14,$10,$86 + .byte $15,$88,$11,$82,$14,$91,$84,$14,$9d,$14,$85,$8a,$16,$16,$81 + .byte $fd + .word @song6ch3loop + +@song6ch4: +@song6ch4loop: +@ref137: + .byte $af +@ref138: + .byte $f9,$f9,$8b +@ref139: + .byte $f9,$f9,$89 + .byte $fd + .word @song6ch4loop diff --git a/neslib.h b/neslib.h new file mode 100644 index 0000000..d71e07a --- /dev/null +++ b/neslib.h @@ -0,0 +1,296 @@ +//NES hardware-dependent functions by Shiru (shiru@mail.ru) +//Feel free to do anything you want with this code, consider it Public Domain + +//Versions history: +// 030914 - minor fixes in the vram update system +// 310814 - added vram_flush_update +// 120414 - removed adr argument from vram_write and vram_read, +// unrle_vram renamed to vram_unrle, with adr argument removed +// 060414 - many fixes and improvements, including sequental VRAM updates +// previous versions were created since mid-2011, there were many updates + + + + + +//set bg and spr palettes, data is 32 bytes array + +void __fastcall__ pal_all(const char *data); + +//set bg palette only, data is 16 bytes array + +void __fastcall__ pal_bg(const char *data); + +//set spr palette only, data is 16 bytes array + +void __fastcall__ pal_spr(const char *data); + +//set a palette entry, index is 0..31 + +void __fastcall__ pal_col(unsigned char index,unsigned char color); + +//reset palette to $0f + +void __fastcall__ pal_clear(void); + +//set virtual bright both for sprites and background, 0 is black, 4 is normal, 8 is white + +void __fastcall__ pal_bright(unsigned char bright); + +//set virtual bright for sprites only + +void __fastcall__ pal_spr_bright(unsigned char bright); + +//set virtual bright for sprites background only + +void __fastcall__ pal_bg_bright(unsigned char bright); + + + +//wait actual TV frame, 50hz for PAL, 60hz for NTSC + +void __fastcall__ ppu_wait_nmi(void); + +//wait virtual frame, it is always 50hz, frame-to-frame in PAL, frameskip in NTSC + +void __fastcall__ ppu_wait_frame(void); + +//turn off rendering, nmi still enabled when rendering is disabled + +void __fastcall__ ppu_off(void); + +//turn on bg, spr + +void __fastcall__ ppu_on_all(void); + +//turn on bg only + +void __fastcall__ ppu_on_bg(void); + +//turn on spr only + +void __fastcall__ ppu_on_spr(void); + +//set PPU_MASK directly + +void __fastcall__ ppu_mask(unsigned char mask); + +//get current video system, 0 for PAL, not 0 for NTSC + +unsigned char __fastcall__ ppu_system(void); + + + +//clear OAM buffer, all the sprites are hidden + +void __fastcall__ oam_clear(void); + +//set sprite display mode, 0 for 8x8 sprites, 1 for 8x16 sprites + +void __fastcall__ oam_size(unsigned char size); + +//set sprite in OAM buffer, chrnum is tile, attr is attribute, sprid is offset in OAM in bytes +//returns sprid+4, which is offset for a next sprite + +unsigned char __fastcall__ oam_spr(unsigned char x,unsigned char y,unsigned char chrnum,unsigned char attr,unsigned char sprid); + +//set metasprite in OAM buffer +//meta sprite is a const unsigned char array, it contains four bytes per sprite +//in order x offset, y offset, tile, attribute +//x=128 is end of a meta sprite +//returns sprid+4, which is offset for a next sprite + +unsigned char __fastcall__ oam_meta_spr(unsigned char x,unsigned char y,unsigned char sprid,const unsigned char *data); + +//hide all remaining sprites from given offset + +void __fastcall__ oam_hide_rest(unsigned char sprid); + + + +//play a music in FamiTone format + +void __fastcall__ music_play(unsigned char song); + +//stop music + +void __fastcall__ music_stop(void); + +//pause and unpause music + +void __fastcall__ music_pause(unsigned char pause); + +//play FamiTone sound effect on channel 0..3 + +void __fastcall__ sfx_play(unsigned char sound,unsigned char channel); + +//play a DPCM sample, 1..63 + +void __fastcall__ sample_play(unsigned char sample); + + + +//poll controller and return flags like PAD_LEFT etc, input is pad number (0 or 1) + +unsigned char __fastcall__ pad_poll(unsigned char pad); + +//poll controller in trigger mode, a flag is set only on button down, not hold +//if you need to poll the pad in both normal and trigger mode, poll it in the +//trigger mode for first, then use pad_state + +unsigned char __fastcall__ pad_trigger(unsigned char pad); + +//get previous pad state without polling ports + +unsigned char __fastcall__ pad_state(unsigned char pad); + + +//set scroll, including rhe top bits +//it is always applied at beginning of a TV frame, not at the function call + +void __fastcall__ scroll(unsigned int x,unsigned int y); + +//set scroll after screen split invoked by the sprite 0 hit +//warning: all CPU time between the function call and the actual split point will be wasted! +//warning: the program loop has to fit into the frame time, ppu_wait_frame should not be used +// otherwise empty frames without split will be inserted, resulting in jumpy screen +//warning: only X scroll could be changed in this version + +void __fastcall__ split(unsigned int x,unsigned int y); + + +//select current chr bank for sprites, 0..1 + +void __fastcall__ bank_spr(unsigned char n); + +//select current chr bank for background, 0..1 + +void __fastcall__ bank_bg(unsigned char n); + + + +//get random number 0..255 or 0..65535 + +unsigned char __fastcall__ rand8(void); +unsigned int __fastcall__ rand16(void); + +//set random seed + +void __fastcall__ set_rand(unsigned int seed); + + + +//when display is enabled, vram access could only be done with this vram update system +//the function sets a pointer to the update buffer that contains data and addresses +//in a special format. It allows to write non-sequental bytes, as well as horizontal or +//vertical nametable sequences. +//buffer pointer could be changed during rendering, but it only takes effect on a new frame +//number of transferred bytes is limited by vblank time +//to disable updates, call this function with NULL pointer + +//the update data format: +// MSB, LSB, byte for a non-sequental write +// MSB|NT_UPD_HORZ, LSB, LEN, [bytes] for a horizontal sequence +// MSB|NT_UPD_VERT, LSB, LEN, [bytes] for a vertical sequence +// NT_UPD_EOF to mark end of the buffer + +//length of this data should be under 256 bytes + +void __fastcall__ set_vram_update(unsigned char *buf); + +//all following vram functions only work when display is disabled + +//do a series of VRAM writes, the same format as for set_vram_update, but writes done right away + +void __fastcall__ flush_vram_update(unsigned char *buf); + +//set vram pointer to write operations if you need to write some data to vram + +void __fastcall__ vram_adr(unsigned int adr); + +//put a byte at current vram address, works only when rendering is turned off + +void __fastcall__ vram_put(unsigned char n); + +//fill a block with a byte at current vram address, works only when rendering is turned off + +void __fastcall__ vram_fill(unsigned char n,unsigned int len); + +//set vram autoincrement, 0 for +1 and not 0 for +32 + +void __fastcall__ vram_inc(unsigned char n); + +//read a block from current address of vram, works only when rendering is turned off + +void __fastcall__ vram_read(unsigned char *dst,unsigned int size); + +//write a block to current address of vram, works only when rendering is turned off + +void __fastcall__ vram_write(const unsigned char *src,unsigned int size); + + +//unpack RLE data to current address of vram, mostly used for nametables + +void __fastcall__ vram_unrle(const unsigned char *data); + + + +//like a normal memcpy, but does not return anything + +void __fastcall__ memcpy(void *dst,void *src,unsigned int len); + +//like memset, but does not return anything + +void __fastcall__ memfill(void *dst,unsigned char value,unsigned int len); + +//delay for N frames + +void __fastcall__ delay(unsigned char frames); + + + +#define PAD_A 0x01 +#define PAD_B 0x02 +#define PAD_SELECT 0x04 +#define PAD_START 0x08 +#define PAD_UP 0x10 +#define PAD_DOWN 0x20 +#define PAD_LEFT 0x40 +#define PAD_RIGHT 0x80 + +#define OAM_FLIP_V 0x80 +#define OAM_FLIP_H 0x40 +#define OAM_BEHIND 0x20 + +#define MAX(x1,x2) ((x1)<(x2)?(x2):(x1)) +#define MIN(x1,x2) ((x1)<(x2)?(x1):(x2)) + +#define MASK_SPR 0x10 +#define MASK_BG 0x08 +#define MASK_EDGE_SPR 0x04 +#define MASK_EDGE_BG 0x02 + +#define NAMETABLE_A 0x2000 +#define NAMETABLE_B 0x2400 +#define NAMETABLE_C 0x2800 +#define NAMETABLE_D 0x2c00 + +#define NULL 0 +#define TRUE 1 +#define FALSE 0 + +#define NT_UPD_HORZ 0x40 +#define NT_UPD_VERT 0x80 +#define NT_UPD_EOF 0xff + +//macro to calculate nametable address from X,Y in compile time + +#define NTADR_A(x,y) (NAMETABLE_A|(((y)<<5)|(x))) +#define NTADR_B(x,y) (NAMETABLE_B|(((y)<<5)|(x))) +#define NTADR_C(x,y) (NAMETABLE_C|(((y)<<5)|(x))) +#define NTADR_D(x,y) (NAMETABLE_D|(((y)<<5)|(x))) + +//macro to get MSB and LSB + +#define MSB(x) (((x)>>8)) +#define LSB(x) (((x)&0xff)) diff --git a/neslib.s b/neslib.s new file mode 100644 index 0000000..1041dde --- /dev/null +++ b/neslib.s @@ -0,0 +1,1245 @@ +;NES hardware-dependent functions by Shiru (shiru@mail.ru) +;with improvements by VEG +;Feel free to do anything you want with this code, consider it Public Domain + + + .export _pal_all,_pal_bg,_pal_spr,_pal_col,_pal_clear + .export _pal_bright,_pal_spr_bright,_pal_bg_bright + .export _ppu_off,_ppu_on_all,_ppu_on_bg,_ppu_on_spr,_ppu_mask,_ppu_system + .export _oam_clear,_oam_size,_oam_spr,_oam_meta_spr,_oam_hide_rest + .export _ppu_wait_frame,_ppu_wait_nmi + .export _scroll,_split + .export _bank_spr,_bank_bg + .export _vram_read,_vram_write + .export _music_play,_music_stop,_music_pause + .export _sfx_play,_sample_play + .export _pad_poll,_pad_trigger,_pad_state + .export _rand8,_rand16,_set_rand + .export _vram_adr,_vram_put,_vram_fill,_vram_inc,_vram_unrle + .export _set_vram_update,_flush_vram_update + .export _memcpy,_memfill,_delay + + + +;NMI handler + +nmi: + pha + txa + pha + tya + pha + + lda OAM_BUF + sta PPU_OAM_DMA + + lda palBrightTable0,>palBrightTable1,>palBrightTable2 + .byte >palBrightTable3,>palBrightTable4,>palBrightTable5 + .byte >palBrightTable6,>palBrightTable7,>palBrightTable8 + +palBrightTable0: + .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f ;black +palBrightTable1: + .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f +palBrightTable2: + .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f +palBrightTable3: + .byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f +palBrightTable4: + .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0f,$0f,$0f ;normal colors +palBrightTable5: + .byte $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1a,$1b,$1c,$00,$00,$00 +palBrightTable6: + .byte $10,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$10,$10,$10 ;$10 because $20 is the same as $30 +palBrightTable7: + .byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$20,$20,$20 +palBrightTable8: + .byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30 ;white + .byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30 + .byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30 + .byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30 + + .include "famitone2.s" diff --git a/nrom.cfg b/nrom.cfg new file mode 100644 index 0000000..4a67b7c --- /dev/null +++ b/nrom.cfg @@ -0,0 +1,59 @@ +MEMORY { + + ZP: start = $0000, size = $0100, type = rw, define = yes; + HEADER: start = $0000, size = $0010, file = %O ,fill = yes; + PRG: start = $8000, size = $7fc0, file = %O ,fill = yes, define = yes; + DMC: start = $ffc0, size = $003a, file = %O, fill = yes; + VECTORS: start = $fffa, size = $0006, file = %O, fill = yes; + CHR: start = $0000, size = $2000, file = %O, fill = yes; + RAM: start = $0300, size = $0500, define = yes; + + # Use this definition instead if you going to use extra 8K RAM + # RAM: start = $6000, size = $2000, define = yes; +} + +SEGMENTS { + + HEADER: load = HEADER, type = ro; + STARTUP: load = PRG, type = ro, define = yes; + LOWCODE: load = PRG, type = ro, optional = yes; + INIT: load = PRG, type = ro, define = yes, optional = yes; + CODE: load = PRG, type = ro, define = yes; + RODATA: load = PRG, type = ro, define = yes; + DATA: load = PRG, run = RAM, type = rw, define = yes; + VECTORS: load = VECTORS, type = rw; + SAMPLES: load = DMC, type = rw; + CHARS: load = CHR, type = rw; + BSS: load = RAM, type = bss, define = yes; + HEAP: load = RAM, type = bss, optional = yes; + ZEROPAGE: load = ZP, type = zp; + +} + +FEATURES { + + CONDES: segment = INIT, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = RODATA, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; + CONDES: type = interruptor, + segment = RODATA, + label = __INTERRUPTOR_TABLE__, + count = __INTERRUPTOR_COUNT__; + +} + +SYMBOLS { + + __STACKSIZE__ = $0500; # 5 pages stack + + NES_MAPPER = 0; # mapper number + NES_PRG_BANKS = 2; # number of 16K PRG banks, change to 2 for NROM256 + NES_CHR_BANKS = 1; # number of 8K CHR banks + NES_MIRRORING = 0; # 0 horizontal, 1 vertical, 8 four screen + +} diff --git a/runtime.lib b/runtime.lib new file mode 100644 index 0000000000000000000000000000000000000000..fa9a1129ef0aa5b108195d3c96ea441caef8b425 GIT binary patch literal 107045 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 Job`=&{tfwX7IXjr literal 0 HcmV?d00001 diff --git a/sound/sounds.ftm b/sound/sounds.ftm new file mode 100644 index 0000000000000000000000000000000000000000..b709f459d63b707bc1d873cfa45723476ef0ad72 GIT binary patch literal 1577 zcmdUu&2G~`6otn)ab13r68;fF5ki73Y}nRn9DzhkaNIo+cu_%Hlm_u8ydIAN=eyVA zhAk2cMj7jPzPY}0&z;QIrzg#3{qb|VnJ&&hef!c*2O%trx>&42KeQAc@HXt1LP(?m z2byoH`MVut?8ENDKhm$uVpi6dA5SG;X{Hz3^=2DRw(V)yv=?93-_Kq|@zS>^i3+%a zCdevL8LOr~UX)ei#e;upQYs^%{`g`m|Mi3JZO_lzRr&t7td7dq@l5LvHFqmberb$( zQ1V>&qu;J~ENnE1z_cHlhnhB6Wd7yivS^yJuHxaWQ?>QXKhN_{CzCXcCkZFWQZ6PH z=BB7A8L*Z^OPpw}@Z}pVUc`SFuJ*RVC_3m}T^*>4M13hQt!|2EU zF#3@WqaUK3AEKQfqB dA5QVZ>7^gD<3K@pUaqowJgp6*Olsemeigpi;hc_EcS!lVXT zb3vE8wGwb571^O6Ridhk1iuiZQl;{vRlRA_YkpWs{u~VPz^Df_; z-M6!Ls%(w}v78nU(5h*Cj z`AjAg!$Rmr6%=c-EZdHEkt#7cjM`2NCy5w0t8k!Ft~0hb4j(qB4VG7{hLKKd8e_*L zTK5@evqsYgF%}{*9>=w|RFBDp7;xOS(l-oDu&FSdcN|w?k*`!L4aT$H z!}tj;J$`}Z=`?wxsg7kuIuTT4tYoWpU@B)%~GgX#n?pLFF*>PxaiEzF1Yb^B~^>{ zL*Bm$TZA<&osP9%H!r*6*@1jRoTACP1V6DKQTU)OaT>lY2KxA<{O~$$Oh>~^4cTr9 z;kE-}J!?!ma6lUyV_Xd<$auwFki^)sg1I4fxrunU-wBt1#*59XxyjzkwzF{Q;>)dI zcjTu<2B0QY=~<-Hy6?N#4%!cp?Ya@@xp)Z+4Tp%Zi zSPVNJQfZd4=U8G(#k50QniS%;4h#E*7#kb2LO5XJf&7>Z2rDAF(*S^%@Gz)Q7GHpY@lzF#<=T^=fazx;}CGoh!@BY;SRKaTz~r zjIo{_ig<-}1BoBimrKVk9XpO6mUr4xJ<_k$ItV?r4w|M{$tLTgq>@KX#=6m@w2SIN zwc4mO>h3=J`>%Na)h25Hrm}p#zJ==Ci%>KY|AXW2+TbQCY z9u6y(u^|-Vj2G8d+HLs87;hOk6)lH=cSn6c+CFjo7|6C+UC>@Gh(uI3s|I4mnu_GE zgZIUk&IA~~l4DZZ=l!?Qav}Y&RtRguV2~*xika$z#Yr!`0u>n zZ^4Y=wImC>wdSv@_-w!UcH<3i?`kNgI70TTI+-4yn5I`T%V$wzv)NoRz{w1@#uQp_ z6#v51&1Y=ZCJq;4q(2(2b=VedY)pq9(^M>s-l)}o75QyNP++QXwAn0#O|x?LDh~Y# zYVe-s9+-m7&&0h7G6E@~+Hl^9?N2;cNGBFjvP<;-3Jp}L2x;1&gk75EuVKUSLXueX zeGcJjv)WvSXJI#Sp7OMV_ijj4IdAoTu*Sv@9z1m7Aj_QrOFrhfA;ulsi4cNAmU3>8 zRSHKy#<7XZCa<2&CX*~hPRQw~^QMJZq!TA=Y^?u6z1{YXKumSwI!Y#0fI^4}8epAhL%Binu4vy0(%Xv(@$Scx zo7Mxx#Yl@xkjsu6$~&z&MHxo6uDdxCjw#;&JYb-}!mmn4{%hFdMK)e_7j5C8x0aa;l2DF5QI$}MF* zw{!4&JGbp{+vQV#uRmFGGfS&)EX~b@^1e{MEtHo-`DMJ47q9ItHjVxVr~Wv&b2o|v z6$+1eD6fX{o!rix?t0B?UrEpP4-E8g#rX8SLMiWNl3iWNlNevh^PwE$OL<=?zl>`b z9bKEuAwGR{H0!mKcdq<%b?GX%GY{pRP`*?#db2$}dg}IDx1gT(q|Wu_bCa%XUcNl% zx|5S;rCP}L=#bxjE5wlJbGgY$$RUP;*{t69nXkRJyk}r%q1t@@_j`N~yNoqRguL1O z^cSUkcjZ0hC44V}@%0_ssGj%eeHfoC)A*AZs00O)?0`ZK6d|VZ-Ee$Yp8T)|7F98D zuk+PE|L(8vw7QmR9q*@~ZCxk#?tfg$ui}CVxtyL%+C(O2 zihF)}kEjklG6I5pw0Hh(M|4)-?FFUN+kQlaa^%@F4m?2FpL@#z?!94)d^t%u`cq#b z$mi$LpZXF>`!o*yNh&qubBNnlE=*51n@yBQiY#GVSzBL6={3R^Ce$SLgL1h{O5t1v zUk?R`xxnyyex~w{(9$=Aw?g=!>4ld%XDzma>5*KJ?~e>tg>!Mf_xaVcf_#5>wL`Ar zq!OHaoHNgk06TBZ%{eq!ddm&Hv^+%Ap9uXi{kdrV(3kc}pPuOt;}ew6nELeeg)8*> z!`s(sW9sYcYgY{5;J}IwL}LR;A5egN9~T+RLJRcXmp&-JKd3&0`Mqyb{>vPI$GGpy z`tapV`5(#uOZhKjpW;8v@25BA|7Q79QU2e1OJ)U&M)~FA+Fd{Ee{u@=@|?fmClY?; z)}BC){FL%@q5N_n-@j|C%>UhAz)X?x@ zzBGJN=Ks}4u@cDd>*RZ9Wd2|M`BETH6n^m33;+0=NEA%#!1!+qvo~G4`?WV8E6jFx zcfa!HWBKh5efNRE7wh@$_k9I?zgX|GZKo(g{&lDnuQxckkUE+?e5N(i9{EOPHF-FDChR!#!hr~cXwf*0)GErzHPVL_8{}!BhP(n>sIXm z^V7vAUVQ@BFXm5fzw@@PY$n4z(Ul})uomzS=flTG>zRST7v=-~xjXK-F)Nru>fU^F z5Ar+UIJThB3c)<+{lEK}FPF>tyvXwmhKGmwQS#wo4?n7{Shs80HtGRWYbIYDLfHwa zG+Y`zH#5pmn5G>)(?h;!nr1N?PT)C@Hl;IE_RB*Giej--j14Cx#drsC{Z}Bd4k>(} zgzq*ZgQW*?|9Q9+;e3g%Gto6o)LXsfnnQ=VfEw9+nXW%fedXa9FPmj3I(8=&mzPZ& zHz}p>wctR^pE`tbIY1+otwr`QUm^dvCBP;_noWHDaFdk3EQgF{%n;W$K%o|}-a3E& zysgIDd~JjC^c(dr581XoRE}_a2J1J|jxb*nxgo$dLxHdMPql_B5k_y^7FE0i*GRSg zg%p-EwtlUdvo2jvnGii7rQe$Oyw_v)T5rAUoj;}QV|_ttKQK9Y{bhS3KR@#;hS4>c z8~EDGn6JHz$$H#AzhY$a_uJlP6r231|pMYYR%qxBJ4@hK literal 0 HcmV?d00001 diff --git a/util/bin-to-h.py b/util/bin-to-h.py new file mode 100644 index 0000000..6adc180 --- /dev/null +++ b/util/bin-to-h.py @@ -0,0 +1,33 @@ +import sys + +use_rle = False +if "--rle" in sys.argv: + use_rle = True + +out = [] + +previous = "NO" +count = 0 + +with open(sys.argv[1]) as f: + x = f.read() + for i in x: + c = hex(ord(i)) + if len(c) == len('0x0'): + c = c[:2] + '0' + c[2] + if use_rle: + if c == previous: + count += 1 + else: + if count: + out.append( hex(count) ) + out.append( previous ) + count = 1 + previous = c + else: + out.append( c ) + if use_rle and count: + out.append( hex(count) ) + out.append( previous ) + +print "const unsigned char __rename_me__[",len(out),"] = {",",".join(out),"};" diff --git a/util/credits.sh b/util/credits.sh new file mode 100644 index 0000000..18270f9 --- /dev/null +++ b/util/credits.sh @@ -0,0 +1,26 @@ +function credit_line() { + echo -n "const unsigned char credits_$1[] = "; + echo "$2" | python ebcdic.py +} + + +# " " +credit_line 0 " SplatooD" +credit_line 1 " a Splatoon demake" +credit_line 2 " Project Lead" +credit_line 3 " John Carmackeral" +credit_line 4 " Music" +credit_line 5 " Nobuo Squidimatsu" +credit_line 6 " Title & Postgame" +credit_line 7 " Koji Ikarashi" +credit_line 8 " Game Design" +credit_line 9 " Squideo Kojima" +credit_line 10 " Graphics" +credit_line 11 " Squid Meier" +credit_line 12 " Game Mechanics" +credit_line 13 " American McGill" +credit_line 14 " Splatoon (C) 2015" +credit_line 15 " Nintendo" +credit_line 16 " Thanks for playing!" + +echo "const unsigned char * credits[] = {" credits_{0..16}, zero, zero, zero "};" diff --git a/util/ebcdic.py b/util/ebcdic.py new file mode 100644 index 0000000..3cf92ae --- /dev/null +++ b/util/ebcdic.py @@ -0,0 +1,9 @@ +import codecs + +out = [] +for i in codecs.encode(raw_input()): + out.append(hex(ord(i)+0x80)) + +out.append("0x00"); + +print "{",",".join(out),"};"