From 261f5c805ee3d79a4dd774051c7222d120cb43a5 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Tue, 25 Nov 2025 01:03:37 +0700 Subject: [PATCH 01/26] Rename files --- loader/samples/minexample/Makefile | 8 ++++---- .../minexample/{sky_scroll.bin => island.bin} | Bin .../{sky_scroll_map.bin => island_map.bin} | Bin loader/samples/minexample/minexample.s | 12 ++++++------ 4 files changed, 10 insertions(+), 10 deletions(-) rename loader/samples/minexample/{sky_scroll.bin => island.bin} (100%) rename loader/samples/minexample/{sky_scroll_map.bin => island_map.bin} (100%) diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index 4356bd0..a82fee3 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -138,10 +138,10 @@ ZX0PRGS = \ falling_star.zx0.prg \ lilia.zx0.prg \ lilia_hero.zx0.prg \ - sky_scroll.zx0.prg + island.zx0.prg LZPRGS = \ - sky_scroll_map.lz.prg + island_map.lz.prg default: diskimage @@ -187,8 +187,8 @@ $(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) -f "fallstar" -w falling_star.zx0.prg \ -f "lilia" -w lilia.zx0.prg \ -f "lilhero" -w lilia_hero.zx0.prg \ - -f "skyscr" -w sky_scroll.zx0.prg \ - -f "skyscrmap" -w sky_scroll_map.lz.prg \ + -f "island" -w island.zx0.prg \ + -f "islandmap" -w island_map.lz.prg \ $@ diff --git a/loader/samples/minexample/sky_scroll.bin b/loader/samples/minexample/island.bin similarity index 100% rename from loader/samples/minexample/sky_scroll.bin rename to loader/samples/minexample/island.bin diff --git a/loader/samples/minexample/sky_scroll_map.bin b/loader/samples/minexample/island_map.bin similarity index 100% rename from loader/samples/minexample/sky_scroll_map.bin rename to loader/samples/minexample/island_map.bin diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index f52b617..16bd582 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -514,12 +514,12 @@ part_9: ; $7800-$78ff tileset tile colors ; $7900-$79ff tileset CRAM colors ; $9000- compressed tilemap - ldx #skyscrname + ldx #islandname lda #$70 jsr load_8000_zx02 - ldx #skyscrmapname + ldx #islandmapname jsr loadraw ldx #0 ldy #$90 @@ -1269,8 +1269,8 @@ fieldname: .byte "field", 0 fallingstarname: .byte "fallstar", 0 lilianame: .byte "lilia", 0 liliaheroname: .byte "lilhero", 0 -skyscrname: .byte "skyscr", 0 -skyscrmapname: .byte "skyscrmap", 0 +islandname: .byte "island", 0 +islandmapname: .byte "islandmap", 0 darmtower_txt: From 937bea7699fb2e6979000e26cb230a0d4abbc0dc Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 26 Nov 2025 00:03:50 +0700 Subject: [PATCH 02/26] Add clouds part --- assets/clouds.png | Bin 0 -> 2167 bytes assets/clouds.prg | Bin 0 -> 10003 bytes assets/clouds_sprites.png | Bin 0 -> 1597 bytes assets/clouds_sprites.prg | Bin 0 -> 1026 bytes loader/samples/minexample/Makefile | 4 +- loader/samples/minexample/clouds.bin | Bin 0 -> 10001 bytes loader/samples/minexample/minexample.s | 135 ++++++++++++++++++++++--- 7 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 assets/clouds.png create mode 100644 assets/clouds.prg create mode 100644 assets/clouds_sprites.png create mode 100644 assets/clouds_sprites.prg create mode 100644 loader/samples/minexample/clouds.bin diff --git a/assets/clouds.png b/assets/clouds.png new file mode 100644 index 0000000000000000000000000000000000000000..311418fcea7ae03c45c77d6fd3d983616506d5bb GIT binary patch literal 2167 zcma)7do&Xa8{bf?2IMg;K~}Zo}sOvdV2?$a=S_bV0mbSm@2I7@CpX z$Cg}@<<5{r&E?f>qvf{i=l$>d<2&d5oK<(hs6#zia*y-YVpVa4U#;3g5UX{JW6*&b! z&Gh3XX36H+R8zI6Lz}nCj)$60_GX?_`f%jRdF|?xZ|;(6mVhTq{^`ACNU*TBzCx4J z*7C%*z<0I(K9)9DO$x9=5go>rk`}Hpi$$8J@B=C0eaK*`11CUKWcdGvo4+rUFgL{C z@#QuT1B5G+Rz_KKHa8`UEX)24R^3wommt%q!oYS2S(Os9@aIqwUGh26G4+jWl>Z7t zpoSk`IM8oH@J>y8U3i7TrqhvnKu+gs)wKv)5z zURl<;_= zR>;Rjl`ej(sryA?UqAl*HsQi&d6>3 zm|lV7y#!t0l9Fgyv5nSg09^VW$;%py`1p-U-me+oryN>)eJN0EwU*P`FqK_yW+lf%c#4@v;in+Nf~EPx_8lA zrJBJyAnrLmDLVW&;dVVQNK}9bb9=q(D!NYGz7;~R7(d-5Dyo%|@FbuAMEu?-?hKi=9$MA3MZOtocf3pa~amIYV(uXldjKLVYd}oNG^h?(}MxUc4x9K zWnb&AX0n6RYz<3K5UIpJRX0k6Ld|%hFs4JUX2)_B(FQpgW-_HqgtYP3{IOVx{pmh-oC=28ap;2EKVPw=rB{#Ksc97M^ zx2g?ry}OM+q?O-onSZ^gK2Gh$y>q5Pxaf^BTywD;KdWKM?=02E>?V8`KS&P7fN+8MX9p_W8m8lIkPt zA7$=bq0)hs$`s6Ee@KtK1P=PEF^>Jmy%L1iyoNh+kE$8J<+WL?u;WPEiW)< z=4SHQ3q61ZD=HtB#m)X4&w%t9ycIN4M3zl^2tx)>_NETJO1O!jgqSrbif*HyqKLC1 zZWMoFdgvuEIIUvnK--i_8MvHsk2n{}cu+F2Jd2Gyd?JHfB|U3LV9XVcUYdxlbxN2|>Z|jeDNa3RATc8{HkPA9L1Y_Fd`nUm+-+De) zvKXJ+iP-B6owxp#1AzFNVu$I9f|!m<%rCt<+S`5z|EK{MY#&YhFRC8etbYOR38`OA zVK3k}SoB^$GcPc0eM78H+75!0m9H3lmLAq5LoI&#!D4;YUJkpShbO za1fIq5R1cUG7D+EYn>A)c!Rq9$9Lu0aPs0Ebyl()I4Sl!fSdBpqUn#;(=sNR#=&N4 zW|;7b>xPu#+?cPt#~0>$xBUjxXB(WPpI=?-cXcN)hNjACoezlx5mvN7V^EU3t zGu8t7tApdi#yH(XOnN7nYjJbCn`pBIuh@^IMC*>}CFDy-bHTS@qCGYe%JBWu2wXIj zqu36%i^=V7E4bj&OfEL3U*merVM0W2-8AOKhc|C>7n51NPz2~q_CG2e7Ak%J%}C5I zG^FlS6pGUB(iIN3%EF@H42fIck=-+!$sh57%|KzrTFtY3zWR=bsoAz)#lba#baSNO z=lh5#li2G+^!<=S^S29cH2GU%Qey~{ZpGPKwAHZP6+o>ym4*iD=Nm1ec822uF!yK1 zfm#!s!s$VRs9$@SXjmf-%@x`#w|D2PAPdKm#^jlqM~M}$X>adrd;jKgdt|1|*m%k& zGJ)~f+F-*Y;8FRZ`8?ln7vCf8AIHBm6`MHp_~XjCwdB2j|FQpzfiD+n51YcKH20`f P|J8P~cfVL`7kcYI!(=!# literal 0 HcmV?d00001 diff --git a/assets/clouds.prg b/assets/clouds.prg new file mode 100644 index 0000000000000000000000000000000000000000..0cd92cbc68f8e0586449a6b4412e3255c1bd1149 GIT binary patch literal 10003 zcmeH}&5qMB5XV`bgqL#AW)GYeX*bgL#G`l*+`CdHTKfc2Q;|GH4sb})_5OM%aTJ_4HKqPVh{-8yRoI;IgTS4V?}5>S#CxLX0h&%J1YGf` zJ?~B@bx-iIPRaMcX!{pRPxnDCf_rRE(r9=ee^?p{QN}B=D_RfGbV^~@I{tKg^QmU) zvh{%GjsJe9IO?hnd(|oV9vERY)>#S%cs1G5I@vCNqdC9Wj{K{(2WUE_5NiopXja`Q zTq_n4tCnl)TopiF*P}_2$h`FTK>qnVDX)&Mrn&Dg=j)a4??XBz-vc93#u%-Y&NBaM zT`h#5yf8$RQl6KDBWrAmI^|LHF)td76=hjEjTu_&*=lV~(-?-^9n=!_Je$qy@EwX` zVHvx~O6Riki1BJ|>vbB%$!L^CF(x;SU9OCC#u~;he;A|0h4<~8{~d%Nb&yi2$undw zL?I~4%AydZPu~V93L-xU!%R9w0SG#z<|~8gINK7btx3n6DWY)GvlgCk^Oj{sI1HkN zAbt%vm~|c>^BElHl)jBHKb;iL38>=}x+$fgn17N70S`%H%^Vex5nY{f6a&%ty{{yX z%8Rc_FHqFt9PRzYhmOnlkNYH3izQUX{oVf+S#ZOm1kHz-fzU{y%%Ru;sR)`Z%I zfSi}IoTK!;h%?SFl~SQ|01vD`!(W$FUDq1x#4<~XB3by{u~utJiD4>zADn#StWs03 z@_M;Y$|$sOgD!b1U#LK5eQSXQ9(^b literal 0 HcmV?d00001 diff --git a/assets/clouds_sprites.png b/assets/clouds_sprites.png new file mode 100644 index 0000000000000000000000000000000000000000..121b6549e401f2519a7a4e08e7d8918b55b24c81 GIT binary patch literal 1597 zcmV-D2EzG?P)Px)_en%SRCt{2UCVLXFccIsx~2f%bxZC^0aPzcN9@IFAO-lwdkRPa%GeR8Xvv-T z!Gj<%*cp$9GKtUI_XQxjJD<6n>2$g);i%gN1)PYN5<6weDNJOB(55Ir?y@u!6ICJMsEr4}AeSWzaD8>TsfI1@h)Zg&!c3hIi zOPHS%ER0!%Rx!;4B-3Xd&6+|cY7JT)2tG}Cmo$;|Hz=>Qf}+n8!KZPuBt)x_?kq@x zG=N0ZLI4-RFFtodB1UST{T*GEw_xqkj+oW=YKcJtFsqutrD3~P0=&=Vg1JP|0wmwN z+uaJ->-$jS6AmDF>=y}=u2JxeU<6Y%e4Y`Eu2Wkl?U|-C6GKR8AM^3(Tc^uJ7r`zC z$uz+QQM*;&oZ9L87Zq^`c0W@LNs$mqF0%`=0$qtU{maeQ5h(aafh1lt0b0RpF&JaY zvq8#=%$0B{L5)It%vD*jbWyfEUu$U?16aKjz8}B_I0vZ<(%(npL@_ooSEeOOs(h`k zjSKV5MHYt|&VTlCq&W+ffdLFEzZ`ECoKFuZ^0Ct_A0lTd9Y;AZy1_ zm_SgH@GDu8M3Z=z{2h;&9cCZ~Q8f=w8HriDc z&w>zaYj08p*~Qw7urwC`Q1&-ePhHiW#NTV}^%MLr3NJ za=q>5!uo20Y6N(F=HS%K+;7;IN;`|KhKd~pziDv@`kJh_eh7bGP-#SE4c@vz>Yu&S zLb@*(@4aNTmRoR4!h!&+rsDltAFA!=ObFP@%K>Ksv>F-Z zT3Ghb2?E}n1xP_ytD(6Ta5fUK6$=pGoclh}e<%B{dDeBFhQKU{rD4n!S+frbTO(gx z2WU-SOTboKNG{AT>u7lLwV+01B?7kQyQ2`k7Sw$G?*G^i*b2f4Xs+f#m!lij(f*B9 vWi$dRqY+RUjeyE%1XM;NpfVZ(ySn%T@nIi`K*1-;00000NkvXXu0mjfP!8Zt literal 0 HcmV?d00001 diff --git a/assets/clouds_sprites.prg b/assets/clouds_sprites.prg new file mode 100644 index 0000000000000000000000000000000000000000..c651a6b08e20aa8289d39e89beef619608033c58 GIT binary patch literal 1026 zcmd6mF>BjE6vzJ}R=i|zOJvB<(4~8q7P=*n?h4$Kk%QvJCnE(n9jcTJZofj8laW#- zOHW1$Zl)wOQ@?}*8ayT;hIVT+6ihD;EiUl~=;OzqcaL|+`#(55#>^-Ii+};`3AC!I zxlHrThyKcgS09$$kIPn4tn70wR6|cvpmi7(I_1L>dx+-u6_kf;1fVV0kqbU67mR_XXfeQI-q5km(U4@1HFN= znlnIo2)%&53ymfWppBuOK}!I8f_jYuE<#QuiA1|o^XfaD_@@<*cf{DGt8MRM+YP)l zXrJ?rXbp;;usAM`Z$UT@N}x} HzfFGwzgzCA literal 0 HcmV?d00001 diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index a82fee3..34d520d 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -138,7 +138,8 @@ ZX0PRGS = \ falling_star.zx0.prg \ lilia.zx0.prg \ lilia_hero.zx0.prg \ - island.zx0.prg + island.zx0.prg \ + clouds.zx0.prg LZPRGS = \ island_map.lz.prg @@ -189,6 +190,7 @@ $(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) -f "lilhero" -w lilia_hero.zx0.prg \ -f "island" -w island.zx0.prg \ -f "islandmap" -w island_map.lz.prg \ + -f "clouds" -w clouds.zx0.prg \ $@ diff --git a/loader/samples/minexample/clouds.bin b/loader/samples/minexample/clouds.bin new file mode 100644 index 0000000000000000000000000000000000000000..81495c14bf35c4d46bc6779aad03fc3e478c876f GIT binary patch literal 10001 zcmeHNKX2Ps5I-SSyku~T$Uuf>>)xdWx+OrmD*%szXeeGx8IoYDLzN@MY^o@w%GuA$cRt(v<#zGc+j47J!4$Tf6Z>YeYxvCuGeB zP{V`@-NyyiEY$h-cC+p^U#z}7e7jY7R<1nv3)?>C%8!10q}05p>-Fcao-n=H+F8YV zjUk}mrGmV+pO^OYMA*$^3)L1|V@y)nT92)@ajh*&nk*qo1(fobZDAI3SzIS%CyGFK^Gd%gXZHxvsq~9TV-{FmsU07v1U9`4PFwgp`m9QdPdWi zH7%n)%cxYYr`7EY%4u?bL&MiTwh!{V78*8cZB;Fh_oZAbztTdJq1jTY)R_9Lu4;AE zsAQ_n@&vl}-Cd|@*&53t#e>-#mHBLrSY2Z3lBPjX1$hl*3Gg0B#CH;20tw&;fbS_3 z#BcB8t-F{3yaiv}f}3ern#4bD(8F-!Y|!uYq|Bm(3(~zs=^m8}Hy3WugG0Oo@YOqN z?`_6&nj|v{I>7l70Cz7!1aijCNAj#ENHW;^2%o&U$@$y%j}HjF0-< z5Dm-PRdFn$&7sS|Iht|UChnbcduF;52WPyI0H##O=bgISpA`US9JYyjr;m`KUIub9 znWxREi~_Q*JwFP0vWhmeE?RBk;EXpeisRpopS-Hkua7NIwJP4<^Z^UKkJzgjhi&2> zMH9slPY!Tz_Y|#_)9_Cu<;~NPPgPGGobiSd*hGT>y#t@F6$2T)qvI%!y#%Oszq(tg z*p4gifvo$Q`$8=1dyeQI9Uc!w|1xOCVVk(e{V)uJzzN8xA`BHivtY*Rk>dWZewJtQkugt%$Cacq`l zWZrSqKQ?5gQmvY@LX$_M=x7+maTtY&^*3SYTbsgm9E-mzLF76ieqXjWOtvmP0CxKWg8zOmbhV~fPf3O{gdi!1DR`$~XEPEyQ_GQ#9sR~aP(=UP)_ zl7LE($Vowaf;hLvaoL?=B8?(a5ou?8M@d_FXGG~4#-!D;gLoJb zVtx>C%55S-PLS&!QtAt`N{rQg-%mPMprH6odUUzp@Am_WlfrauN|J%_onnnb*QR0a ziay~asyOofJ;F-J?Sb!yKGkG~x?E_9L?!4VQAY#|Sun@bI3Mjfl$f*;md|anCzi7V z!uNy-x&-&r{=A+eFh^jHz#M@&0&@heJ_7IkVegU#{+iPqfjI)79Dz%EoUex2)H!;O t*XOiS^#39k(Rj*5S|1$$$EqK(?#Y}F+7*Kz()-wT|1WwMg7yDU_#4B)T#o<% literal 0 HcmV?d00001 diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 16bd582..50354a3 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -659,10 +659,11 @@ part_9: @finish: lda #0 sta timer_mode + sta $d015 ; TODO is there a delay here -part_10: - jmp * + ; we run out of space before the fixed location vector return now + jmp part_10 drawrow: ldy #0 @@ -810,13 +811,15 @@ init_2x: lda #$00 sta $d012 +position_2x_to_display: + lda #51 +position_2x: : bit $d011 bpl :- : bit $d011 bmi :- - lda #51 : cmp $d012 bne :- @@ -1259,18 +1262,19 @@ irq_badguy: pla rti -badguy: .byte "badguy",0 -fontname: .byte "font",0 -sidname: .byte "sid", 0 -introname: .byte "intrbmp", 0 -towername: .byte "tower", 0 -towerbeamname: .byte "towerbm", 0 -fieldname: .byte "field", 0 -fallingstarname: .byte "fallstar", 0 -lilianame: .byte "lilia", 0 -liliaheroname: .byte "lilhero", 0 -islandname: .byte "island", 0 -islandmapname: .byte "islandmap", 0 +badguy: .byte "badguy",0 +fontname: .byte "font",0 +sidname: .byte "sid", 0 +introname: .byte "intrbmp", 0 +towername: .byte "tower", 0 +towerbeamname: .byte "towerbm", 0 +fieldname: .byte "field", 0 +fallingstarname: .byte "fallstar", 0 +lilianame: .byte "lilia", 0 +liliaheroname: .byte "lilhero", 0 +islandname: .byte "island", 0 +islandmapname: .byte "islandmap", 0 +cloudsname: .byte "clouds", 0 darmtower_txt: @@ -1429,6 +1433,107 @@ load_8000_zx02: pla jmp zx02 +part_10: + ; the sprite data is embedded into first few bitmap pixels + ; which are hidden by black border attributes +@y = $60 + ldx #cloudsname + jsr load_8000_zx02_2000 + jsr init_bmp + ldx #0 + stx $d010 + stx $d017 + stx $d01d + stx $d025 + stx frame + dex + stx $d01b + stx $d01c + lda #11 + sta $d026 + lda #@y+50 + jsr position_2x + ; draw top half +@loop: + bit $d011 + bpl @loop + ldx #0 + ldy #0 + lda frame + cmp #200 ; TODO + bcc :+ + jmp @finish +: + adc @sprxs,x + sta $d000,y + sta temp + lda @sprys,x + sta $d001,y + txa + ora #$80 + sta $7f8,x + lda @sprcols,x + sta $d027,x + lda temp + iny + iny + inx + cpx #8 + bcc :- + lda #$ff + sta $d015 + + ; draw bottom half +: + bit $d011 + bmi :- + lda #@y+37 +: + cmp $d012 + bcs :- + + ldx #0 + ldy #0 + lda frame + clc +: + adc @sprxs+8,x + sta $d000,y + sta temp + lda @sprys+8,x + sta $d001,y + txa + ora #$88 + sta $7f8,x + lda @sprcols+8,x + sta $d027,x + lda temp + iny + iny + inx + cpx #6 + nop + bcc :- + + inc frame + jmp @loop + +@sprxs: + .byte 200, <-24, 24, 24, <-64, 24, 24, 24 + .byte 200-40, 24, 24, 24, <-44, 24 + +@sprys: + .byte @y-8, @y, @y, @y, @y+21, @y+21, @y+21, @y+21 + .byte @y+42, @y+42, @y+42, @y+42, @y+63, @y+63 + +@sprcols: + .byte 2, 5, 5, 5, 14, 14, 14, 6 + .byte 2, 2, 2, 9, 2, 2 + +@finish: + jmp * + clear_2bufs: ldy #$44 .byte $2c ; skip next instruction From 3f4765029bcfc601b2af2303b647bba298b9b94e Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 26 Nov 2025 04:35:13 +0700 Subject: [PATCH 03/26] Load font directly to the destination --- loader/samples/minexample/Makefile | 4 +- loader/samples/minexample/badguy.bin | Bin 27828 -> 27828 bytes loader/samples/minexample/font.bin | Bin 514 -> 517 bytes loader/samples/minexample/loaderconfig.inc | 2 +- loader/samples/minexample/minexample.s | 116 ++++++++------------- 5 files changed, 49 insertions(+), 73 deletions(-) diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index 34d520d..3f2f604 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -155,7 +155,7 @@ tellarch: loader: $(LOADER) $(LOADER): $(LOADERCFG) - make -C $(LOADER_SRC) EXTCONFIGPATH=../samples/$(NAME) PLATFORM=$(_PLATFORM_) INSTALL=0a00 RESIDENT=0900 ZP=02 prg + make -C $(LOADER_SRC) EXTCONFIGPATH=../samples/$(NAME) PLATFORM=$(_PLATFORM_) INSTALL=0b00 RESIDENT=0900 ZP=02 prg assemble: $(ASSEMBLE) @@ -174,7 +174,7 @@ endif diskimage: $(DISKIMAGE) -$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) +$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) use_this_sid.bin font.bin $(RM) $@ $(CC1541) -n "otomata labs" -i " 2025" \ -f "ys2intro" -w $< \ diff --git a/loader/samples/minexample/badguy.bin b/loader/samples/minexample/badguy.bin index 1c722c928ecbd92f63833ce7f51caa93510bda81..4d8173a6148c0cd04014ea1277cb2ef518b43dee 100644 GIT binary patch delta 224 mcmdmTlX1&U#tjKd^$i0HJgH{=M#fD{lkcUnZGND7#SH-a*>5WV delta 22 ecmdmTlX1&U#tjKd8wIMEC*MnD+x$TFiW>lU5ehp1 diff --git a/loader/samples/minexample/font.bin b/loader/samples/minexample/font.bin index 83283441bce5e6fe36c36d90a1b2e164257611b4..adddaf8aeab5ca99f88720d8b7361d394cd39ceb 100644 GIT binary patch literal 517 zcmXw#ziS&Y6vr(*lt7{FSm@HBgQsFTY08wXYyXD+0hu}!d{w|L4TPX9BJa@DDMN=0 z=I~G-M-U1k8biS)m>WdfK?DurFhO||$wzuTzS8?8jh?0lTqY%Vef_hXEEeOkJ)68` zeh#1o{A;!Ita(7pBOdBHve=@qd zWT&zwv#ZPQyOhs1`F<)czOL7+rfHt9LYco>4a0E$ZhwAYbT{W>hgoZ7U6WVes%k>% z3xLCe*HcO#-(4AF7}hKL4ZlFG=bZ20J5?B_toq>`mY4$~I8((b?*UFus$;$c-ABdg mX8^60bKMM@U~5VgCLwBJ$GEKRaXzGv|NrD)c;w&v(U*G~du;{) literal 514 zcmXw#y=ojW5XXf%gbHC)grH(MOb&ue8DSyJvX|mmu5jVPRVuM#)L4XoLvmoT7gD71 z1LPU<2(DbI3P-9dQlv4YOj4N?hmw(qf6_4grTLP`d-5MyAVeM>p4F4(a#y#A+pqEI zHj?3jiRV30OXWV@e02Zt3A{mxR_FkYXDjjI)JWd^mB?Ho0W#u zurDK0Ij2yQhzpUNVj_v@$0>$MVi&icZx^=Ak+D$Lx{KcL8tvTOoo}Pj+WYY5@6mC* za6?`n9k*|s`#ml98-Ma{HkcU4Lw&w$`+FlyHq<|N;Nni(y%Ab$}c=J{sU#3lFk4C diff --git a/loader/samples/minexample/loaderconfig.inc b/loader/samples/minexample/loaderconfig.inc index 7901632..dab7083 100644 --- a/loader/samples/minexample/loaderconfig.inc +++ b/loader/samples/minexample/loaderconfig.inc @@ -40,7 +40,7 @@ DECOMPRESSOR = DECOMPRESSORS::NONE; available are NONE, BITNA ; extended features, different settings can be run with the same installed drive code, increase host-side code size -.define FILE_EXISTS_API 0 ; include the fileexists call for simple multi-disk handling +.define FILE_EXISTS_API 1 ; include the fileexists call for simple multi-disk handling .define LOAD_UNDER_D000_DFFF 0 ; C-64/128: enable loading (and decompression) to the RAM at $D000..$DFFF, ; note that this does not slow down loading when not loading to RAM at $D000..$DFFF, diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 50354a3..301e9d3 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -95,26 +95,12 @@ code_start: sei - ldx #fontname - jsr loadraw + lda #0 + jsr load_font lda #$34 sta $01 - ldx #0 -: - lda $8000, x - sta $d800, x - eor #$ff - sta $c00, x - lda $8100, x - sta $d900, x - eor #$ff - sta $d00, x - inx - bne :- - lda #0 tax : @@ -151,7 +137,7 @@ code_start: lda #$1b sta $d011 - lda #$d0 + lda #$d2 sta $d012 lda #1 @@ -1221,36 +1207,32 @@ irq_badguy: inc vbl ;inc $d020 + nop + nop + nop + nop lda #$1b sta $d011 - lda #$19 - sta $d018 lda #$c8 sta $d016 - lda $dd00 - and #3 - sta @dd00_arc+1 - lda #0 - sta $dd00 - lda #$47 + lda #$13 sta $d018 + lda #1 + sta $d021 + lda #$fa : - lda $d012 - cmp #$fb - bcc :- - - .res 2, $ea + cmp $d012 + bcs :- lda #$3b sta $d011 - lda #$19 - sta $d018 lda #$d8 sta $d016 -@dd00_arc: + lda #$19 + sta $d018 lda #0 - sta $dd00 + sta $d021 ;dec $d020 @@ -1303,60 +1285,33 @@ too_bad_txt: .res (40-16)/2, ' ' upload_text: - lda #$34 - sta $01 - stx text_ptr sty text_ptr+1 ldy #39 : lda (text_ptr), y - sec - sbc #$20 - sta $d348, y + clc + adc #$60 + sta $748, y dey - bne :- - - lda #$35 - sta $01 - - lda #1 - ldy #39 -: - sta $db48, y - dey - bne :- + bpl :- rts upload_text_bottom: - lda #$34 - sta $01 - stx text_ptr sty text_ptr+1 ldy #39 : lda (text_ptr), y - sec - sbc #$20 - sta $d348+40+40, y + clc + adc #$60 + sta $748+40+40, y dey - bne :- - - lda #$35 - sta $01 - - lda #1 - ldy #39 -: - sta $db48+40+40, y - dey - bne :- + bpl :- rts - run_nufli_bmp: lda #$01 sta $81 @@ -1433,6 +1388,18 @@ load_8000_zx02: pla jmp zx02 +load_font: + beq :+ + pha +: + ldx #fontname + jsr fileexists + bcs :- + ldx #fontname + jmp loadraw + part_10: ; the sprite data is embedded into first few bitmap pixels ; which are hidden by black border attributes @@ -1452,7 +1419,7 @@ part_10: stx $d01c lda #11 sta $d026 - lda #@y+50 + lda #@y+48 jsr position_2x ; draw top half @loop: @@ -1532,6 +1499,15 @@ part_10: .byte 2, 2, 2, 9, 2, 2 @finish: + jsr position_2x_to_display + + .res ((*+$ff)&$ff00|2)-* +end: + ldx #fontname + jsr fileexists + bcc end + jsr load_font jmp * clear_2bufs: From c006e1a0a233d03bad5604c4a0a4064e7092b8ef Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 26 Nov 2025 19:42:34 +0700 Subject: [PATCH 04/26] Add music player source --- loader/samples/minexample/Makefile | 10 +- loader/samples/minexample/furC64/.gitignore | 8 + loader/samples/minexample/furC64/README.md | 42 + loader/samples/minexample/furC64/asm/bin.cfg | 16 + loader/samples/minexample/furC64/asm/exe.cfg | 22 + .../samples/minexample/furC64/asm/furC64.asm | 2181 +++++++++++++++++ .../samples/minexample/furC64/asm/note_hi.bin | 3 + .../samples/minexample/furC64/asm/note_lo.bin | 1 + .../minexample/furC64/chipchune/__init__.py | 18 + .../minexample/furC64/chipchune/_util.py | 98 + .../furC64/chipchune/deflemask/__init__.py | 3 + .../furC64/chipchune/famitracker/__init__.py | 3 + .../furC64/chipchune/furnace/__init__.py | 24 + .../furC64/chipchune/furnace/data_types.py | 706 ++++++ .../furC64/chipchune/furnace/enums.py | 648 +++++ .../furC64/chipchune/furnace/instrument.py | 1572 ++++++++++++ .../furC64/chipchune/furnace/module.py | 1111 +++++++++ .../furC64/chipchune/furnace/sample.py | 47 + .../furC64/chipchune/furnace/wavetable.py | 101 + .../furC64/chipchune/interchange/__init__.py | 7 + .../furC64/chipchune/interchange/enums.py | 24 + .../furC64/chipchune/interchange/furnace.py | 52 + .../furC64/chipchune/utils/__init__.py | 5 + .../furC64/chipchune/utils/conversion.py | 94 + loader/samples/minexample/furC64/convert.bat | 14 + loader/samples/minexample/furC64/convert.sh | 15 + .../minexample/furC64/convert_to_asm.py | 780 ++++++ loader/samples/minexample/guy_amb.fur | Bin 0 -> 415 bytes loader/samples/minexample/guy_appear.fur | Bin 0 -> 441 bytes loader/samples/minexample/minexample.s | 9 +- loader/samples/minexample/use_this_sid.bin | Bin 6815 -> 6904 bytes loader/samples/minexample/ys2_new.bin | Bin 8351 -> 0 bytes loader/samples/minexample/ys2_port_legato.fur | Bin 0 -> 6501 bytes loader/samples/minexample/ys2_sid.sid | Bin 8439 -> 0 bytes loader/samples/minexample/ys2sid.bin | Bin 8305 -> 0 bytes 35 files changed, 7608 insertions(+), 6 deletions(-) create mode 100644 loader/samples/minexample/furC64/.gitignore create mode 100644 loader/samples/minexample/furC64/README.md create mode 100644 loader/samples/minexample/furC64/asm/bin.cfg create mode 100644 loader/samples/minexample/furC64/asm/exe.cfg create mode 100644 loader/samples/minexample/furC64/asm/furC64.asm create mode 100644 loader/samples/minexample/furC64/asm/note_hi.bin create mode 100644 loader/samples/minexample/furC64/asm/note_lo.bin create mode 100644 loader/samples/minexample/furC64/chipchune/__init__.py create mode 100644 loader/samples/minexample/furC64/chipchune/_util.py create mode 100644 loader/samples/minexample/furC64/chipchune/deflemask/__init__.py create mode 100644 loader/samples/minexample/furC64/chipchune/famitracker/__init__.py create mode 100644 loader/samples/minexample/furC64/chipchune/furnace/__init__.py create mode 100644 loader/samples/minexample/furC64/chipchune/furnace/data_types.py create mode 100644 loader/samples/minexample/furC64/chipchune/furnace/enums.py create mode 100644 loader/samples/minexample/furC64/chipchune/furnace/instrument.py create mode 100644 loader/samples/minexample/furC64/chipchune/furnace/module.py create mode 100644 loader/samples/minexample/furC64/chipchune/furnace/sample.py create mode 100644 loader/samples/minexample/furC64/chipchune/furnace/wavetable.py create mode 100644 loader/samples/minexample/furC64/chipchune/interchange/__init__.py create mode 100644 loader/samples/minexample/furC64/chipchune/interchange/enums.py create mode 100644 loader/samples/minexample/furC64/chipchune/interchange/furnace.py create mode 100644 loader/samples/minexample/furC64/chipchune/utils/__init__.py create mode 100644 loader/samples/minexample/furC64/chipchune/utils/conversion.py create mode 100644 loader/samples/minexample/furC64/convert.bat create mode 100755 loader/samples/minexample/furC64/convert.sh create mode 100644 loader/samples/minexample/furC64/convert_to_asm.py create mode 100644 loader/samples/minexample/guy_amb.fur create mode 100644 loader/samples/minexample/guy_appear.fur delete mode 100644 loader/samples/minexample/ys2_new.bin create mode 100644 loader/samples/minexample/ys2_port_legato.fur delete mode 100644 loader/samples/minexample/ys2_sid.sid delete mode 100644 loader/samples/minexample/ys2sid.bin diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index 3f2f604..2241425 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -97,6 +97,7 @@ C1541 = c1541 CC1541 = ../../tools/cc1541/cc1541 ZX02 = zx02/build/zx02 ZX02_SRC = zx02 +FURC64 = furC64 PYTHON = python3 MKDIR = mkdir -p @@ -130,6 +131,7 @@ DISKIMAGE = $(BUILDDIR)/$(NAME)-$(_PLATFORM_).d64 AS_FLAGS = -Wa -I../../../shared -I ../../include -u __EXEHDR__ ZX0PRGS = \ + use_this_sid.zx0.prg \ badguy.zx0.prg \ title_320-prepared.zx0.prg \ tower.zx0.prg \ @@ -174,11 +176,11 @@ endif diskimage: $(DISKIMAGE) -$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) use_this_sid.bin font.bin +$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.bin $(RM) $@ $(CC1541) -n "otomata labs" -i " 2025" \ -f "ys2intro" -w $< \ - -f "sid" -w use_this_sid.bin \ + -f "song0" -w use_this_sid.zx0.prg \ -f "badguy" -w badguy.zx0.prg \ -f "font" -w font.bin \ -f "intrbmp" -w title_320-prepared.zx0.prg \ @@ -224,6 +226,10 @@ $(ZX02): $(PRINTF) "\x00\x90" | cat - $@.tmp > $@ $(RM) $@.tmp +use_this_sid.bin: ys2_port_legato.fur + cd $(FURC64) && ./convert.sh $(abspath $<) + cp $(FURC64)/asm/song.bin $@ + clean: -$(RM) $(ZX0PRGS) $(LZPRGS) -$(RM) *.o $(ASSEMBLE) $(DISKIMAGE) diff --git a/loader/samples/minexample/furC64/.gitignore b/loader/samples/minexample/furC64/.gitignore new file mode 100644 index 0000000..6b8c623 --- /dev/null +++ b/loader/samples/minexample/furC64/.gitignore @@ -0,0 +1,8 @@ +__pycache__ +asm/song.asm +asm/song.bin +*.o +*.lbl +*.lst +*.map +*.prg diff --git a/loader/samples/minexample/furC64/README.md b/loader/samples/minexample/furC64/README.md new file mode 100644 index 0000000..927b587 --- /dev/null +++ b/loader/samples/minexample/furC64/README.md @@ -0,0 +1,42 @@ +# furC64 +a C64/SID sound driver for Furnace + +### **THIS SOUND DRIVER IS CURRENTLY A WIP** + +A SID driver that's easy to make music with? It's more likely than you think. + +* You have to have [Python](https://www.python.org/) and the [CC65 toolchain](https://cc65.github.io/) installed +* You **have** to set the pitch linearity option to "None". You can do this by going to `window -> song -> compatability flags -> Pitch/Playback -> Pitch linearity` and then setting the option to "None". + +* The driver only supports **arpeggio, waveform, duty and cutoff** macros in each instrument and it DOESN'T support LFO and ADSR macros nor delay and step length, **although you can use LFO macros in the duty and cutoff macros (as in range-sweeping)** + +* The furC64 driver only supports these effects: + * 00xx: arpeggio + * 01xx: pitch slide up + * 02xx: pitch slide down + * 03xx: portamento + * 04xx: vibrato + * 09xx: set speed 1 + * 0Bxx: jump to pattern + * 0Dxx: jump to next pattern + * 0Fxx: set speed 2 + * 1Axx: disable/enable envelope reset + * 1Bxx: reset cutoff + * 1Cxx: reset pulse-width + * 4xxx: set filter cutoff + * E1xx: note slide up + * E2xx: note slide down + * E5xx: note fine-pitch + * EAxx: legato + * ECxx: note cut + +when you've finished / want to test out this driver: +* open the terminal/command prompt **to the furC64 directory** +* run `convert.sh your_fur_file.fur` or `convert.bat file.fur` (depending on your OS) +* in the `furC64/asm` directory you'll hopefully see a file called **`furC64-test.prg`** + * that's your .prg file that you can run on hardware or on an emulator like VICE! + +Hopefully you'll have fun with this driver alongside [furNES](https://github.com/AnnoyedArt1256/furNES) :D + +Libraries used: chipchune + diff --git a/loader/samples/minexample/furC64/asm/bin.cfg b/loader/samples/minexample/furC64/asm/bin.cfg new file mode 100644 index 0000000..bf5f6ea --- /dev/null +++ b/loader/samples/minexample/furC64/asm/bin.cfg @@ -0,0 +1,16 @@ +FEATURES { + STARTADDRESS: default = $0801; +} +MEMORY { + ZP: file = "", start = $0002, size = $00FE, define = yes; + MAIN: file = "", start = %S, size = $A000 - %S; + PLAYER: file = %O, start = $A000, size = $5FFA; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; + PLAYER: load = PLAYER, type = rw, define = yes; +} diff --git a/loader/samples/minexample/furC64/asm/exe.cfg b/loader/samples/minexample/furC64/asm/exe.cfg new file mode 100644 index 0000000..bb41d47 --- /dev/null +++ b/loader/samples/minexample/furC64/asm/exe.cfg @@ -0,0 +1,22 @@ +FEATURES { + STARTADDRESS: default = $0801; +} +SYMBOLS { + __LOADADDR__: type = import; +} +MEMORY { + ZP: file = "", start = $0002, size = $00FE, define = yes; + LOADADDR: file = %O, start = %S - 2, size = $0002; + MAIN: file = %O, start = %S, size = $A000 - %S; + PLAYER: file = %O, start = $A000, size = $5FFA; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + LOADADDR: load = LOADADDR, type = ro; + EXEHDR: load = MAIN, type = ro, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; + PLAYER: load = MAIN, run = PLAYER, type = rw, define = yes; +} diff --git a/loader/samples/minexample/furC64/asm/furC64.asm b/loader/samples/minexample/furC64/asm/furC64.asm new file mode 100644 index 0000000..5629d5a --- /dev/null +++ b/loader/samples/minexample/furC64/asm/furC64.asm @@ -0,0 +1,2181 @@ +.feature c_comments + +.define chnum 3 +.define use_zp 0 +.define porta_once 0 +.define compat_hr 0 +.define CHIP_AMT 1 +.define DIGI 0 +.define HR_ADSR 1 +TEST_AD := $00 +TEST_SR := $00 + +;.define compat_hr 1 +;TEST_AD := $0f +;TEST_SR := $0f + + +.if DIGI = 0 +.define outch chnum +.else +.define outch 4 +.endif + +.macro variables +start_vars = * + +mframeW: .res chnum +doMacroW: .res chnum + +; why +env_reset_buf: .res chnum +env_reset: .res chnum + +fil_lo_n2: .res CHIP_AMT +fil_hi_n2: .res CHIP_AMT +fil_st2: .res CHIP_AMT + +legato: .res chnum + +test_reset: .res chnum + +note_tick: .res chnum + +dur: .res chnum + +vibrato_param: .res chnum +vibrato_phase: .res chnum + +absfil: .res CHIP_AMT + +doMacroC: .res CHIP_AMT +mframeC: .res CHIP_AMT + +instF: .res CHIP_AMT + +wav: .res chnum + +hrframe: .res chnum + +hrc: .res chnum + +ad: .res chnum +sr: .res chnum + +patseq: .res chnum*2 + +duty_lo: .res chnum +duty_hi: .res chnum + +nextpat: .res 1 +patind: .res 1 +jumppat: .res 1 +ch: .res 1 +chm: .res 1 +tick: .res 1 +ins: .res chnum +inst_prev: .res chnum +mframeA: .res chnum +mframeD: .res chnum +doMacroA: .res chnum +doMacroD: .res chnum +arp: .res chnum +absarp: .res chnum +effects_temp: .res 2 +tick_speeds: .res 2 +tick_sel: .res 1 +slide_amt: .res chnum +slide_amt_sign: .res chnum +slide_buffer_lo: .res chnum +slide_buffer_hi: .res chnum +note_pitch_lo: .res chnum +note_pitch_hi: .res chnum +note_n: .res chnum +note_temp: .res chnum +note_dest: .res chnum +finepitch: .res chnum +cut_dur: .res chnum +pw_mod_lo: .res chnum +pw_mod_hi: .res chnum +abspw: .res chnum +retrigger_pw: .res chnum +retrigger_fil: .res CHIP_AMT +triggered_fil: .res CHIP_AMT +.if porta_once = 1 +didporta: .res chnum +.endif +arpeff1: .res chnum +arpeff2: .res chnum +arpind: .res chnum +vol: .res CHIP_AMT +res: .res CHIP_AMT +fil_lo: .res CHIP_AMT +fil_hi: .res CHIP_AMT +fil_lo_n: .res CHIP_AMT +fil_hi_n: .res CHIP_AMT +base: .res 1 +chipnum: .res 1 +has_played: .res chnum +vars_len = *-start_vars + +.endmacro + +inst_buffer = ins + +.if chnum > 4 +.define actual_use_zp 0 +.else +.define actual_use_zp use_zp +.endif + +.ZEROPAGE +.if actual_use_zp = 1 +.org $10 +variables +.endif +patzp := $fe +macroIns := patzp +temp := patzp-4 +flags_temp := temp+3 +patloop = 0 + +.segment "CODE" + +.org $080D +jmp $900 +.res $0900-* +.import __PLAYER_LOAD__, __PLAYER_RUN__, __PLAYER_SIZE__ +main: + sei + lda #$35 + sta $01 + + lda #<__PLAYER_LOAD__ + sta temp + lda #>__PLAYER_LOAD__ + sta temp+1 + lda #<__PLAYER_RUN__ + sta temp+2 + lda #>__PLAYER_RUN__ + sta temp+3 + ldy #0 + ldx #>__PLAYER_SIZE__ + beq :+++ +: + lda (temp),y + sta (temp+2),y + iny + bne :- + inc temp+1 + inc temp+3 + dex + bne :- + beq :++ +: + lda (temp),y + sta (temp+2),y + iny +: + cpy #<__PLAYER_SIZE__ + bne :-- + + lda #127 + sta $dc0d + + and $d011 + sta $d011 + + lda $dc0d + lda $dd0d + + lda #irq + sta $ffff + +.if DIGI <> 0 + lda #$0b + sta $d011 + lda #$00 +.else + lda #$10 +.endif + sta $d012 + + lda #0 + sta $d01a + + lda #$63; <(985248/100) + sta $dc04 + lda #$26;>(985248/100) + sta $dc05 + + lda $dc0d + and #$81 + sta $dc0d + + lda #$40 + sta $dc0c + + lda #$81 + sta $dc0d + + +.if DIGI <> 0 +ldx #0 +: + lda real_addr, x + sta $2, x + inx + cpx #nmi_end-nmi + bne :- +.endif + + lda #0 + jsr init + +.if DIGI <> 0 +lda #nmi +sta $fffb + +lda #$01 +sta $dd0d +sta $dd0e + +lda #$88 ; lo +sta $dd04 +lda #0 +sta $dd05 ; hi + +lda $dd0d +lda #$81 +sta $dd0d + +lda #$40 +sta $dd0c +.endif + + cli + jmp * + +irq: + pha + txa + pha + tya + pha + + .if DIGI = 0 + inc $d020 + .endif + + ;lda $d012 + ;sta rastertime + jsr play + + .if DIGI = 0 + dec $d020 + .endif + + ;lda $d012 + ;sec + ;sbc rastertime + ;sta rastertime + + ;asl $d019 + pla + tay + pla + tax + pla + ;rti + jmp $dc0c + +;rastertime: .res 1 + +.if DIGI <> 0 +real_addr = * +.org $2 +nmi: + sta z:ldat+1 +ldn: + lda $200 + sta $d418 + inc ldn+1 +ldat: + lda #0 + jmp $dd0c +NMI_BUFFER: + ldy #0 +NMI_LOOP: + lda z:nmi_add+2 +nmi_cmp: + cmp #0 + bcc nmi_store +nmi_cmp2: + lda #0 + sta z:nmi_add+2 +nmi_none: + lda vol + and #$f0 + ora #10 + sta $200, y + jmp NMI_LOOP_END + +nmi_store: + lda vol + and #$f0 +nmi_add: + ora $1000 + sta $200, y + clc +nmi_freq_lo2: + lda #0 +nmi_freq_lo: + adc #0 + sta nmi_freq_lo2+1 + lda nmi_add+1 +nmi_freq_hi: + adc #1 + sta nmi_add+1 + bcc NMI_LOOP_END + inc nmi_add+2 +NMI_LOOP_END: + iny + cpy #144 + bne NMI_LOOP + rts +nmi_end: +.org real_addr+(nmi_end-nmi) +.endif + +.segment "PLAYER" +.reloc +init: +jmp initaddr +play: +jmp playaddr +.byte " furC64 driver by AArt1256" + +.if actual_use_zp = 0 +variables +.endif +table_1_to_ff: +table_fil: + .byte 0 + .res 15, $ff + +.proc initaddr +.if actual_use_zp = 1 + ldx #vars_len + lda #0 +: + sta start_vars-1, x + dex + bne :- +.endif + + + ldx #(CHIP_AMT)-1 +: + lda #$7f + sta vol, x + lda #$00 + sta res, x + sta retrigger_fil, x + sta triggered_fil, x + lda #$ff + sta fil_lo, x + sta fil_lo_n, x + lda #$07 + sta fil_hi, x + sta fil_hi_n, x + lda #0 + sta doMacroC, x + sta absfil, x + sta fil_lo_n2, x + sta fil_hi_n2, x + sta fil_st2, x + sta mframeC, x + sta has_played, x + dex + bpl :- + + lda #0 + sta tick_sel + + lda ticks_init + sta tick_speeds + lda ticks_init+1 + sta tick_speeds+1 + + lda #0 + sta patind + + ldx #chnum-1 +: + lda #$80 + sta finepitch, x + sta finepitch, x + lda #1 + sta dur, x + lda #$ff + sta cut_dur, x + lda #0 + sta pw_mod_lo, x + sta pw_mod_hi, x +.if porta_once = 1 + sta didporta, x +.endif + sta wav, x + sta retrigger_pw, x + sta abspw, x + sta ins, x + sta inst_prev, x + sta arp, x + sta slide_amt, x + sta slide_amt_sign, x + sta slide_buffer_lo, x + sta slide_buffer_hi, x + sta vibrato_phase, x + sta vibrato_param, x + sta note_dest, x + sta mframeA, x + sta mframeW, x + sta mframeD, x + sta doMacroA, x + sta doMacroW, x + sta doMacroD, x + lda #$ff + sta env_reset_buf, x + lda #8 + sta test_reset, x + lda #4 + sta hrframe, x + sta note_tick, x + dex + bpl :- + + ldx #0 + jsr set_patseq_init + lda #0 + sta tick + sta jumppat + + rts +.endproc + +.macro get_patzp + .local skipW + inc patzp + bne skipW + inc patzp+1 +skipW: + lda (patzp), y +.endmacro + +.macro get_patzp_vol + .local skipW + inc patzp + bne skipW + inc patzp+1 +skipW: + lda vol + and #$f0 + ora (patzp), y +.endmacro + +.macro add_09xx +effectE0: + get_patzp + sta tick_speeds + jmp begnote +.endmacro + + +.macro add_0Fxx +effectE1: + get_patzp + sta tick_speeds+1 + jmp begnote +.endmacro + +.macro add_0Bxx +effectED: + get_patzp + sta patind + lda #$ff + sta jumppat + jmp begnote +.endmacro + + +.macro add_00xx +effectE2: + get_patzp + sta effects_temp+1 + ldx ch + lda #0 + sta arpind, x + lda effects_temp+1 + and #$0f + sta arpeff2, x + lda effects_temp+1 + lsr + lsr + lsr + lsr + sta arpeff1, x + jmp begnote +.endmacro + + +.macro add_01xx +effectE3: + get_patzp + ldx ch + sta slide_amt, x + lda #$ff + sta slide_amt_sign, x + ldx ch + lda #88 + sta note_dest, x +.if porta_once = 1 + lda #$00 + sta didporta, x +.endif + jmp begnote +.endmacro + +.macro add_02xx +effectE4: + get_patzp + ldx ch + sta slide_amt, x + lda #$00 + sta slide_amt_sign, x + ldx ch + lda #0 + sta note_dest, x +.if porta_once = 1 + lda #$00 + sta didporta, x +.endif + jmp begnote +.endmacro + +.macro add_03xx +effectE5: + get_patzp + ldx ch + sta slide_amt, x + ldy #0 + get_patzp + ldx ch + sta note_dest, x + +.if porta_once = 1 + lda #$ff + sta didporta, x +.endif + + lda note_n, x + cmp note_dest, x + bne :+ + lda #0 + sta slide_amt, x + sta slide_amt_sign, x + jmp begnote +: + bcc :+ + lda #$00 + sta slide_amt_sign, x + jmp begnote +: + lda #$ff + sta slide_amt_sign, x + jmp begnote +.endmacro + +.macro add_04xx + .local retskip +effectE6: + get_patzp + ldx ch + sta vibrato_param, x + beq retskip + sta vibrato_phase, x +retskip: + jmp begnote +.endmacro + +.macro add_1Axx +effectF1: + get_patzp + ldx ch + eor #$ff + sta env_reset_buf, x + jmp begnote +.endmacro + + +.macro add_1Bxx + .local retskip +effectE7: + get_patzp + sta effects_temp+1 + and #$0f + tax + lda table_fil, x + ldx ch + beq :+ + ldx chipnum + lda fil_lo_n, x + sta fil_lo, x + lda fil_hi_n, x + sta fil_hi, x + ldx ch +: + lda effects_temp+1 + lsr + lsr + lsr + lsr + tax + lda table_fil, x + ldx chipnum + sta retrigger_fil, x + jmp begnote +.endmacro + +.macro add_1Cxx + .local retskip +effectE8: + get_patzp + sta effects_temp+1 + and #$0f + tax + lda table_fil, x + ldx ch + beq :+ + lda #0 + sta pw_mod_lo, x + sta pw_mod_hi, x +: + lda effects_temp+1 + lsr + lsr + lsr + lsr + tax + lda table_fil, x + ldx ch + sta retrigger_pw, x + jmp begnote +.endmacro + +.macro add_E1xx +effectE9: + get_patzp + ldx ch + asl + asl + sta slide_amt, x + lda #$ff + sta slide_amt_sign, x + ldy #0 + get_patzp + ldx ch + ora #$80 + sta note_dest, x +.if porta_once = 1 + lda #$00 + sta didporta, x +.endif + jmp begnote +.endmacro + +.macro add_E2xx +effectEA: + get_patzp + ldx ch + asl + asl + sta slide_amt, x + lda #$00 + sta slide_amt_sign, x + ldy #0 + get_patzp + ldx ch + ora #$80 + sta note_dest, x +.if porta_once = 1 + lda #$00 + sta didporta, x +.endif + jmp begnote +.endmacro + + +.macro add_E5xx +effectEB: + get_patzp + ldx ch + sta finepitch, x + jmp begnote +.endmacro + +.macro add_ECxx +effectEC: + get_patzp + ldx ch + clc + .if compat_hr = 0 + adc #3 + .else + adc #2 + .endif + sta cut_dur, x + jmp begnote +.endmacro + +.macro add_4xxx +effectEE: + ldx chipnum + lda #0 + sta doMacroC, x + sta fil_hi_n2, x + lda #$ff + sta fil_st2, x + get_patzp + ldx chipnum + sta fil_lo_n2, x + clc + asl fil_lo_n2, x + rol fil_hi_n2, x + clc + asl fil_lo_n2, x + rol fil_hi_n2, x + clc + asl fil_lo_n2, x + rol fil_hi_n2, x + jmp begnote +.endmacro + + +.macro add_EAxx +effectEF: + ldx ch + lda #0 + sta legato, x + jmp begnote + +effectF0: + ldx ch + lda #$ff + sta legato, x + jmp begnote +.endmacro + +add_09xx +add_0Fxx +add_00xx +add_01xx +add_02xx +add_03xx +add_04xx +add_0Bxx +add_1Axx +add_1Bxx +add_1Cxx +add_E1xx +add_E2xx +add_E5xx +add_EAxx +add_ECxx +add_4xxx + +other_effects: + lda effects_temp + cmp #$FB + bne :+ + ldx ch + get_patzp + sta ins, x + jmp begnote +: + cmp #$FC + bne :+ + ldx chipnum + get_patzp_vol + sta vol, x + jmp begnote +: + + cmp #$FD + bne :+ + ldx ch + ldy ins, x + lda insArel, y + sta mframeA, x + lda insDrel, y + sta mframeD, x + ldx ch + .if compat_hr = 0 + lda #3 + .else + lda #2 + .endif + sta cut_dur, x + lda #1 + sta dur, x + ldy #0 + jmp end_advance +: + + cmp #$FE + bne :+ + ldx ch + .if compat_hr = 0 + lda #3 + .else + lda #2 + .endif + sta cut_dur, x + lda #1 + sta dur, x + ldy #0 + jmp end_advance +: + lda effects_temp + cmp #224 + bcc cont_advance + + lda effects_temp + and #$1f + tax + lda eff_lo, x + sta effect_smc+1 + lda eff_hi, x + sta effect_smc+2 + ldx ch + lda effects_temp +effect_smc: + jmp cont_advance + +eff_lo: +.repeat $12, I + .lobytes .ident(.concat ("effect", .sprintf("%02X",I+$e0))) +.endrepeat +eff_hi: +.repeat $12, I + .hibytes .ident(.concat ("effect", .sprintf("%02X",I+$e0))) +.endrepeat + +.macro add_advance_routine +advance: + .local skipD, noIns, noVol, beg, blank2, blank3, hasNote, wait +beg: + lda ch + asl + tax + lda patseq, x + sta patzp + lda patseq+1, x + sta patzp+1 + + ldx ch + dec dur, x + lda dur, x + beq begnote + jmp end_advance +begnote: + + ldy #0 + get_patzp + sta temp + sta effects_temp + and #$80 + beq wait + lda temp + cmp #$ff + beq blank2 + jmp other_effects +cont_advance: + lda temp + and #$7f + ldx ch + + ldy env_reset_buf, x + beq :+ + sta note_n, x +: + sta note_temp, x + + lda note_tick, x + cmp #96 + bne :+ + lda #0 + sta slide_amt, x + sta slide_amt_sign, x +: + lda note_tick, x + cmp #2 + bcc :+ + lda legato, x + bne :+ + lda #0 + sta hrframe, x + lda #$ff + sta hrc, x +: + lda #0 + sta slide_buffer_lo, x + sta slide_buffer_hi, x + sta note_tick, x +.if porta_once = 1 + cmp didporta, x + beq :+ + sta didporta, x + sta slide_amt, x + sta slide_amt_sign, x +: +.endif + ldx ch + lda env_reset_buf, x + sta env_reset, x + lda #1 + sta dur, x + sta has_played, x + ldy #0 + jmp end_advance + +wait: + lda temp + and #$40 + beq :+ + ldx ch + lda temp + and #$3f + sta ins, x + jmp begnote +: + lda temp + ldx ch + sta dur, x +blank2: + lda temp + cmp #$ff + bne end_advance + + lda #$ff + sta nextpat + +end_advance: + lda ch + asl + tax + lda patzp + sta patseq, x + lda patzp+1 + sta patseq+1, x + rts +.endmacro + +add_advance_routine + +.macro add_insarp +insarp: + .local end, skip1, beg, skip2 +beg: + ldx ch + lda doMacroA, x + beq end + + ldx ch + ldy inst_buffer, x + lda insAL, y + sta macroIns + lda insAH, y + sta macroIns+1 + ldx ch + ldy mframeA, x + lda (macroIns), y + cmp #$fe + beq skip2 + cmp #$ff + bne skip1 + iny + lda (macroIns), y + cmp #$ff + beq :+ + sta mframeA, x + jmp beg +: + lda #0 + sta doMacroA, x + rts +skip1: + sec + sbc #128 + sta arp, x + lda #0 + sta absarp, x + inc mframeA, x + rts +skip2: + iny + lda (macroIns), y + sta arp, x + lda #$ff + sta absarp, x + inc mframeA, x + inc mframeA, x +end: + rts +.endmacro + +add_insarp + +.macro add_insduty +insduty: + .local end, skip1, beg, skip2 +beg: + ldx ch + lda doMacroD, x + beq end + + ldx ch + ldy inst_buffer, x + lda insDL, y + sta macroIns + lda insDH, y + sta macroIns+1 + + ;ldx ch + + ldy mframeD, x + lda (macroIns), y + sta temp + cmp #$ff + bne skip1 + iny + lda (macroIns), y + cmp #$ff + beq :+ + sta mframeD, x + jmp beg +: + lda #0 + sta doMacroD, x + rts +skip1: + iny + lda (macroIns), y + sta temp+1 + + lda abspw, x + bne :+ + + lda temp+1 + sec + sbc #$80 + sta temp+1 + lda pw_mod_lo, x + clc + adc temp + sta pw_mod_lo, x + lda pw_mod_hi, x + adc temp+1 + sta pw_mod_hi, x + inc mframeD, x + inc mframeD, x + rts +: + lda temp + sta duty_lo, x + lda temp+1 + sta duty_hi, x + lda #0 + sta pw_mod_lo, x + sta pw_mod_hi, x + inc mframeD, x + inc mframeD, x +end: + rts +.endmacro + +add_insduty + +.macro add_inswave +inswave: + .local end, skip1, beg, skip2 +beg: + ldx ch + lda doMacroW, x + beq end + + ldx ch + ldy inst_buffer, x + lda insWL, y + sta macroIns + lda insWH, y + sta macroIns+1 + ldx ch + ldy mframeW, x + lda (macroIns), y + cmp #$ff + bne skip1 + iny + lda (macroIns), y + cmp #$ff + beq :+ + sta mframeW, x + jmp beg +: + lda #0 + sta doMacroW, x + rts +skip1: + ldx ch + pha + lda wav, x + and #$0f + sta wav, x + pla + ora wav, x + sta wav, x + inc mframeW, x +end: + rts +.endmacro + +add_inswave + +.macro add_inscut +inscut: + .local end, skip1, beg, skip2 +beg: + ldx ch + lda doMacroC, x + beq end + + ldx ch + ldy instF, x + lda insCL, y + sta macroIns + lda insCH, y + sta macroIns+1 + ldx ch + ldy mframeC, x + lda (macroIns), y + sta temp + cmp #$ff + bne skip1 + iny + lda (macroIns), y + cmp #$ff + beq :+ + sta mframeC, x + jmp beg +: + lda #0 + sta doMacroC, x + rts +skip1: + iny + lda (macroIns), y + sta temp+1 + + lda absfil, x + bne :+ + + lda temp+1 + sec + sbc #$80 + sta temp+1 + + lda fil_lo, x + clc + adc temp + sta fil_lo, x + lda fil_hi, x + adc temp+1 + sta fil_hi, x + jmp :++ +: + lda temp + sta fil_lo, x + lda temp+1 + sta fil_hi, x +: + inc mframeC, x + inc mframeC, x +end: + rts +.endmacro + +add_inscut + +.macro cmp16 val1, val2 +/* + .if 0 + lda val1 + sec + sbc val2 + php + lda val1+1 + sbc val2+1 + php + pla + sta macroIns + pla + and #%00000010 + ora #%11111101 + and macroIns + pha + plp + .else + lda val1 + sec + sbc val2 + lda val1+1 + sbc val2+1 + .endif + */ + lda val1 + sec + sbc val2 + lda val1+1 + sbc val2+1 +.endmacro + +doFinepitch: + lda vibrato_param, x + lsr + lsr + lsr + lsr + clc + adc vibrato_phase, x + and #63 + sta vibrato_phase, x + tay + lda vibrato_param, x + and #$0f + ora triangle_lookup, y + tay + + + ; this is NOT a typo! + sec + lda note_pitch_lo, x + sbc finepitch, x + sta temp + lda note_pitch_hi, x + sbc #$fe + sta temp+1 + +; bcs skip_pitch +; lda #0 +; sta temp +; sta temp+1 +;skip_pitch: + +.repeat 3 + lda tri_vibrato_lookup, y + ;lsr + ;clc + ;adc tri_vibrato_lookup, y + eor #$ff + + clc + adc temp + sta temp + lda temp+1 + adc #$ff + sta temp+1 +.endrepeat + rts + +.macro add_do_ch +do_ch_jsr: + .local skipHR1, skipHR2, end + ldx ch + lda hrc, x + beq skipHR1 + + lda #0 + sta hrc, x +.if HR_ADSR <> 0 + lda env_reset, x + beq :+ + lda #0 + sta env_reset, x + + lda #TEST_AD + sta ad, x + lda #TEST_SR + sta sr, x + lda wav, x + and #255^1 + ora test_reset, x + sta wav, x +: +.else + lda inst_buffer, x + tax + lda insFL, x + sta patzp + lda insFH, x + sta patzp+1 + ldx ch + ldy #1 + lda (patzp), y + sta ad, x + iny + lda (patzp), y + ldy base + sta sr, x + lda wav, x + and #255^1 + ora test_reset, x + sta wav, x +.endif + lda #0 + sta doMacroA, x + sta doMacroD, x + sta doMacroW, x + +skipHR1: + + lda hrframe, x + cmp #4 + bne :+ + jmp skipHR2 +: + + inc hrframe, x + +.if compat_hr = 0 + cmp #2 +.else + cmp #1 +.endif + beq :+ + jmp skipHR2 +: + + ldx ch + + ; for 1Axx + lda note_temp, x + sta note_n, x + + lda #0 + sta mframeA, x + sta mframeD, x + sta mframeW, x + lda #$ff + sta doMacroA, x + sta doMacroD, x + sta doMacroW, x + + lda inst_buffer, x + tax + lda insFL, x + sta patzp + lda insFH, x + sta patzp+1 + + ldx ch + ldy #1 + lda (patzp), y + sta ad, x + iny + lda (patzp), y + sta sr, x + + iny + lda (patzp), y + sta duty_lo, x + iny + lda (patzp), y + sta duty_hi, x + + iny + lda (patzp), y + sta flags_temp + and #1 + ;tay + ;lda table_1_to_ff, y + sta abspw, x + + lda flags_temp + and #2 + beq :+ + lda #0 + sta pw_mod_lo, x + sta pw_mod_hi, x +: + + lda flags_temp + and #4 + tay + ldx chipnum + lda res, x + ldx chm + and ch_filter_enable_inv, x + cpy #0 + beq :+ + ora ch_filter_enable, x +: + ldx chipnum + sta res, x + + lda flags_temp + and #8 + beq :++ + ldx chipnum + lda #0 + sta doMacroC, x + lda res, x + and #$0f + ldy #6 + ora (patzp), y + sta res, x + iny + lda vol, x + and #$0f + ora (patzp), y + sta vol, x + iny + lda (patzp), y + sta fil_lo_n, x + iny + lda (patzp), y + sta fil_hi_n, x + + lda flags_temp + and #32 + bne :++ + lda triggered_fil, x + beq :+ + lda retrigger_fil, x + beq :++ +: + lda #$ff + sta triggered_fil, x + lda fil_lo_n, x + sta fil_lo, x + lda fil_hi_n, x + sta fil_hi, x +: + + ldx ch + lda inst_buffer, x + cmp inst_prev, x + beq :+ + ldx chipnum + lda fil_lo_n, x + sta fil_lo, x + lda fil_hi_n, x + sta fil_hi, x + ldx ch + lda inst_buffer, x + sta inst_prev, x +: + + lda flags_temp + and #32 + beq :+ + ldx ch + lda inst_buffer, x + ldx chipnum + sta instF, x + lda #0 + sta mframeC, x + lda #$ff + sta doMacroC, x + + lda flags_temp + and #16 + lsr + tay + lda table_1_to_ff, y + ldy chipnum + sta absfil, y + +: + + lda flags_temp + and #64 + lsr + lsr + lsr + ldx ch + sta test_reset, x + + lda retrigger_pw, x + beq :+ + lda #0 + sta pw_mod_lo, x + sta pw_mod_hi, x +: + + lda mframeW, x + beq :+ + ldy #0 + lda (patzp), y + and #$0f + sta temp + lda wav, x + and #%11110000 + ora #1 + ora temp + sta wav, x + jmp skipHR2 +: + ldx ch + ldy #0 + lda (patzp), y + ora #1 + sta wav, x +skipHR2: + rts + +.endmacro + +add_do_ch + +.macro add_do_ch_DIGI +do_ch_DIGI: + .local skipHR1, skipHR2, skipHR_ADSR, end + + ldx #3 + jsr doFinepitch + +.repeat 4 + clc + lsr temp+1 + ror temp +.endrepeat + + lda temp + sta nmi_freq_lo+1 + lda temp+1 + sta nmi_freq_hi+1 + + ldx ch + lda hrc, x + beq skipHR1 + + lda #0 + sta hrc, x + sta doMacroA, x + sta doMacroD, x + sta doMacroW, x + +skipHR1: + + lda hrframe, x + cmp #4 + bne :+ + jmp skipHR2 +: + + inc hrframe, x + +.if compat_hr = 0 + cmp #2 +.else + cmp #1 +.endif + beq :+ + jmp skipHR_ADSR +: + + ldx ch + lda #0 + sta mframeA, x + sta mframeD, x + sta mframeW, x + lda #$ff + sta doMacroA, x + sta doMacroD, x + sta doMacroW, x + + lda inst_buffer, x + tax + lda insSI, x + tax + lda sampleHS, x + sta nmi_add+2 + lda #0 + sta nmi_add+1 + lda sampleHE, x + sta nmi_cmp+1 + sta nmi_cmp2+1 + +skipHR_ADSR: + +skipHR2: + rts + +.endmacro + +.if DIGI <> 0 + add_do_ch_DIGI +.endif + +.proc playaddr +.if DIGI <> 0 + lda #0 + sta ldn+1 + jsr NMI_BUFFER +.endif + + ldx tick_sel + inc tick + lda tick + cmp tick_speeds, x + bcs :+ + jmp skipseq +: + lda #0 + sta tick + +advance_tick: + + lda tick_sel + eor #1 + sta tick_sel + ldx #(CHIP_AMT)-1 + lda #0 +: + sta fil_st2, x + dex + bpl :- + + + .repeat chnum, I + lda #I + sta ch + lda #I/3 + sta chipnum + jsr advance + .endrepeat + + lda nextpat + beq skipnextpat + lda #0 + sta nextpat + lda jumppat + beq :+ + lda #0 + sta jumppat + jmp :++ +: + inc patind + lda patind + cmp #order0len + bne :+ + lda #0 ; #patloop + sta patind +: + jsr set_patseq + ldx #chnum-1 + lda #1 +durloop: + sta dur, x + dex + bpl durloop + jmp advance_tick +skipnextpat: + lda jumppat + beq :+ + lda #$ff + sta nextpat +: +skipseq: + +.if DIGI = 0 +.repeat chnum, I + ldx #I + stx ch + lda #I .mod 3 + sta chm + lda #(I .mod 3)*7+(I/3)*$20 + sta base + lda #I/3 + sta chipnum + jsr do_ch_jsr + ldx ch + lda #$ff + sta env_reset_buf, x +.endrepeat +.else +.repeat 4, I + ldx #I + stx ch + lda #I .mod 3 + sta chm + lda #(I .mod 3)*7+(I/3)*$20 + sta base + lda #I/3 + sta chipnum + .if I = 3 + jsr do_ch_DIGI + .else + jsr do_ch_jsr + .endif + ldx ch + lda #$ff + sta env_reset_buf, x +.endrepeat +.endif + + +.repeat chnum, I + lda #I + sta ch + jsr insarp + jsr inswave + jsr insduty +.endrepeat + +.repeat CHIP_AMT, I + lda #I + sta ch + jsr inscut + ldx ch + lda fil_st2, x + beq :+ + lda fil_lo_n2, x + sta fil_lo, x + lda fil_hi_n2, x + sta fil_hi, x +: + +.endrepeat + + ldx #chnum-1 +note_cut_loop: + lda cut_dur, x + cmp #$ff + beq note_cut_loop_end + dec cut_dur, x + lda cut_dur, x + bne note_cut_loop_end + + lda #$ff + sta cut_dur, x + + lda wav, x + and #%11111110 + sta wav, x + +note_cut_loop_end: + dex + bpl note_cut_loop + + ldx #chnum-1 +relslide_loop: + lda note_dest, x + and #$80 + beq slide_skip + eor note_dest, x + sta macroIns + lda slide_amt_sign, x + beq positive_slide2 + lda note_n, x + clc + adc macroIns + jsr clamp_note + sta note_dest, x + jmp slide_skip +positive_slide2: + lda note_n, x + sec + sbc macroIns + jsr clamp_note + sta note_dest, x +slide_skip: + dex + bpl relslide_loop + + ldx #chnum-1 +note_loop: + lda absarp, x + beq nrel + lda arp, x + and #127 + jmp nout +nrel: + lda note_n, x + clc + ;adc arp, x +nout: + ;clc + jsr add_arpeff + jsr clamp_note + tay + clc + lda note_table_lo, y + adc slide_buffer_lo, x + sta note_pitch_lo, x + lda note_table_hi, y + adc slide_buffer_hi, x + sta note_pitch_hi, x + dex + bpl note_loop + + ldx #chnum-1 +slide_loop: + lda slide_amt, x + beq slide_loop2 + + lda slide_amt_sign, x + bne positive_slide + sec + lda slide_buffer_lo, x + sbc slide_amt, x + sta slide_buffer_lo, x + bcs :+ + dec slide_buffer_hi, x +: + + ldy note_dest, x + lda note_table_lo, y + sec + sbc note_pitch_lo, x + lda note_table_hi, y + sbc note_pitch_hi, x + bcc slide_loop2 + jmp finish_slide +positive_slide: + clc + lda slide_buffer_lo, x + adc slide_amt, x + sta slide_buffer_lo, x + bcc :+ + inc slide_buffer_hi, x +: + jmp :+ +finish_slide: + lda note_dest, x + sta note_n, x + lda #0 + sta slide_buffer_lo, x + sta slide_buffer_hi, x + sta slide_amt, x + sta slide_amt_sign, x + jmp slide_loop2 +: + ldy note_dest, x + lda note_pitch_lo, x + sec + sbc note_table_lo, y + lda note_pitch_hi, x + sbc note_table_hi, y + bcc slide_loop2 + jmp finish_slide + +slide_loop2: + dex + bpl slide_loop + + ldx #chnum-1 +: + lda note_tick, x + cmp #96 + beq note_tick_loop + inc note_tick, x +note_tick_loop: + + lda has_played, x + bne note_tick_loop2 + lda #3 + sta note_tick, x +note_tick_loop2: + dex + bpl :- + +.if DIGI = 0 +lda vol +sta $d418 +.if chnum >= 6 +lda vol+1 +sta $d438 +.endif +.if chnum >= 9 +lda vol+2 +sta $d458 +.endif +.if chnum >= 12 +lda vol+3 +sta $d478 +.endif +.endif + +lda res +sta $d417 +.if chnum >= 6 +lda res+1 +sta $d437 +.endif +.if chnum >= 9 +lda res+2 +sta $d457 +.endif +.if chnum >= 12 +lda res+3 +sta $d477 +.endif + +lda fil_lo +sta temp +lda fil_hi +sta temp+1 + +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp + +lda temp +sta $d416 + +.if chnum >= 6 +lda fil_lo+1 +sta temp +lda fil_hi+1 +sta temp+1 + +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp + +lda temp +sta $d436 +.endif + +.if chnum >= 9 +lda fil_lo+2 +sta temp +lda fil_hi+2 +sta temp+1 + +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp + +lda temp +sta $d456 +.endif + +.if chnum >= 12 +lda fil_lo+2 +sta temp +lda fil_hi+2 +sta temp+1 + +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp +clc +lsr temp+1 +ror temp + +lda temp +sta $d476 +.endif + + ldx #chnum-1 +note_loop3: + lda absarp, x + beq nrel3 + lda arp, x + and #127 + jmp nout3 +nrel3: + lda note_n, x + clc + adc arp, x +nout3: + clc + jsr add_arpeff + jsr clamp_note + tay + clc + lda note_table_lo, y + adc slide_buffer_lo, x + sta note_pitch_lo, x + lda note_table_hi, y + adc slide_buffer_hi, x + sta note_pitch_hi, x + dex + bpl note_loop3 + +.repeat CHIP_AMT, J + ldx #2 +: + txa + clc + adc #J*3 + tax + jsr doFinepitch + txa + sec + sbc #J*3 + tax + + ldy ch_mul_tabl, x + lda temp + sta $d400+J*$20,y + lda temp+1 + sta $d401+J*$20, y + + lda ad+J*3, x + sta $d405+J*$20, y + lda sr+J*3, x + sta $d406+J*$20, y + + lda wav+J*3, x + sta $d404+J*$20, y + lda duty_lo+J*3, x + clc + adc pw_mod_lo+J*3, x + sta $d402+J*$20, y + lda duty_hi+J*3, x + adc pw_mod_hi+J*3, x + and #$0f + sta $d403+J*$20, y + + dex + bpl :- +.endrepeat + rts +.endproc + +set_patseq: + stx temp+2 + + ldx patind + + .repeat chnum, I + lda .ident(.concat ("order", .sprintf("%d",I), "L")), x + sta patseq+0+2*I + lda .ident(.concat ("order", .sprintf("%d",I), "H")), x + sta patseq+1+2*I + .endrepeat + + ldx temp+2 + rts + +set_patseq_init: + .repeat chnum, I + ldx patind + lda .ident(.concat ("order", .sprintf("%d",I), "L")), x + sta patseq+0+2*I + lda .ident(.concat ("order", .sprintf("%d",I), "H")), x + sta patseq+1+2*I + .endrepeat + rts + +add_arpeff: + pha + inc arpind, x + ldy arpind, x + lda arp_mod, y + sta arpind, x + tay + pla + cpy #1 + beq arp1 + cpy #2 + beq arp2 + rts + +arp1: + clc + adc arpeff1, x + rts + +arp2: + clc + adc arpeff2, x + rts + +arp_mod: +.byte 0,1,2,0 + +ch_mul_tabl: +.byte 0,7,14 + +clamp_note: + cmp #95 + bcc :+ + lda #95 +: + rts + +note_table_lo: + .incbin "note_lo.bin" +note_table_hi: + .incbin "note_hi.bin" + +ch_filter_enable: +.byte 1, 2, 4 +ch_filter_enable_inv: +.byte 255^1, 255^2, 255^4 + +triangle_lookup: + .repeat 64, I + .if (I+0)&32 + .byte ((32-(((I+0)&63)-32)-1)>>1)<<4 + .else + .byte (((I+0)&63)>>1)<<4 + .endif + .endrepeat + +tri_vibrato_lookup: + .repeat 16, J + .repeat 16, I + ;.byte ((I*((J>>1)-15)*2)/15)+$1f + VAL .set ((I*((J<<1)-15)*2)/3) + .if (VAL+$80) < 0 + .byte 0 + .elseif (VAL+$80) > 255 + .byte $ff + .else + .byte VAL+$80 + .endif + .endrepeat + .endrepeat + +.include "song.asm" + +;.res 4096, $00 \ No newline at end of file diff --git a/loader/samples/minexample/furC64/asm/note_hi.bin b/loader/samples/minexample/furC64/asm/note_hi.bin new file mode 100644 index 0000000..a472973 --- /dev/null +++ b/loader/samples/minexample/furC64/asm/note_hi.bin @@ -0,0 +1,3 @@ + + +  "$')+.147:>AEINRW\bhnu| \ No newline at end of file diff --git a/loader/samples/minexample/furC64/asm/note_lo.bin b/loader/samples/minexample/furC64/asm/note_lo.bin new file mode 100644 index 0000000..ee26c5b --- /dev/null +++ b/loader/samples/minexample/furC64/asm/note_lo.bin @@ -0,0 +1 @@ +&8K^s ,MqBsY,{'Q67YN Ϣmgo:Ddu8&?"ȴqLh8Eh$ \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/__init__.py b/loader/samples/minexample/furC64/chipchune/__init__.py new file mode 100644 index 0000000..fd53fbd --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/__init__.py @@ -0,0 +1,18 @@ +""" +:mod:`chipchune` is a Python library for manipulating several +different kinds of chiptune music files. + +Currently supports: + - Furnace (:mod:`chipchune.furnace`) (almost!) + +Plans to support: + - DefleMask (:mod:`chipchune.deflemask`) + - FamiTracker (:mod:`chipchune.famitracker`) + +### Installation + +`pip install git+https://github.com/ZoomTen/chipchune@master` + +""" + +__version__ = "0.0.1" diff --git a/loader/samples/minexample/furC64/chipchune/_util.py b/loader/samples/minexample/furC64/chipchune/_util.py new file mode 100644 index 0000000..4fa2842 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/_util.py @@ -0,0 +1,98 @@ +import struct +from enum import Enum +from typing import BinaryIO, Any, cast +import io + +known_sizes = { + 'c': 1, + 'b': 1, 'B': 1, + '?': 1, + 'h': 2, 'H': 2, + 'i': 4, 'I': 4, + 'l': 4, 'L': 4, + 'q': 8, 'Q': 8, + 'e': 2, 'f': 4, + 'd': 8 +} + + +class EnumShowNameOnly(Enum): + """ + Just an Enum, except its string repr is + just the enum's name + """ + def __repr__(self) -> str: + return self.name + + def __str__(self) -> str: + return self.__repr__() + + +class EnumValueEquals(Enum): + """ + Enum that can be compared to its raw value. + """ + def __eq__(self, other: Any) -> bool: + return cast(bool, self.value == other) + + +def truthy_to_boolbyte(value: Any) -> bytes: + """ + If value is truthy, output b'\x01'. Else output b'\x00'. + + :param value: anything + """ + if value: + return b'\x01' + else: + return b'\x00' + + +# these are just to make the typehinter happy +# cast(dolphin, foobar) should've been named trust_me_bro_im_a(dolphin, foobar) + + +def read_int(file: BinaryIO, signed: bool = False) -> int: + """ + 4 bytes + """ + if signed: + return cast(int, struct.unpack(' int: + """ + 2 bytes + """ + if signed: + return cast(int, struct.unpack(' int: + """ + 1 bytes + """ + if signed: + return cast(int, struct.unpack(' float: + """ + 4 bytes + """ + return cast(float, struct.unpack(' str: + """ + variable string (ends in \\x00) + """ + buffer = bytearray() + char = file.read(1) + while char != b'\x00': + buffer += char + char = file.read(1) + return buffer.decode('utf-8') diff --git a/loader/samples/minexample/furC64/chipchune/deflemask/__init__.py b/loader/samples/minexample/furC64/chipchune/deflemask/__init__.py new file mode 100644 index 0000000..9399e49 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/deflemask/__init__.py @@ -0,0 +1,3 @@ +""" +soon! +""" \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/famitracker/__init__.py b/loader/samples/minexample/furC64/chipchune/famitracker/__init__.py new file mode 100644 index 0000000..9399e49 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/famitracker/__init__.py @@ -0,0 +1,3 @@ +""" +soon! +""" \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/furnace/__init__.py b/loader/samples/minexample/furC64/chipchune/furnace/__init__.py new file mode 100644 index 0000000..32575fc --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/furnace/__init__.py @@ -0,0 +1,24 @@ +""" +Tools to manipulate Furnace .fur files. + +- :mod:`chipchune.furnace.module`: Tools to inspect and manipulate module files. +- :mod:`chipchune.furnace.instrument`: Tools to inspect and manipulate instrument data from within or without the module. +- :mod:`chipchune.furnace.sample`: Tools to inspect and manipulate sample data (might be merged with inst?) +- :mod:`chipchune.furnace.wavetable`: Tools to inspect and manipulate wavetable data +- :mod:`chipchune.furnace.enums`: Various constants that apply to Furnace. +- :mod:`chipchune.furnace.data_types`: Various data types that apply to Furnace. + + +### Example + + from chipchune.furnace.module import FurnaceModule + + module = FurnaceModule("tests/samples/furnace/skate_or_die.143.fur") + + pattern = module.get_pattern(0, 0, 0) + + print(pattern.as_clipboard()) + + for row in pattern.data: + print(row) +""" diff --git a/loader/samples/minexample/furC64/chipchune/furnace/data_types.py b/loader/samples/minexample/furC64/chipchune/furnace/data_types.py new file mode 100644 index 0000000..0d5415e --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/furnace/data_types.py @@ -0,0 +1,706 @@ +from dataclasses import dataclass, field +from typing import Tuple, List, TypedDict, Any, Union, Dict + +from .enums import ( + ChipType, LinearPitch, LoopModality, DelayBehavior, JumpTreatment, InputPortSet, OutputPortSet, + InstrumentType, MacroCode, OpMacroCode, MacroType, MacroItem, GBHwCommand, WaveFX, ESFilterMode, + SNESSusMode, GainMode, Note +) + + +# modules +@dataclass +class ChipInfo: + """ + Information on a single chip. + """ + type: ChipType + #: shall be a simple dict, no enums needed + flags: Dict[str, Any] = field(default_factory=dict) + panning: float = 0.0 + surround: float = 0.0 + """ + Chip front/rear balance. + """ + volume: float = 1.0 + + +@dataclass +class ModuleMeta: + """ + Module metadata. + """ + name: str = '' + name_jp: str = '' + author: str = '' + author_jp: str = '' + album: str = '' + """ + Can also be the game name or container name. + """ + album_jp: str = '' + sys_name: str = 'Sega Genesis/Mega Drive' + sys_name_jp: str = '' + comment: str = '' + version: int = 0 + tuning: float = 440.0 + + +@dataclass +class TimingInfo: + """ + Timing information for a single subsong. + """ + arp_speed = 1 + clock_speed = 60.0 + highlight: Tuple[int, int] = (4, 16) + speed: Tuple[int, int] = (0, 0) + timebase = 1 + virtual_tempo: Tuple[int, int] = (150, 150) + + +@dataclass +class ChipList: + """ + Information about chips used in the module. + """ + list: List[ChipInfo] = field(default_factory=list) + master_volume: float = 2.0 + + +@dataclass(repr=False) +class ChannelDisplayInfo: + """ + Relating to channel display in Pattern and Order windows. + """ + name: str = '' + abbreviation: str = '' + collapsed: bool = False + shown: bool = True + + def __repr__(self) -> str: + return "ChannelDisplayInfo(name='%s', abbreviation='%s', collapsed=%s, shown=%s)" % ( + self.name, + self.abbreviation, + self.collapsed, + self.shown + ) + + +@dataclass +class ModuleCompatFlags: + """ + Module compatibility flags, a.k.a. "The Motherload" + + Default values correspond with fileOps.cpp in the furnace src. + """ + + # compat 1 + + limit_slides: bool = False + linear_pitch: LinearPitch = field(default_factory=lambda: LinearPitch.FULL_LINEAR) + loop_modality: LoopModality = field(default_factory=lambda: LoopModality.DO_NOTHING) + proper_noise_layout: bool = True + wave_duty_is_volume: bool = False + reset_macro_on_porta: bool = False + legacy_volume_slides: bool = False + compatible_arpeggio: bool = False + note_off_resets_slides: bool = True + target_resets_slides: bool = True + arpeggio_inhibits_portamento: bool = False + wack_algorithm_macro: bool = False + broken_shortcut_slides: bool = False + ignore_duplicates_slides: bool = False + stop_portamento_on_note_off: bool = False + continuous_vibrato: bool = False + broken_dac_mode: bool = False + one_tick_cut: bool = False + instrument_change_allowed_in_porta: bool = True + reset_note_base_on_arpeggio_stop: bool = True + + # compat 2 (>= dev70) + + broken_speed_selection: bool = False + no_slides_on_first_tick: bool = False + next_row_reset_arp_pos: bool = False + ignore_jump_at_end: bool = False + buggy_portamento_after_slide: bool = False + gb_ins_affects_env: bool = True + shared_extch_state: bool = True + ignore_outside_dac_mode_change: bool = False + e1e2_takes_priority: bool = False + new_sega_pcm: bool = True + weird_fnum_pitch_slides: bool = False + sn_duty_resets_phase: bool = False + linear_pitch_macro: bool = True + pitch_slide_speed_in_linear: int = 4 + old_octave_boundary: bool = False + disable_opn2_dac_volume_control: bool = False + new_volume_scaling: bool = True + volume_macro_lingers: bool = True + broken_out_vol: bool = False + e1e2_stop_on_same_note: bool = False + broken_porta_after_arp: bool = False + sn_no_low_periods: bool = False + cut_delay_effect_policy: DelayBehavior = field(default_factory=lambda: DelayBehavior.LAX) + jump_treatment: JumpTreatment = field(default_factory=lambda: JumpTreatment.ALL_JUMPS) + auto_sys_name: bool = True + disable_sample_macro: bool = False + broken_out_vol_2: bool = False + old_arp_strategy: bool = False + + # not-a-compat (>= dev135) + + auto_patchbay: bool = True + + # compat 3 (>= dev138) + + broken_porta_during_legato: bool = False + + broken_fm_off: bool = False + pre_note_no_effect: bool = False + old_dpcm: bool = False + reset_arp_phase_on_new_note: bool = False + ceil_volume_scaling: bool = False + old_always_set_volume: bool = False + old_sample_offset: bool = False + + +@dataclass +class SubSong: + """ + Information on a single subsong. + """ + name: str = '' + comment: str = '' + speed_pattern: List[int] = field(default_factory=lambda: [6]) + """ + Maximum 16 entries. + """ + grooves: List[List[int]] = field(default_factory=list) + timing: TimingInfo = field(default_factory=TimingInfo) + pattern_length = 64 + order: Dict[int, List[int]] = field(default_factory=lambda: { + 0: [0], 1: [0], 2: [0], 3: [0], 4: [0], + 5: [0], 6: [0], 7: [0], 8: [0], 9: [0] + }) + effect_columns: List[int] = field(default_factory=lambda: [ + 1 for _ in range( + ChipType.YM2612.channels + ChipType.SMS.channels + ) + ]) + channel_display: List[ChannelDisplayInfo] = field(default_factory=lambda: [ + ChannelDisplayInfo() for _ in range( + ChipType.YM2612.channels + ChipType.SMS.channels + ) + ]) + + +@dataclass +class FurnaceRow: + """ + Represents a single row in a pattern. + """ + note: Note + octave: int + instrument: int + volume: int + effects: List[Tuple[int, int]] = field(default_factory=list) + + def as_clipboard(self) -> str: + """ + Renders the selected row in Furnace clipboard format (without header!) + + :return: Furnace clipboard data (str) + """ + note_maps = { + Note.Cs: "C#", + Note.D_: "D-", + Note.Ds: "D#", + Note.E_: "E-", + Note.F_: "F-", + Note.Fs: "F#", + Note.G_: "G-", + Note.Gs: "G#", + Note.A_: "A-", + Note.As: "A#", + Note.B_: "B-", + Note.C_: "C-", + } + if self.note == Note.OFF: + note_str = "OFF" + elif self.note == Note.OFF_REL: + note_str = "===" + elif self.note == Note.REL: + note_str = "REL" + elif self.note == Note.__: + note_str = "..." + else: + note_str = "%s%d" % (note_maps[self.note], self.octave) + + vol = ".." if self.volume==0xffff else "%02X" % self.volume + ins = ".." if self.instrument==0xffff else "%02X" % self.instrument + + rep_str = "%s%s%s" + + for fx in self.effects: + cmd, val = fx + cmd_str = ".." if cmd == 0xffff else "%02X" % cmd + val_str = ".." if val == 0xffff else "%02X" % val + rep_str += "%s%s" % (cmd_str, val_str) + + return rep_str % ( + note_str, + ins, vol + ) + "|" + + def __str__(self) -> str: + if self.note == Note.OFF: + note_str = "OFF" + elif self.note == Note.OFF_REL: + note_str = "===" + elif self.note == Note.REL: + note_str = "///" + elif self.note == Note.__: + note_str = "---" + else: + note_str = "%s%d" % (self.note, self.octave) + + vol = "--" if self.volume==0xffff else "%02x" % self.volume + ins = "--" if self.instrument==0xffff else "%02x" % self.instrument + + rep_str = "row data: %s %s %s" + + for fx in self.effects: + cmd, val = fx + cmd_str = "--" if cmd == 0xffff else "%02x" % cmd + val_str = "--" if val == 0xffff else "%02x" % val + rep_str += " %s%s" % (cmd_str, val_str) + + return "<" + rep_str % ( + note_str, + ins, vol + ) + ">" + + +@dataclass +class FurnacePattern: + """ + Represents one pattern in a module. + """ + channel: int = 0 + index: int = 0 + subsong: int = 0 + data: List[FurnaceRow] = field(default_factory=list) # yeah... + name: str = "" + + def as_clipboard(self) -> str: + """ + Renders the selected pattern in Furnace clipboard format. + + :return: Furnace clipboard data + """ + return "org.tildearrow.furnace - Pattern Data\n0\n" + "\n".join([x.as_clipboard() for x in self.data]) + + def __str__(self) -> str: + return "" % ( + self.name if len(self.name) > 0 else "%02x" % self.index, + self.channel, + self.subsong + ) + + +class InputPatchBayEntry(TypedDict): + """ + A patch that has an "input" connector. + """ + set: InputPortSet + """ + The set that the patch belongs to. + """ + port: int + """ + Which port to connect to. + """ + + +class OutputPatchBayEntry(TypedDict): + """ + A patch that has an "output" connector. + """ + set: OutputPortSet + """ + The set that the patch belongs to. + """ + port: int + """ + Which port to connect from. + """ + + +@dataclass +class PatchBay: + """ + A single patchbay connection. + """ + source: OutputPatchBayEntry + dest: InputPatchBayEntry + + +# instruments +@dataclass +class InsFeatureAbstract: + """ + Base class for all InsFeature* classes. Not really to be used. + """ + _code: str = field(init=False) + + def __post_init__(self) -> None: + if len(self._code) != 2: + raise ValueError('No code defined for this instrument feature') + + # def serialize(self) -> bytes: + # raise Exception('Method serialize() has not been overridden...') + + +@dataclass +class InsFeatureName(InsFeatureAbstract, str): + """ + Instrument's name block. Can be used as a string. + """ + _code = 'NA' + name: str = '' + + def __str__(self) -> str: + return self.name + + +@dataclass +class InsMeta: + version: int = 143 + type: InstrumentType = InstrumentType.FM_4OP + + +@dataclass +class InsFMOperator: + am: bool = False + ar: int = 0 + dr: int = 0 + mult: int = 0 + rr: int = 0 + sl: int = 0 + tl: int = 0 + dt2: int = 0 + rs: int = 0 + dt: int = 0 + d2r: int = 0 + ssg_env: int = 0 + dam: int = 0 + dvb: int = 0 + egt: bool = False + ksl: int = 0 + sus: bool = False + vib: bool = False + ws: int = 0 + ksr: bool = False + enable: bool = True + kvs: int = 2 + + +@dataclass +class InsFeatureFM(InsFeatureAbstract): + _code = 'FM' + alg: int = 0 + fb: int = 4 + fms: int = 0 + ams: int = 0 + fms2: int = 0 + ams2: int = 0 + ops: int = 2 + opll_preset: int = 0 + op_list: List[InsFMOperator] = field(default_factory=lambda: [ + InsFMOperator( + tl=42, ar=31, dr=8, + sl=15, rr=3, mult=5, + dt=5 + ), + InsFMOperator( + tl=48, ar=31, dr=4, + sl=11, rr=1, mult=1, + dt=5 + ), + InsFMOperator( + tl=18, ar=31, dr=10, + sl=15, rr=4, mult=1, + dt=0 + ), + InsFMOperator( + tl=2, ar=31, dr=9, + sl=15, rr=9, mult=1, + dt=0 + ), + ]) + + +@dataclass +class SingleMacro: + kind: Union[MacroCode, OpMacroCode] = field(default_factory=lambda: MacroCode.VOL) + mode: int = 0 + type: MacroType = field(default_factory=lambda: MacroType.SEQUENCE) + delay: int = 0 + speed: int = 1 + open: bool = False + data: List[Union[int, MacroItem]] = field(default_factory=list) + + +@dataclass +class InsFeatureMacro(InsFeatureAbstract): + _code = 'MA' + macros: List[SingleMacro] = field(default_factory=lambda: [SingleMacro()]) + + +@dataclass +class InsFeatureOpr1Macro(InsFeatureMacro): + _code = 'O1' + + +@dataclass +class InsFeatureOpr2Macro(InsFeatureMacro): + _code = 'O2' + + +@dataclass +class InsFeatureOpr3Macro(InsFeatureMacro): + _code = 'O3' + + +@dataclass +class InsFeatureOpr4Macro(InsFeatureMacro): + _code = 'O4' + + +@dataclass +class GBHwSeq: + command: GBHwCommand + data: List[int] = field(default_factory=lambda: [0, 0]) + + +@dataclass +class InsFeatureGB(InsFeatureAbstract): + _code = 'GB' + env_vol: int = 15 + env_dir: int = 0 + env_len: int = 2 + sound_len: int = 0 + soft_env: bool = False + always_init: bool = False + hw_seq: List[GBHwSeq] = field(default_factory=list) + + +@dataclass +class GenericADSR: + a: int = 0 + d: int = 0 + s: int = 0 + r: int = 0 + + +@dataclass +class InsFeatureC64(InsFeatureAbstract): + _code = '64' + tri_on: bool = False + saw_on: bool = True + pulse_on: bool = False + noise_on: bool = False + envelope: GenericADSR = field(default_factory=lambda: GenericADSR(a=0, d=8, s=0, r=0)) + duty: int = 2048 + ring_mod: int = 0 + osc_sync: int = 0 + to_filter: bool = False + vol_is_cutoff: bool = False + init_filter: bool = False + duty_is_abs: bool = False + filter_is_abs: bool = False + no_test: bool = False + res: int = 0 + cut: int = 0 + hp: bool = False + lp: bool = False + bp: bool = False + ch3_off: bool = False + + +@dataclass +class SampleMap: + freq: int = 0 + sample_index: int = 0 + + +@dataclass +class DPCMMap: + pitch: int = 0 + delta: int = 0 + + +@dataclass +class InsFeatureAmiga(InsFeatureAbstract): # Sample data + _code = 'SM' + init_sample: int = 0 + use_note_map: bool = False + use_sample: bool = False + use_wave: bool = False + wave_len: int = 31 + sample_map: List[SampleMap] = field(default_factory=lambda: [SampleMap() for _ in range(120)]) + + +@dataclass +class InsFeatureDPCMMap(InsFeatureAbstract): # DPCM sample data + _code = 'NE' + use_map: bool = False + sample_map: List[DPCMMap] = field(default_factory=lambda: [SampleMap() for _ in range(120)]) + + +@dataclass +class InsFeatureX1010(InsFeatureAbstract): + _code = 'X1' + bank_slot: int = 0 + + +@dataclass +class InsFeaturePowerNoise(InsFeatureAbstract): + _code = 'PN' + octave: int = 0 + + +@dataclass +class InsFeatureSID2(InsFeatureAbstract): + _code = 'S2' + noise_mode: int = 0 + wave_mix: int = 0 + volume: int = 0 + + +@dataclass +class InsFeatureN163(InsFeatureAbstract): + _code = 'N1' + wave: int = -1 + wave_pos: int = 0 + wave_len: int = 32 + wave_mode: int = 3 + + +@dataclass +class InsFeatureFDS(InsFeatureAbstract): # Virtual Boy + _code = 'FD' + mod_speed: int = 0 + mod_depth: int = 0 + init_table_with_first_wave: bool = False # compat + mod_table: List[int] = field(default_factory=lambda: [0 for i in range(32)]) + + +@dataclass +class InsFeatureMultiPCM(InsFeatureAbstract): + _code = 'MP' + ar: int = 15 + d1r: int = 15 + dl: int = 0 + d2r: int = 0 + rr: int = 15 + rc: int = 15 + lfo: int = 0 + vib: int = 0 + am: int = 0 + + +@dataclass +class InsFeatureWaveSynth(InsFeatureAbstract): + _code = 'WS' + wave_indices: List[int] = field(default_factory=lambda: [0, 0]) + rate_divider: int = 1 + effect: WaveFX = WaveFX.NONE + enabled: bool = False + global_effect: bool = False + speed: int = 0 + params: List[int] = field(default_factory=lambda: [0, 0, 0, 0]) + one_shot: bool = False # not read? + + +@dataclass +class InsFeatureSoundUnit(InsFeatureAbstract): + _code = 'SU' + switch_roles: bool = False + + +@dataclass +class InsFeatureES5506(InsFeatureAbstract): + _code = 'ES' + filter_mode: ESFilterMode = ESFilterMode.LPK2_LPK1 + k1: int = 0xffff + k2: int = 0xffff + env_count: int = 0 + left_volume_ramp: int = 0 + right_volume_ramp: int = 0 + k1_ramp: int = 0 + k2_ramp: int = 0 + k1_slow: int = 0 + k2_slow: int = 0 + + +@dataclass +class InsFeatureSNES(InsFeatureAbstract): + _code = 'SN' + use_env: bool = True + sus: SNESSusMode = SNESSusMode.DIRECT + gain_mode: GainMode = GainMode.DIRECT + gain: int = 127 + d2: int = 0 + envelope: GenericADSR = field(default_factory=lambda: GenericADSR(a=15, d=7, s=7, r=0)) + + +@dataclass +class InsFeatureOPLDrums(InsFeatureAbstract): + _code = 'LD' + fixed_drums: bool = False + kick_freq: int = 1312 + snare_hat_freq: int = 1360 + tom_top_freq: int = 448 + + +@dataclass +class _InsFeaturePointerAbstract(InsFeatureAbstract): + """ + Also not really to be used. Container for all "list" features. + """ + _code = 'LL' + pointers: Dict[int, int] = field(default_factory=dict) + + +@dataclass +class InsFeatureSampleList(_InsFeaturePointerAbstract): + """ + List of pointers to all samples used by this instrument. + """ + _code = 'SL' + + +@dataclass +class InsFeatureWaveList(_InsFeaturePointerAbstract): + """ + List of pointers to all wave tables used by this instrument. + """ + _code = 'WL' + +@dataclass +class WavetableMeta: + name: str = '' + width: int = 32 + height: int = 32 + +@dataclass +class SampleMeta: + name: str = '' + length: int = 0 + sample_rate: int = 0 + bitdepth: int = 0 + loop_start: int = 0 + loop_end: int = 0 diff --git a/loader/samples/minexample/furC64/chipchune/furnace/enums.py b/loader/samples/minexample/furC64/chipchune/furnace/enums.py new file mode 100644 index 0000000..d8b29c8 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/furnace/enums.py @@ -0,0 +1,648 @@ +from chipchune._util import EnumShowNameOnly, EnumValueEquals +from typing import Tuple + +class LinearPitch(EnumShowNameOnly, EnumValueEquals): + """ + Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.linear_pitch`. + """ + NON_LINEAR = 0 + ONLY_PITCH_CHANGE = 1 + FULL_LINEAR = 2 + + +class LoopModality(EnumShowNameOnly, EnumValueEquals): + """ + Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.loop_modality`. + """ + HARD_RESET_CHANNELS = 0 + SOFT_RESET_CHANNELS = 1 + DO_NOTHING = 2 + + +class DelayBehavior(EnumShowNameOnly, EnumValueEquals): + """ + Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.cut_delay_effect_policy`. + """ + STRICT = 0 + BROKEN = 1 + LAX = 2 + + +class JumpTreatment(EnumShowNameOnly, EnumValueEquals): + """ + Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.jump_treatment`. + """ + ALL_JUMPS = 0 + FIRST_JUMP_ONLY = 1 + ROW_JUMP_PRIORITY = 2 + + +class Note(EnumShowNameOnly): + """ + All notes recognized by Furnace + """ + __ = 0 + Cs = 1 + D_ = 2 + Ds = 3 + E_ = 4 + F_ = 5 + Fs = 6 + G_ = 7 + Gs = 8 + A_ = 9 + As = 10 + B_ = 11 + C_ = 12 + OFF = 100 + OFF_REL = 101 + REL = 102 + + +class MacroItem(EnumShowNameOnly): + """ + Special values used only in this parser, to allow data editing similar to that + of Furnace itself. + """ + LOOP = 0 + RELEASE = 1 + + +class MacroCode(EnumShowNameOnly, EnumValueEquals): + """ + Marks what aspect of an instrument does a macro change. + """ + + VOL = 0 + """ + Also: + - C64 cutoff + """ + + ARP = 1 + """ + Not applicable to MSM6258 and MSM6295. + """ + + DUTY = 2 + """ + Also: + - AY noise freq + - POKEY audctl + - Mikey duty/int + - MSM5232 group ctrl + - Beeper/Pokemon Mini pulse width + - T6W28 noise type + - Virtual Boy noise length + - PC Engine/Namco/WonderSwan noise type + - SNES noise freq + - Namco 163 waveform pos. + - ES5506 filter mode + - MSM6258/MSM6295 freq. divider + - ADPCMA global volume + - QSound echo level + """ + + WAVE = 3 + """ + Also: + - OPLL patch + - OPZ/OPM lfo1 shape + """ + + PITCH = 4 + + EX1 = 5 + """ + - OPZ/OPM am depth + - C64 filter mode + - SAA1099 envelope + - X1-010 env. mode + - Namco 163 wave length + - FDS mod depth + - TSU cutoff + - ES5506 filter k1 + - MSM6258 clk divider + - QSound echo feedback + - SNES special + - MSM5232 group attack + - AY8930 duty? + """ + + EX2 = 6 + """ + - C64 resonance + - Namco 163 wave update + - FDS mod speed + - TSU resonance + - ES5506 filter k2 + - QSound echo length + - SNES gain + - MSM5232 group decay + - AY3/AY8930 envelope + """ + + EX3 = 7 + """ + - C64 special + - AY/AY8930 autoenv num + - X1-010 autoenv num + - Namco 163 waveload wave + - FDS mod position + - TSU control + - MSM5232 noise + """ + + ALG = 8 + """ + Also: + - AY/AY8930 autoenv den + - X1-010 autoenv den + - Namco 163 waveload pos + - ES5506 control + """ + + FB = 9 + """ + Also: + - AY8930 noise & mask + - Namco 163 waveload len + - ES5506 outputs + """ + + FMS = 10 + """ + Also: + - AY8930 noise | mask + - Namco 163 waveload trigger + """ + + AMS = 11 + + PAN_L = 12 + + PAN_R = 13 + + PHASE_RESET = 14 + + EX4 = 15 + """ + - C64 test/gate + - TSU phase reset timer + - FM/OPM opmask + """ + + EX5 = 16 + """ + - OPZ am depth 2 + """ + + EX6 = 17 + """ + - OPZ pm depth 2 + """ + + EX7 = 18 + """ + - OPZ lfo2 speed + """ + + EX8 = 19 + """ + - OPZ lfo2 shape + """ + + STOP = 255 + """ + Marks end of macro reading. + """ + + +class OpMacroCode(EnumShowNameOnly, EnumValueEquals): + """ + Controls which FM parameter a macro should change. + """ + AM = 0 + AR = 1 + DR = 2 + MULT = 3 + RR = 4 + SL = 5 + TL = 6 + DT2 = 7 + RS = 8 + DT = 9 + D2R = 10 + SSG_EG = 11 + DAM = 12 + DVB = 13 + EGT = 14 + KSL = 15 + SUS = 16 + VIB = 17 + WS = 18 + KSR = 19 + + +class MacroType(EnumShowNameOnly): + """ + Instrument macro type (version 120+). + """ + SEQUENCE = 0 + ADSR = 1 + LFO = 2 + + +class MacroSize(EnumShowNameOnly): + """ + Type of value stored in the instrument file. + """ + _value_: int + num_bytes: int + signed: bool + + UINT8: Tuple[int, int, bool] = (0, 1, False) + INT8: Tuple[int, int, bool] = (1, 1, True) + INT16: Tuple[int, int, bool] = (2, 2, True) + INT32: Tuple[int, int, bool] = (3, 4, True) + + def __new__(cls, id: int, num_bytes: int, signed: bool): # type: ignore[no-untyped-def] + member = object.__new__(cls) + member._value_ = id + setattr(member, 'num_bytes', num_bytes) + setattr(member, 'signed', signed) + return member + + +class GBHwCommand(EnumShowNameOnly): + """ + Game Boy hardware envelope commands. + """ + ENVELOPE = 0 + SWEEP = 1 + WAIT = 2 + WAIT_REL = 3 + LOOP = 4 + LOOP_REL = 5 + + +class SampleType(EnumShowNameOnly): + """ + Sample types used in Furnace + """ + ZX_DRUM = 0 + NES_DPCM = 1 + QSOUND_ADPCM = 4 + ADPCM_A = 5 + ADPCM_B = 6 + X68K_ADPCM = 7 + PCM_8 = 8 + SNES_BRR = 9 + VOX = 10 + PCM_16 = 16 + + +class InstrumentType(EnumShowNameOnly): + """ + Instrument types currently available as of version 144. + """ + STANDARD = 0 + FM_4OP = 1 + GB = 2 + C64 = 3 + AMIGA = 4 + PCE = 5 + SSG = 6 + AY8930 = 7 + TIA = 8 + SAA1099 = 9 + VIC = 10 + PET = 11 + VRC6 = 12 + FM_OPLL = 13 + FM_OPL = 14 + FDS = 15 + VB = 16 + N163 = 17 + KONAMI_SCC = 18 + FM_OPZ = 19 + POKEY = 20 + PC_BEEPER = 21 + WONDERSWAN = 22 + LYNX = 23 + VERA = 24 + X1010 = 25 + VRC6_SAW = 26 + ES5506 = 27 + MULTIPCM = 28 + SNES = 29 + TSU = 30 + NAMCO_WSG = 31 + OPL_DRUMS = 32 + FM_OPM = 33 + NES = 34 + MSM6258 = 35 + MSM6295 = 36 + ADPCM_A = 37 + ADPCM_B = 38 + SEGAPCM = 39 + QSOUND = 40 + YMZ280B = 41 + RF5C68 = 42 + MSM5232 = 43 + T6W28 = 44 + K007232 = 45 + GA20 = 46 + POKEMON_MINI = 47 + SM8521 = 48 + PV1000 = 49 + + +class ChipType(EnumShowNameOnly): + """ + Furnace chip database, either planned or implemented. + Contains console name, chip ID and number of channels. + """ + _value_: int + channels: int + + YMU759 = (0x01, 17) + GENESIS = (0x02, 10) # YM2612 + SN76489 + SMS = (0x03, 4) # SN76489 + GB = (0x04, 4) # LR53902 + PCE = (0x05, 6) # HuC6280 + NES = (0x06, 5) # RP2A03 + C64_8580 = (0x07, 3) # SID r8580 + SEGA_ARCADE = (0x08, 13) # YM2151 + SegaPCM + NEO_GEO_CD = (0x09, 13) + + GENESIS_EX = (0x42, 13) # YM2612 + SN76489 + SMS_JP = (0x43, 13) # SN76489 + YM2413 + NES_VRC7 = (0x46, 11) # RP2A03 + YM2413 + C64_6581 = (0x47, 3) # SID r6581 + NEO_GEO_CD_EX = (0x49, 16) + + AY38910 = (0x80, 3) + AMIGA = (0x81, 4) # Paula + YM2151 = (0x82, 8) # YM2151 + YM2612 = (0x83, 6) # YM2612 + TIA = (0x84, 2) + VIC20 = (0x85, 4) + PET = (0x86, 1) + SNES = (0x87, 8) # SPC700 + VRC6 = (0x88, 3) + OPLL = (0x89, 9) # YM2413 + FDS = (0x8a, 1) + MMC5 = (0x8b, 3) + N163 = (0x8c, 8) + OPN = (0x8d, 6) # YM2203 + PC98 = (0x8e, 16) # YM2608 + OPL = (0x8f, 9) # YM3526 + + OPL2 = (0x90, 9) # YM3812 + OPL3 = (0x91, 18) # YMF262 + MULTIPCM = (0x92, 24) + PC_SPEAKER = (0x93, 1) # Intel 8253 + POKEY = (0x94, 4) + RF5C68 = (0x95, 8) + WONDERSWAN = (0x96, 4) + SAA1099 = (0x97, 6) + OPZ = (0x98, 8) + POKEMON_MINI = (0x99, 1) + AY8930 = (0x9a, 3) + SEGAPCM = (0x9b, 16) + VIRTUAL_BOY = (0x9c, 6) + VRC7 = (0x9d, 6) + YM2610B = (0x9e, 16) + ZX_BEEPER = (0x9f, 6) # tildearrow's engine + + YM2612_EX = (0xa0, 9) + SCC = (0xa1, 5) + OPL_DRUMS = (0xa2, 11) + OPL2_DRUMS = (0xa3, 11) + OPL3_DRUMS = (0xa4, 20) + NEO_GEO = (0xa5, 14) + NEO_GEO_EX = (0xa6, 17) + OPLL_DRUMS = (0xa7, 11) + LYNX = (0xa8, 4) + SEGAPCM_DMF = (0xa9, 5) + MSM6295 = (0xaa, 4) + MSM6258 = (0xab, 1) + COMMANDER_X16 = (0xac, 17) # VERA + BUBBLE_SYSTEM_WSG = (0xad, 2) + OPL4 = (0xae, 42) + OPL4_DRUMS = (0xaf, 44) + + SETA = (0xb0, 16) # Allumer X1-010 + ES5506 = (0xb1, 32) + Y8950 = (0xb2, 10) + Y8950_DRUMS = (0xb3, 12) + SCC_PLUS = (0xb4, 5) + TSU = (0xb5, 8) + YM2203_EX = (0xb6, 9) + YM2608_EX = (0xb7, 19) + YMZ280B = (0xb8, 8) + NAMCO = (0xb9, 3) # Namco WSG + N15XX = (0xba, 8) # Namco 15xx + CUS30 = (0xbb, 8) # Namco CUS30 + MSM5232 = (0xbc, 8) + YM2612_PLUS_EX = (0xbd, 11) + YM2612_PLUS = (0xbe, 7) + T6W28 = (0xbf, 4) + + PCM_DAC = (0xc0, 1) + YM2612_CSM = (0xc1, 10) + NEO_GEO_CSM = (0xc2, 18) # YM2610 CSM + YM2203_CSM = (0xc3, 10) + YM2608_CSM = (0xc4, 20) + YM2610B_CSM = (0xc5, 20) + K007232 = (0xc6, 2) + GA20 = (0xc7, 4) + SM8521 = (0xc8, 3) + M114S = (0xc9, 16) + ZX_BEEPER_QUADTONE: Tuple[int, int] = (0xca, 5) # Natt Akuma's engine + PV_1000: Tuple[int, int] = (0xcb, 3) # NEC D65010G031 + K053260 = (0xcc, 4) + TED = (0xcd, 2) + NAMCO_C140 = (0xce, 24) + NAMCO_C219 = (0xcf, 16) + + NAMCO_C352 = (0xd0, 32) + ESFM = (0xd1, 18) + ES5503 = (0xd2, 32) + POWERNOISE = (0xd4, 4) + DAVE = (0xd5, 6) + NDS = (0xd6, 16) + GBA = (0xd7, 2) + GBA_MINMOD = (0xd8, 16) + BIFURCATOR = (0xd9, 4) + YM2610B_EX = (0xde, 19) + + QSOUND = (0xe0, 19) + + SID2 = (0xf0, 3) # SID2 + FIVEE01 = (0xf1, 5) # 5E01 + PONG = (0xfc, 1) + DUMMY = (0xfd, 1) + + RESERVED_1 = (0xfe, 1) + RESERVED_2 = (0xff, 1) + + def __new__(cls, id: int, channels: int): # type: ignore[no-untyped-def] + member = object.__new__(cls) + member._value_ = id + setattr(member, 'channels', channels) + return member + + def __repr__(self) -> str: + # repr abuse + # about as stupid as "mapping for the renderer"... + return "%s (0x%02x), %d channel%s" % ( + self.name, self._value_, self.channels, + "s" if self.channels != 1 else "" + ) + + +class InputPortSet(EnumShowNameOnly): + """ + Devices which contain an "input" port. + """ + SYSTEM = 0 + NULL = 0xFFF + + +class OutputPortSet(EnumShowNameOnly): + """ + Devices which contain an "output" port. + """ + CHIP_1 = 0 + CHIP_2 = 1 + CHIP_3 = 2 + CHIP_4 = 3 + CHIP_5 = 4 + CHIP_6 = 5 + CHIP_7 = 6 + CHIP_8 = 7 + CHIP_9 = 8 + CHIP_10 = 9 + CHIP_11 = 10 + CHIP_12 = 11 + CHIP_13 = 12 + CHIP_14 = 13 + CHIP_15 = 14 + CHIP_16 = 15 + CHIP_17 = 16 + CHIP_18 = 17 + CHIP_19 = 18 + CHIP_20 = 19 + CHIP_21 = 20 + CHIP_22 = 21 + CHIP_23 = 22 + CHIP_24 = 23 + CHIP_25 = 24 + CHIP_26 = 25 + CHIP_27 = 26 + CHIP_28 = 27 + CHIP_29 = 28 + CHIP_30 = 29 + CHIP_31 = 30 + CHIP_32 = 31 + PREVIEW = 0xFFD + METRONOME = 0xFFE + NULL = 0xFFF + + +class WaveFX(EnumShowNameOnly): + """ + Used in :attr:`chipchune.furnace.data_types.InsFeatureWaveSynth.effect`. + """ + NONE = 0 + + # single waveform + INVERT = 1 + ADD = 2 + SUBTRACT = 3 + AVERAGE = 4 + PHASE = 5 + CHORUS = 6 + + # double waveform + NONE_DUAL = 128 + WIPE = 129 + FADE = 130 + PING_PONG = 131 + OVERLAY = 132 + NEGATIVE_OVERLAY = 133 + SLIDE = 134 + MIX = 135 + PHASE_MOD = 136 + + +class ESFilterMode(EnumShowNameOnly): + """ + Used in :attr:`chipchune.furnace.data_types.InsFeatureES5506.filter_mode`. + """ + HPK2_HPK2 = 0 + HPK2_LPK1 = 1 + LPK2_LPK2 = 2 + LPK2_LPK1 = 3 + + +class GainMode(EnumShowNameOnly): + """ + Used in :attr:`chipchune.furnace.data_types.InsFeatureSNES.gain_mode`. + """ + DIRECT = 0 + DEC_LINEAR = 4 + DEC_LOG = 5 + INC_LINEAR = 6 + INC_INVLOG = 7 + + +class SNESSusMode(EnumShowNameOnly): + """ + Used in :attr:`chipchune.furnace.data_types.InsFeatureSNES.sus`. + """ + DIRECT = 0 + SUS_WITH_DEC = 1 + SUS_WITH_EXP = 2 + SUS_WITH_REL = 3 + + +class _FurInsImportType(EnumShowNameOnly, EnumValueEquals): + """ + Also only used in this parser to differentiate between different types of instrument formats. + """ + # Old format + FORMAT_0_FILE = 0 + FORMAT_0_EMBED = 1 + + # Dev127 format + FORMAT_1_FILE = 2 + FORMAT_1_EMBED = 3 + +class _FurWavetableImportType(EnumShowNameOnly, EnumValueEquals): + """ + Also only used in this parser to differentiate between different types of wavetable formats. + """ + FILE = 0 + EMBED = 1 + +class _FurSampleType(EnumShowNameOnly, EnumValueEquals): + """ + Also only used in this parser to differentiate between different types of sample formats. + """ + PCM_1_BIT = 0 + DPCM = 1 + YMZ = 3 + QSOUND = 4 + ADPCM_A = 5 + ADPCM_B = 6 + K05_ADPCM = 7 + PCM_8_BIT = 8 + BRR = 9 + VOX = 10 + ULAW = 11 + C219 = 12 + IMA = 13 + PCM_16_BIT = 16 diff --git a/loader/samples/minexample/furC64/chipchune/furnace/instrument.py b/loader/samples/minexample/furC64/chipchune/furnace/instrument.py new file mode 100644 index 0000000..0eaf3b0 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/furnace/instrument.py @@ -0,0 +1,1572 @@ +from io import BytesIO +from typing import Optional, Union, BinaryIO, TypeVar, Type, List, Dict + +from chipchune._util import read_byte, read_short, read_int, read_str +from .data_types import ( + InsFeatureAbstract, InsFeatureMacro, InsMeta, InstrumentType, InsFeatureName, + InsFeatureFM, InsFeatureOpr1Macro, InsFeatureOpr2Macro, InsFeatureOpr3Macro, InsFeatureOpr4Macro, + InsFeatureC64, InsFeatureGB, GBHwSeq, SingleMacro, InsFeatureAmiga, InsFeatureOPLDrums, InsFeatureSNES, + GainMode, InsFeatureN163, InsFeatureFDS, InsFeatureWaveSynth, _InsFeaturePointerAbstract, InsFeatureSampleList, + InsFeatureWaveList, InsFeatureMultiPCM, InsFeatureSoundUnit, InsFeatureES5506, InsFeatureX1010, GenericADSR, + InsFeatureDPCMMap, InsFeaturePowerNoise, InsFeatureSID2 +) +from .enums import ( + _FurInsImportType, MacroCode, OpMacroCode, MacroItem, MacroType, GBHwCommand, + SNESSusMode, WaveFX, ESFilterMode, MacroSize +) + +FILE_MAGIC_STR = b'-Furnace instr.-' +DEV127_FILE_MAGIC_STR = b'FINS' + +EMBED_MAGIC_STR = b'INST' +DEV127_EMBED_MAGIC_STR = b'INS2' + +T_MACRO = TypeVar('T_MACRO', bound=InsFeatureMacro) # T_MACRO must be subclass of InsFeatureMacro +T_POINTERS = TypeVar('T_POINTERS', bound=_InsFeaturePointerAbstract) + + +class FurnaceInstrument: + def __init__(self, file_name: Optional[str] = None, protocol_version: Optional[int] = 1) -> None: + """ + Creates or opens a new Furnace instrument as a Python object. + + :param file_name: (Optional) + If specified, then it will parse a file as a FurnaceInstrument. If file name (str) is + given, it will load that file. + + Defaults to None. + + :param protocol_version: (Optional) + If specified, it will determine which format the instrument is to be serialized (exported) + to. It is ignored if loading up a file. + + Defaults to 2 (dev127+ ins. format) + """ + self.file_name: Optional[str] = None + """ + Original file name, if the object was initialized with one. + """ + self.protocol_version: Optional[int] = protocol_version + """ + Instrument file "protocol" version. Currently: + - 0: The "unified" instrument format up to Furnace version 126. + - 1: The new "featural" instrument format introduced in version 127. + """ + self.features: List[InsFeatureAbstract] = [] + """ + List of features, regardless of protocol version. + """ + self.meta: InsMeta = InsMeta() + """ + Instrument metadata. + """ + + # self.wavetables: list[] = [] + # self.samples: list[] = [] + + self.__map_to_fn = { + b'NA': self.__load_na_block, + b'FM': self.__load_fm_block, + b'MA': self.__load_ma_block, + b'64': self.__load_c64_block, + b'GB': self.__load_gb_block, + b'SM': self.__load_sm_block, + b'O1': self.__load_o1_block, + b'O2': self.__load_o2_block, + b'O3': self.__load_o3_block, + b'O4': self.__load_o4_block, + b'LD': self.__load_ld_block, + b'SN': self.__load_sn_block, + b'N1': self.__load_n1_block, + b'FD': self.__load_fd_block, + b'WS': self.__load_ws_block, + b'SL': self.__load_sl_block, + b'WL': self.__load_wl_block, + b'MP': self.__load_mp_block, + b'SU': self.__load_su_block, + b'ES': self.__load_es_block, + b'X1': self.__load_x1_block, + b'NE': self.__load_ne_block, + # TODO: No documentation? + #b'EF': self.__load_ef_block, + b'PN': self.__load_pn_block, + b'S2': self.__load_s2_block, + } + + if isinstance(file_name, str): + self.load_from_file(file_name) + + def load_from_file(self, file_name: Optional[str] = None) -> None: + if isinstance(file_name, str): + self.file_name = file_name + if self.file_name is None: + raise RuntimeError('No file name set, either set self.file_name or pass file_name to the function') + + # since we're loading from an uncompressed file, we can just check the file magic number + with open(self.file_name, 'rb') as f: + detect_magic = f.peek(len(FILE_MAGIC_STR))[:len(FILE_MAGIC_STR)] + if detect_magic == FILE_MAGIC_STR: + return self.load_from_stream(f, _FurInsImportType.FORMAT_0_FILE) + elif detect_magic[:len(DEV127_FILE_MAGIC_STR)] == DEV127_FILE_MAGIC_STR: + return self.load_from_stream(f, _FurInsImportType.FORMAT_1_FILE) + else: # uncompressed for sure + raise ValueError('No recognized file type magic') + + def load_from_bytes(self, data: bytes, import_as: Union[int, _FurInsImportType]) -> None: + """ + Load an instrument from a series of bytes. + + :param data: Bytes + :param import_as: int + see :method:`FurnaceInstrument.load_from_stream` + + """ + return self.load_from_stream( + BytesIO(data), + import_as + ) + + def load_from_stream(self, stream: BinaryIO, import_as: Union[int, _FurInsImportType]) -> None: + """ + Load a module from an **uncompressed** stream. + + :param stream: File-like object containing the uncompressed module. + :param import_as: int + - 0 = old format instrument file + - 1 = old format, embedded in module + - 2 = new format instrument file + - 3 = new format, embedded in module + """ + if import_as == _FurInsImportType.FORMAT_0_FILE: + if stream.read(len(FILE_MAGIC_STR)) != FILE_MAGIC_STR: + raise ValueError('Bad magic value for a format 1 file') + self.protocol_version = 0 + self.meta.version = read_short(stream) + read_short(stream) # reserved + ins_data_ptr = read_int(stream) + num_waves = read_short(stream) + num_samples = read_short(stream) + read_int(stream) # reserved + + # these don't exist for format 1 instrs. + self.__wavetable_ptr = [ + read_int(stream) for _ in range(num_waves) + ] + self.__sample_ptr = [ + read_int(stream) for _ in range(num_samples) + ] + + stream.seek(ins_data_ptr) + self.__load_format_0_embed(stream) + # TODO: load wavetables and samples + + elif import_as == _FurInsImportType.FORMAT_0_EMBED: + self.protocol_version = 0 + return self.__load_format_0_embed(stream) + + elif import_as == _FurInsImportType.FORMAT_1_FILE: + if stream.read(len(DEV127_FILE_MAGIC_STR)) != DEV127_FILE_MAGIC_STR: + raise ValueError('Bad magic value for a format 1 file') + self.protocol_version = 1 + self.__load_format_1(stream) + # TODO: load wavetables and samples + + elif import_as == _FurInsImportType.FORMAT_1_EMBED: + if stream.read(len(DEV127_EMBED_MAGIC_STR)) != DEV127_EMBED_MAGIC_STR: + raise ValueError('Bad magic value for a format 1 embed') + self.protocol_version = 1 + ins_data = BytesIO(stream.read(read_int(stream))) + return self.__load_format_1(ins_data) + + else: + raise ValueError('Invalid import type') + + def __str__(self) -> str: + return '' % ( + self.get_name(), self.meta.type + ) + + def __load_format_1(self, stream: BinaryIO) -> None: + # skip headers and magic + self.meta.version = read_short(stream) + self.meta.type = InstrumentType(read_short(stream)) + self.features.clear() + + # add all the features + feat = self.__read_format_1_feature(stream) + while isinstance(feat, InsFeatureAbstract): + self.features.append(feat) + feat = self.__read_format_1_feature(stream) + + def __read_format_1_feature(self, stream: BinaryIO) -> Optional[object]: # subclass InsFeatureAbstract + code = stream.read(2) + if code == b'EN' or code == b'': # eof + return None + + len_block = read_short(stream) + feature_block = BytesIO(stream.read(len_block)) + + # if this fails it might be a malformed file + return self.__map_to_fn[code](feature_block) + + def get_name(self) -> str: + """ + Shortcut to fetch the instrument name. + + :return: Instrument name + """ + name = '' + for i in self.features: + if isinstance(i, InsFeatureName): + name = i # InsFeatureName also subclasses 'str' so it's fine + return name + + # format 1 features + + def __load_na_block(self, stream: BytesIO) -> InsFeatureName: + return InsFeatureName( + read_str(stream) + ) + + def __load_fm_block(self, stream: BytesIO) -> InsFeatureFM: + fm = InsFeatureFM() + + # read base data + data = [read_byte(stream) for _ in range(4)] + + current = data.pop(0) + ops = current & 0b1111 + fm.op_list[0].enable = bool(current & 16) + fm.op_list[1].enable = bool(current & 32) + fm.op_list[2].enable = bool(current & 64) + fm.op_list[3].enable = bool(current & 128) + + current = data.pop(0) + fm.alg = (current >> 4) & 0b111 + fm.fb = current & 0b111 + + current = data.pop(0) + fm.fms2 = (current >> 5) & 0b111 + fm.ams = (current >> 3) & 0b11 + fm.fms = current & 0b111 + + current = data.pop(0) + fm.ams2 = (current >> 6) & 0b11 + if current & 32: + fm.ops = 4 + else: + fm.ops = 2 + fm.opll_preset = current & 31 + + # read operators + for op in range(ops): + data = [read_byte(stream) for _ in range(8)] + + current = data.pop(0) + fm.op_list[op].ksr = bool(current & 128) + fm.op_list[op].dt = (current >> 4) & 7 + fm.op_list[op].mult = current & 15 + + current = data.pop(0) + fm.op_list[op].sus = bool(current & 128) + fm.op_list[op].tl = current & 127 + + current = data.pop(0) + fm.op_list[op].rs = (current >> 6) & 3 + fm.op_list[op].vib = bool(current & 32) + fm.op_list[op].ar = current & 31 + + current = data.pop(0) + fm.op_list[op].am = bool(current & 128) + fm.op_list[op].ksl = (current >> 5) & 3 + fm.op_list[op].dr = current & 31 + + current = data.pop(0) + fm.op_list[op].egt = bool(current & 128) + fm.op_list[op].kvs = (current >> 5) & 3 + fm.op_list[op].d2r = current & 31 + + current = data.pop(0) + fm.op_list[op].sl = (current >> 4) & 15 + fm.op_list[op].rr = current & 15 + + current = data.pop(0) + fm.op_list[op].dvb = (current >> 4) & 15 + fm.op_list[op].ssg_env = current & 15 + + current = data.pop(0) + fm.op_list[op].dam = (current >> 5) & 7 + fm.op_list[op].dt2 = (current >> 3) & 3 + fm.op_list[op].ws = current & 7 + + return fm + + def __common_ma_block(self, stream: BytesIO, macro_class: Type[T_MACRO]) -> T_MACRO: + ma = macro_class() + ma.macros.clear() + read_short(stream) # header size + + target_code: Union[MacroCode, OpMacroCode] + + if macro_class in [InsFeatureOpr1Macro, + InsFeatureOpr2Macro, + InsFeatureOpr3Macro, + InsFeatureOpr4Macro]: + target_code = OpMacroCode(read_byte(stream)) + else: + target_code = MacroCode(read_byte(stream)) + + while target_code != MacroCode.STOP: + new_macro = SingleMacro(kind=target_code) + + length = read_byte(stream) + loop = read_byte(stream) + release = read_byte(stream) + + new_macro.mode = read_byte(stream) + flags = read_byte(stream) + + word_size = MacroSize(flags >> 6 & 0b11) # type: ignore + new_macro.type = MacroType(flags >> 1 & 0b11) + new_macro.open = bool(flags & 1) + new_macro.delay = read_byte(stream) + new_macro.speed = read_byte(stream) + + # adsr and lfo will simply be kept as a list + macro_content: List[Union[int, MacroItem]] = [ + int.from_bytes( + stream.read(word_size.num_bytes), + byteorder='little', + signed=word_size.signed + ) + for _ in range(length) + ] + + if loop != 0xff: # hard limit in new macro + macro_content.insert(loop, MacroItem.LOOP) + + if release != 0xff: # ^ + macro_content.insert(release, MacroItem.RELEASE) + + new_macro.data = macro_content + + ma.macros.append(new_macro) + + if macro_class in [InsFeatureOpr1Macro, + InsFeatureOpr2Macro, + InsFeatureOpr3Macro, + InsFeatureOpr4Macro]: + target_code = OpMacroCode(read_byte(stream)) + else: + target_code = MacroCode(read_byte(stream)) + + return ma + + def __load_ma_block(self, stream: BytesIO) -> InsFeatureMacro: + return self.__common_ma_block(stream, InsFeatureMacro) + + def __load_o1_block(self, stream: BytesIO) -> InsFeatureOpr1Macro: + return self.__common_ma_block(stream, InsFeatureOpr1Macro) + + def __load_o2_block(self, stream: BytesIO) -> InsFeatureOpr2Macro: + return self.__common_ma_block(stream, InsFeatureOpr2Macro) + + def __load_o3_block(self, stream: BytesIO) -> InsFeatureOpr3Macro: + return self.__common_ma_block(stream, InsFeatureOpr3Macro) + + def __load_o4_block(self, stream: BytesIO) -> InsFeatureOpr4Macro: + return self.__common_ma_block(stream, InsFeatureOpr4Macro) + + def __load_c64_block(self, stream: BytesIO) -> InsFeatureC64: + c64 = InsFeatureC64() + + data = [read_byte(stream) for _ in range(4)] + + current = data.pop(0) + c64.duty_is_abs = bool((current >> 7) & 1) + c64.init_filter = bool((current >> 6) & 1) + c64.vol_is_cutoff = bool((current >> 5) & 1) + c64.to_filter = bool((current >> 4) & 1) + c64.noise_on = bool((current >> 3) & 1) + c64.pulse_on = bool((current >> 2) & 1) + c64.saw_on = bool((current >> 1) & 1) + c64.tri_on = bool(current & 1) + + current = data.pop(0) + c64.osc_sync = bool((current >> 7) & 1) + c64.ring_mod = bool((current >> 6) & 1) + c64.no_test = bool((current >> 5) & 1) + c64.filter_is_abs = bool((current >> 4) & 1) + c64.ch3_off = bool((current >> 3) & 1) + c64.bp = bool((current >> 2) & 1) + c64.hp = bool((current >> 1) & 1) + c64.lp = bool(current & 1) + + current = data.pop(0) + c64.envelope.a = (current >> 4) & 0b1111 + c64.envelope.d = current & 0b1111 + + current = data.pop(0) + c64.envelope.s = (current >> 4) & 0b1111 + c64.envelope.r = current & 0b1111 + + c64.duty = read_short(stream) + + c_r = read_short(stream) + c64.cut = c_r & 0b11111111111 + c64.res = (c_r >> 12) & 0b1111 + + return c64 + + def __load_gb_block(self, stream: BytesIO) -> InsFeatureGB: + gb = InsFeatureGB() + + data = [read_byte(stream) for _ in range(4)] + + current = data.pop(0) + gb.env_vol = current & 0b1111 + gb.env_dir = (current >> 4) & 1 + gb.env_len = (current >> 5) & 0b111 + + gb.sound_len = data.pop(0) + + current = data.pop(0) + gb.soft_env = bool(current & 1) + gb.always_init = bool((current >> 1) & 1) + + hw_seq_len = data.pop(0) + for i in range(hw_seq_len): + seq_entry = GBHwSeq( + GBHwCommand(read_byte(stream)) + ) + seq_entry.data = [ + read_byte(stream), + read_byte(stream) + ] + gb.hw_seq.append(seq_entry) + + return gb + + def __load_sm_block(self, stream: BytesIO) -> InsFeatureAmiga: + sm = InsFeatureAmiga() + + sm.init_sample = read_short(stream) + + current = read_byte(stream) + sm.use_wave = bool((current >> 2) & 1) + sm.use_sample = bool((current >> 1) & 1) + sm.use_note_map = bool(current & 1) + + sm.wave_len = read_byte(stream) + + if sm.use_note_map: + for i in range(len(sm.sample_map)): + sm.sample_map[i].freq = read_short(stream) + sm.sample_map[i].sample_index = read_short(stream) + + return sm + + def __load_ld_block(self, stream: BytesIO) -> InsFeatureOPLDrums: + return InsFeatureOPLDrums( + fixed_drums=bool(read_byte(stream) & 1), + kick_freq=read_short(stream), + snare_hat_freq=read_short(stream), + tom_top_freq=read_short(stream) + ) + + def __load_sn_block(self, stream: BytesIO) -> InsFeatureSNES: + sn = InsFeatureSNES() + + data = [read_byte(stream) for _ in range(4)] + + current = data.pop(0) + sn.envelope.d = (current >> 4) & 0b1111 + sn.envelope.a = current & 0b1111 + + current = data.pop(0) + sn.envelope.s = (current >> 4) & 0b1111 + sn.envelope.r = current & 0b1111 + + current = data.pop(0) + sn.use_env = bool((current >> 4) & 1) + sn.sus = SNESSusMode((current >> 3) & 1) + + gain_mode = current & 0b111 + if current < 4: + gain_mode = 0 + sn.gain_mode = GainMode(gain_mode) + + sn.gain = data.pop(0) + + if self.meta.version >= 131: + d2s = read_byte(stream) + sn.sus = SNESSusMode((d2s >> 5 & 0b11)) + sn.d2 = d2s & 31 + + return sn + + def __load_n1_block(self, stream: BytesIO) -> InsFeatureN163: + return InsFeatureN163( + wave=read_int(stream), + wave_pos=read_byte(stream), + wave_len=read_byte(stream), + wave_mode=read_byte(stream) + ) + + def __load_fd_block(self, stream: BytesIO) -> InsFeatureFDS: + fd = InsFeatureFDS( + mod_speed=read_int(stream), + mod_depth=read_int(stream), + init_table_with_first_wave=bool(read_byte(stream)) + ) + for i in range(32): + fd.mod_table[i] = read_byte(stream) + return fd + + def __load_ws_block(self, stream: BytesIO) -> InsFeatureWaveSynth: + return InsFeatureWaveSynth( + wave_indices=[ + read_int(stream), read_int(stream) + ], + rate_divider=read_byte(stream), + effect=WaveFX(read_byte(stream)), + enabled=bool(read_byte(stream) & 1), + global_effect=bool(read_byte(stream) & 1), + speed=read_byte(stream), + params=[ + read_byte(stream), read_byte(stream), + read_byte(stream), read_byte(stream) + ] + ) + + def __common_pointers_block(self, stream: BytesIO, ptr_class: Type[T_POINTERS]) -> T_POINTERS: + pt = ptr_class() + num_entries = read_byte(stream) + + for _ in range(num_entries): + pt.pointers[read_byte(stream)] = -1 + + for i in pt.pointers: + pt.pointers[i] = read_int(stream) + + return pt + + def __load_sl_block(self, stream: BytesIO) -> InsFeatureSampleList: + return self.__common_pointers_block(stream, InsFeatureSampleList) + + def __load_wl_block(self, stream: BytesIO) -> InsFeatureWaveList: + return self.__common_pointers_block(stream, InsFeatureWaveList) + + def __load_mp_block(self, stream: BytesIO) -> InsFeatureMultiPCM: + return InsFeatureMultiPCM( + ar=read_byte(stream), + d1r=read_byte(stream), + dl=read_byte(stream), + d2r=read_byte(stream), + rr=read_byte(stream), + rc=read_byte(stream), + lfo=read_byte(stream), + vib=read_byte(stream), + am=read_byte(stream), + ) + + def __load_su_block(self, stream: BytesIO) -> InsFeatureSoundUnit: + return InsFeatureSoundUnit( + switch_roles=bool(read_byte(stream)) + ) + + def __load_es_block(self, stream: BytesIO) -> InsFeatureES5506: + return InsFeatureES5506( + filter_mode=ESFilterMode(read_byte(stream)), + k1=read_short(stream), + k2=read_short(stream), + env_count=read_short(stream), + left_volume_ramp=read_byte(stream), + right_volume_ramp=read_byte(stream), + k1_ramp=read_byte(stream), + k2_ramp=read_byte(stream), + k1_slow=read_byte(stream), + k2_slow=read_byte(stream) + ) + + def __load_x1_block(self, stream: BytesIO) -> InsFeatureX1010: + return InsFeatureX1010( + bank_slot=read_int(stream) + ) + + def __load_ne_block(self, stream: BytesIO) -> InsFeatureDPCMMap: + sm = InsFeatureDPCMMap() + + sm.use_map = bool(read_byte(stream) & 1) + + if sm.use_map: + for i in range(len(sm.sample_map)): + sm.sample_map[i].pitch = read_byte(stream) + sm.sample_map[i].delta = read_byte(stream) + + return sm + + # TODO: No documentation? + #def __load_ef_block(self, stream: BytesIO) -> InsFeatureESFM: + # pass + + def __load_pn_block(self, stream: BytesIO) -> InsFeaturePowerNoise: + return InsFeaturePowerNoise( + octave=read_byte(stream) + ) + + def __load_s2_block(self, stream: BytesIO) -> InsFeatureSID2: + current_byte = read_byte(stream) + return InsFeatureSID2( + volume=current_byte & 0b1111, + wave_mix=(current_byte >> 4) & 0b11, + noise_mode=(current_byte >> 6) & 0b11 + ) + + # format 0; also used for file because it includes the "INST" header too + + def __load_format_0_embed(self, stream: BinaryIO) -> None: + # load format 0 as a series of format 1 feature blocks + + # aux function... + def add_to_macro_data(macro: List[Union[int, MacroItem]], + loop: Optional[int] = 0xffffffff, + release: Optional[int] = 0xffffffff, + data: Optional[List[int]] = None) -> None: + if data is not None: + macro.extend(data) + if loop is not None and loop != 0xffffffff: # old macros have a 4-byte length + macro.insert(loop, MacroItem.LOOP) + if release is not None and release != 0xffffffff: + macro.insert(release, MacroItem.RELEASE) + + # we check the header here + if stream.read(len(EMBED_MAGIC_STR)) != EMBED_MAGIC_STR: + raise RuntimeError('Bad magic value for a format 0 embed') + + blk_size = read_int(stream) + if blk_size > 0: + ins_data = BytesIO(stream.read(blk_size)) + else: + ins_data = stream + + self.meta.version = read_short(ins_data) # overwrites the file header version + self.meta.type = InstrumentType(read_byte(ins_data)) + + read_byte(ins_data) + + # read all features in one go! + self.features.clear() + + # name, insert immediately + self.features.append( + InsFeatureName(read_str(ins_data)) + ) + + # fm + if True: + fm = InsFeatureFM( + alg=read_byte(ins_data), + fb=read_byte(ins_data), + fms=read_byte(ins_data), + ams=read_byte(ins_data), + ops=read_byte(ins_data), + opll_preset=read_byte(ins_data) + ) + read_short(ins_data) + for i in range(4): + fm.op_list[i].am = bool(read_byte(ins_data)) + fm.op_list[i].ar = read_byte(ins_data) + fm.op_list[i].dr = read_byte(ins_data) + fm.op_list[i].mult = read_byte(ins_data) + fm.op_list[i].rr = read_byte(ins_data) + fm.op_list[i].sl = read_byte(ins_data) + fm.op_list[i].tl = read_byte(ins_data) + fm.op_list[i].dt2 = read_byte(ins_data) + fm.op_list[i].rs = read_byte(ins_data) + fm.op_list[i].dt = read_byte(ins_data) + fm.op_list[i].d2r = read_byte(ins_data) + fm.op_list[i].ssg_env = read_byte(ins_data) + fm.op_list[i].dam = read_byte(ins_data) + fm.op_list[i].dvb = read_byte(ins_data) + fm.op_list[i].egt = bool(read_byte(ins_data)) + fm.op_list[i].ksl = read_byte(ins_data) + fm.op_list[i].sus = bool(read_byte(ins_data)) + fm.op_list[i].vib = bool(read_byte(ins_data)) + fm.op_list[i].ws = read_byte(ins_data) + fm.op_list[i].ksr = bool(read_byte(ins_data)) + en = read_byte(ins_data) + if self.meta.version >= 114: + fm.op_list[i].enable = bool(en) + kvs = read_byte(ins_data) + if self.meta.version >= 115: + fm.op_list[i].kvs = kvs + ins_data.read(10) + self.features.append(fm) + + # gameboy + if True: + gb = InsFeatureGB( + env_vol=read_byte(ins_data), + env_dir=read_byte(ins_data), + env_len=read_byte(ins_data), + sound_len=read_byte(ins_data) + ) + self.features.append(gb) + + # c64 + if True: + c64 = InsFeatureC64( + tri_on=bool(read_byte(ins_data)), + saw_on=bool(read_byte(ins_data)), + pulse_on=bool(read_byte(ins_data)), + noise_on=bool(read_byte(ins_data)), + duty=read_short(ins_data), + ring_mod=read_byte(ins_data), + osc_sync=read_byte(ins_data), + to_filter=bool(read_byte(ins_data)), + init_filter=bool(read_byte(ins_data)), + vol_is_cutoff=bool(read_byte(ins_data)), + res=read_byte(ins_data), + lp=bool(read_byte(ins_data)), + bp=bool(read_byte(ins_data)), + hp=bool(read_byte(ins_data)), + ch3_off=bool(read_byte(ins_data)), + cut=read_short(ins_data), + duty_is_abs=bool(read_byte(ins_data)), + filter_is_abs=bool(read_byte(ins_data)) + ) + c64.envelope = GenericADSR( + a=read_byte(ins_data), + d=read_byte(ins_data), + s=read_byte(ins_data), + r=read_byte(ins_data), + ) + self.features.append(c64) + + # amiga + if True: + amiga = InsFeatureAmiga( + init_sample=read_short(ins_data) + ) + + wave = read_byte(ins_data) + wavelen = read_byte(ins_data) + if self.meta.version >= 82: + amiga.use_wave = bool(wave) + amiga.wave_len = wavelen + + for _ in range(12): + read_byte(ins_data) # reserved + + self.features.append(amiga) + + # standard + if True: + mac = InsFeatureMacro() + + vol_mac = SingleMacro(kind=MacroCode.VOL) + arp_mac = SingleMacro(kind=MacroCode.ARP) + duty_mac = SingleMacro(kind=MacroCode.DUTY) + wave_mac = SingleMacro(kind=MacroCode.WAVE) + + vol_mac.data.clear() + arp_mac.data.clear() + duty_mac.data.clear() + wave_mac.data.clear() + + mac_list: List[SingleMacro] = [vol_mac, arp_mac, duty_mac, wave_mac] + mac.macros = mac_list + + vol_mac_len = read_int(ins_data) + arp_mac_len = read_int(ins_data) + duty_mac_len = read_int(ins_data) + wave_mac_len = read_int(ins_data) + + if self.meta.version >= 17: + pitch_mac = SingleMacro(kind=MacroCode.PITCH) + x1_mac = SingleMacro(kind=MacroCode.EX1) + x2_mac = SingleMacro(kind=MacroCode.EX2) + x3_mac = SingleMacro(kind=MacroCode.EX3) + + pitch_mac.data.clear() + x1_mac.data.clear() + x2_mac.data.clear() + x3_mac.data.clear() + + mac_list.extend([pitch_mac, x1_mac, x2_mac, x3_mac]) + + pitch_mac_len = read_int(ins_data) + x1_mac_len = read_int(ins_data) + x2_mac_len = read_int(ins_data) + x3_mac_len = read_int(ins_data) + + vol_mac_loop = read_int(ins_data) + arp_mac_loop = read_int(ins_data) + duty_mac_loop = read_int(ins_data) + wave_mac_loop = read_int(ins_data) + + if self.meta.version >= 17: + pitch_mac_loop = read_int(ins_data) + x1_mac_loop = read_int(ins_data) + x2_mac_loop = read_int(ins_data) + x3_mac_loop = read_int(ins_data) + + arp_mac_mode = read_byte(ins_data) + old_vol_height = read_byte(ins_data) + old_duty_height = read_byte(ins_data) + + read_byte(ins_data) + + add_to_macro_data(vol_mac.data, + loop=vol_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(vol_mac_len)]) + + add_to_macro_data(arp_mac.data, + loop=arp_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(arp_mac_len)]) + + add_to_macro_data(duty_mac.data, + loop=duty_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(duty_mac_len)]) + + add_to_macro_data(wave_mac.data, + loop=wave_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(wave_mac_len)]) + + # adjust values + if self.meta.version < 31: + if arp_mac_mode == 0: + for j in range(len(arp_mac.data)): + if isinstance(arp_mac.data[j], int): + arp_mac.data[j] -= 12 + if self.meta.version < 87: + if c64.vol_is_cutoff and not c64.filter_is_abs: + for j in range(len(vol_mac.data)): + if isinstance(vol_mac.data[j], int): + vol_mac.data[j] -= 18 + if c64.duty_is_abs: # TODO + for j in range(len(duty_mac.data)): + if isinstance(duty_mac.data[j], int): + duty_mac.data[j] -= 12 + if self.meta.version < 112: + if arp_mac_mode == 1: # fixed arp! + for i in range(len(arp_mac.data)): + if isinstance(arp_mac.data[i], int): + arp_mac.data[i] |= (1 << 30) + if len(arp_mac.data) > 0: + if arp_mac_loop != 0xffffffff: + if arp_mac_loop == arp_mac_len+1: + arp_mac.data[-1] = 0 + arp_mac.data.append(MacroItem.LOOP) + elif arp_mac_loop == arp_mac_len: + arp_mac.data.append(0) + else: + arp_mac.data.append(0) + + # read more macros + if self.meta.version >= 17: + add_to_macro_data(pitch_mac.data, + loop=pitch_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(pitch_mac_len)]) + + add_to_macro_data(x1_mac.data, + loop=x1_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(x1_mac_len)]) + + add_to_macro_data(x2_mac.data, + loop=x2_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(x2_mac_len)]) + + add_to_macro_data(x3_mac.data, + loop=x3_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(x3_mac_len)]) + else: + if self.meta.type == InstrumentType.STANDARD: + if old_vol_height == 31: + self.meta.type = InstrumentType.PCE + elif old_duty_height == 31: + self.meta.type = InstrumentType.SSG + + self.features.append(mac) + + # fm macros + if True: + if self.meta.version >= 29: + alg_mac = SingleMacro(kind=MacroCode.ALG) + fb_mac = SingleMacro(kind=MacroCode.FB) + fms_mac = SingleMacro(kind=MacroCode.FMS) + ams_mac = SingleMacro(kind=MacroCode.AMS) + mac_list.extend([alg_mac, fb_mac, fms_mac, ams_mac]) + + alg_mac.data.clear() + fb_mac.data.clear() + fms_mac.data.clear() + ams_mac.data.clear() + + alg_mac_len = read_int(ins_data) + fb_mac_len = read_int(ins_data) + fms_mac_len = read_int(ins_data) + ams_mac_len = read_int(ins_data) + + alg_mac_loop = read_int(ins_data) + fb_mac_loop = read_int(ins_data) + fms_mac_loop = read_int(ins_data) + ams_mac_loop = read_int(ins_data) + + vol_mac.open = bool(read_byte(ins_data)) + arp_mac.open = bool(read_byte(ins_data)) + duty_mac.open = bool(read_byte(ins_data)) + wave_mac.open = bool(read_byte(ins_data)) + pitch_mac.open = bool(read_byte(ins_data)) + x1_mac.open = bool(read_byte(ins_data)) + x2_mac.open = bool(read_byte(ins_data)) + x3_mac.open = bool(read_byte(ins_data)) + + alg_mac.open = bool(read_byte(ins_data)) + fb_mac.open = bool(read_byte(ins_data)) + fms_mac.open = bool(read_byte(ins_data)) + ams_mac.open = bool(read_byte(ins_data)) + + add_to_macro_data(alg_mac.data, + loop=alg_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(alg_mac_len)]) + + add_to_macro_data(fb_mac.data, + loop=fb_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(fb_mac_len)]) + + add_to_macro_data(fms_mac.data, + loop=fms_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(fms_mac_len)]) + + add_to_macro_data(ams_mac.data, + loop=ams_mac_loop, + release=None, + data=[read_int(ins_data) for _ in range(ams_mac_len)]) + + # fm op macros + if True: + if self.meta.version >= 29: + new_ops: Dict[int, InsFeatureMacro] = {} # actual ops + + ops_types: Dict[int, Type[InsFeatureMacro]] = { # classes + 0: InsFeatureOpr1Macro, + 1: InsFeatureOpr2Macro, + 2: InsFeatureOpr3Macro, + 3: InsFeatureOpr4Macro, + } + + ops: Dict[int, Dict[str, Union[int, bool]]] = { # params + 0: {}, + 1: {}, + 2: {}, + 3: {} + } + + for opi in ops: + ops[opi]["am_mac_len"] = read_int(ins_data) + ops[opi]["ar_mac_len"] = read_int(ins_data) + ops[opi]["dr_mac_len"] = read_int(ins_data) + ops[opi]["mult_mac_len"] = read_int(ins_data) + ops[opi]["rr_mac_len"] = read_int(ins_data) + ops[opi]["sl_mac_len"] = read_int(ins_data) + ops[opi]["tl_mac_len"] = read_int(ins_data) + ops[opi]["dt2_mac_len"] = read_int(ins_data) + ops[opi]["rs_mac_len"] = read_int(ins_data) + ops[opi]["dt_mac_len"] = read_int(ins_data) + ops[opi]["d2r_mac_len"] = read_int(ins_data) + ops[opi]["ssg_mac_len"] = read_int(ins_data) + + ops[opi]["am_mac_loop"] = read_int(ins_data) + ops[opi]["ar_mac_loop"] = read_int(ins_data) + ops[opi]["dr_mac_loop"] = read_int(ins_data) + ops[opi]["mult_mac_loop"] = read_int(ins_data) + ops[opi]["rr_mac_loop"] = read_int(ins_data) + ops[opi]["sl_mac_loop"] = read_int(ins_data) + ops[opi]["tl_mac_loop"] = read_int(ins_data) + ops[opi]["dt2_mac_loop"] = read_int(ins_data) + ops[opi]["rs_mac_loop"] = read_int(ins_data) + ops[opi]["dt_mac_loop"] = read_int(ins_data) + ops[opi]["d2r_mac_loop"] = read_int(ins_data) + ops[opi]["ssg_mac_loop"] = read_int(ins_data) + + ops[opi]["am_mac_open"] = read_byte(ins_data) + ops[opi]["ar_mac_open"] = read_byte(ins_data) + ops[opi]["dr_mac_open"] = read_byte(ins_data) + ops[opi]["mult_mac_open"] = read_byte(ins_data) + ops[opi]["rr_mac_open"] = read_byte(ins_data) + ops[opi]["sl_mac_open"] = read_byte(ins_data) + ops[opi]["tl_mac_open"] = read_byte(ins_data) + ops[opi]["dt2_mac_open"] = read_byte(ins_data) + ops[opi]["rs_mac_open"] = read_byte(ins_data) + ops[opi]["dt_mac_open"] = read_byte(ins_data) + ops[opi]["d2r_mac_open"] = read_byte(ins_data) + ops[opi]["ssg_mac_open"] = read_byte(ins_data) + + for opi in ops: + new_op = ops_types[opi]() + new_op.macros = [] + + am_mac = SingleMacro(kind=OpMacroCode.AM) + am_mac.open = bool(ops[opi]["am_mac_open"]) + am_mac.data.clear() + add_to_macro_data(am_mac.data, + loop=ops[opi]["am_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["am_mac_len"])]) + + ar_mac = SingleMacro(kind=OpMacroCode.AR) + ar_mac.open = bool(ops[opi]["ar_mac_open"]) + ar_mac.data.clear() + add_to_macro_data(ar_mac.data, + loop=ops[opi]["ar_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["ar_mac_len"])]) + + dr_mac = SingleMacro(kind=OpMacroCode.DR) + dr_mac.open = bool(ops[opi]["dr_mac_open"]) + dr_mac.data.clear() + add_to_macro_data(dr_mac.data, + loop=ops[opi]["dr_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["dr_mac_len"])]) + + mult_mac = SingleMacro(kind=OpMacroCode.MULT) + mult_mac.open = bool(ops[opi]["mult_mac_open"]) + mult_mac.data.clear() + add_to_macro_data(mult_mac.data, + loop=ops[opi]["mult_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["mult_mac_len"])]) + + rr_mac = SingleMacro(kind=OpMacroCode.RR) + rr_mac.open = bool(ops[opi]["rr_mac_open"]) + rr_mac.data.clear() + add_to_macro_data(rr_mac.data, + loop=ops[opi]["rr_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["rr_mac_len"])]) + + sl_mac = SingleMacro(kind=OpMacroCode.SL) + sl_mac.open = bool(ops[opi]["sl_mac_open"]) + sl_mac.data.clear() + add_to_macro_data(sl_mac.data, + loop=ops[opi]["sl_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["sl_mac_len"])]) + + tl_mac = SingleMacro(kind=OpMacroCode.TL) + tl_mac.open = bool(ops[opi]["tl_mac_open"]) + tl_mac.data.clear() + add_to_macro_data(tl_mac.data, + loop=ops[opi]["tl_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["tl_mac_len"])]) + + dt2_mac = SingleMacro(kind=OpMacroCode.DT2) + dt2_mac.open = bool(ops[opi]["dt2_mac_open"]) + dt2_mac.data.clear() + add_to_macro_data(dt2_mac.data, + loop=ops[opi]["dt2_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["dt2_mac_len"])]) + + rs_mac = SingleMacro(kind=OpMacroCode.RS) + rs_mac.open = bool(ops[opi]["rs_mac_open"]) + rs_mac.data.clear() + add_to_macro_data(rs_mac.data, + loop=ops[opi]["rs_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["rs_mac_len"])]) + + dt_mac = SingleMacro(kind=OpMacroCode.DT) + dt_mac.open = bool(ops[opi]["dt_mac_open"]) + dt_mac.data.clear() + add_to_macro_data(dt_mac.data, + loop=ops[opi]["dt_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["dt_mac_len"])]) + + d2r_mac = SingleMacro(kind=OpMacroCode.D2R) + d2r_mac.open = bool(ops[opi]["d2r_mac_open"]) + d2r_mac.data.clear() + add_to_macro_data(d2r_mac.data, + loop=ops[opi]["d2r_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["d2r_mac_len"])]) + + ssg_mac = SingleMacro(kind=OpMacroCode.SSG_EG) + ssg_mac.open = bool(ops[opi]["ssg_mac_open"]) + ssg_mac.data.clear() + add_to_macro_data(ssg_mac.data, + loop=ops[opi]["ssg_mac_loop"], + release=None, + data=[read_int(ins_data) for _ in range(ops[opi]["ssg_mac_len"])]) + + new_op.macros.extend([ + am_mac, ar_mac, dr_mac, mult_mac, rr_mac, + sl_mac, tl_mac, dt2_mac, rs_mac, dt_mac, + d2r_mac, ssg_mac + ]) # must be in order!! + + new_ops[opi] = new_op + + # release points + if True: + if self.meta.version >= 44: + add_to_macro_data(vol_mac.data, None, read_int(ins_data), None) + add_to_macro_data(arp_mac.data, None, read_int(ins_data), None) + add_to_macro_data(duty_mac.data, None, read_int(ins_data), None) + add_to_macro_data(wave_mac.data, None, read_int(ins_data), None) + add_to_macro_data(pitch_mac.data, None, read_int(ins_data), None) + add_to_macro_data(x1_mac.data, None, read_int(ins_data), None) + add_to_macro_data(x2_mac.data, None, read_int(ins_data), None) + add_to_macro_data(x3_mac.data, None, read_int(ins_data), None) + add_to_macro_data(alg_mac.data, None, read_int(ins_data), None) + add_to_macro_data(fb_mac.data, None, read_int(ins_data), None) + add_to_macro_data(fms_mac.data, None, read_int(ins_data), None) + add_to_macro_data(ams_mac.data, None, read_int(ins_data), None) + + for opi in new_ops: + for i in range(12): + add_to_macro_data(new_ops[opi].macros[i].data, None, read_int(ins_data), None) + + # extended op macros + if True: + if self.meta.version >= 61: + for op in new_ops: + dam_mac = SingleMacro(kind=OpMacroCode.DAM) + dvb_mac = SingleMacro(kind=OpMacroCode.DVB) + egt_mac = SingleMacro(kind=OpMacroCode.EGT) + ksl_mac = SingleMacro(kind=OpMacroCode.KSL) + sus_mac = SingleMacro(kind=OpMacroCode.SUS) + vib_mac = SingleMacro(kind=OpMacroCode.VIB) + ws_mac = SingleMacro(kind=OpMacroCode.WS) + ksr_mac = SingleMacro(kind=OpMacroCode.KSR) + + dam_mac_len = read_int(ins_data) + dvb_mac_len = read_int(ins_data) + egt_mac_len = read_int(ins_data) + ksl_mac_len = read_int(ins_data) + sus_mac_len = read_int(ins_data) + vib_mac_len = read_int(ins_data) + ws_mac_len = read_int(ins_data) + ksr_mac_len = read_int(ins_data) + + dam_mac_loop = read_int(ins_data) + dvb_mac_loop = read_int(ins_data) + egt_mac_loop = read_int(ins_data) + ksl_mac_loop = read_int(ins_data) + sus_mac_loop = read_int(ins_data) + vib_mac_loop = read_int(ins_data) + ws_mac_loop = read_int(ins_data) + ksr_mac_loop = read_int(ins_data) + + dam_mac_rel = read_int(ins_data) + dvb_mac_rel = read_int(ins_data) + egt_mac_rel = read_int(ins_data) + ksl_mac_rel = read_int(ins_data) + sus_mac_rel = read_int(ins_data) + vib_mac_rel = read_int(ins_data) + ws_mac_rel = read_int(ins_data) + ksr_mac_rel = read_int(ins_data) + + dam_mac.open = bool(read_byte(ins_data)) + dvb_mac.open = bool(read_byte(ins_data)) + egt_mac.open = bool(read_byte(ins_data)) + ksl_mac.open = bool(read_byte(ins_data)) + sus_mac.open = bool(read_byte(ins_data)) + vib_mac.open = bool(read_byte(ins_data)) + ws_mac.open = bool(read_byte(ins_data)) + ksr_mac.open = bool(read_byte(ins_data)) + + dam_mac.data.clear() + dvb_mac.data.clear() + egt_mac.data.clear() + ksl_mac.data.clear() + sus_mac.data.clear() + vib_mac.data.clear() + ws_mac.data.clear() + ksr_mac.data.clear() + + add_to_macro_data(dam_mac.data, dam_mac_loop, dam_mac_rel, [ + read_byte(ins_data) for _ in range(dam_mac_len) + ]) + add_to_macro_data(dvb_mac.data, dvb_mac_loop, dvb_mac_rel, [ + read_byte(ins_data) for _ in range(dvb_mac_len) + ]) + add_to_macro_data(egt_mac.data, egt_mac_loop, egt_mac_rel, [ + read_byte(ins_data) for _ in range(egt_mac_len) + ]) + add_to_macro_data(ksl_mac.data, ksl_mac_loop, ksl_mac_rel, [ + read_byte(ins_data) for _ in range(ksl_mac_len) + ]) + add_to_macro_data(sus_mac.data, sus_mac_loop, sus_mac_rel, [ + read_byte(ins_data) for _ in range(sus_mac_len) + ]) + add_to_macro_data(vib_mac.data, vib_mac_loop, vib_mac_rel, [ + read_byte(ins_data) for _ in range(vib_mac_len) + ]) + add_to_macro_data(ws_mac.data, ws_mac_loop, ws_mac_rel, [ + read_byte(ins_data) for _ in range(ws_mac_len) + ]) + add_to_macro_data(ksr_mac.data, ksr_mac_loop, ksr_mac_rel, [ + read_byte(ins_data) for _ in range(ksr_mac_len) + ]) + + new_ops[op].macros.extend([ + dam_mac, dvb_mac, egt_mac, ksl_mac, sus_mac, vib_mac, + ws_mac, ksr_mac + ]) + + # opl drum data + if True: + if self.meta.version >= 63: + opl_drum = InsFeatureOPLDrums( + fixed_drums = bool(read_byte(ins_data)) + ) + read_byte(ins_data) + opl_drum.kick_freq = read_short(ins_data) + opl_drum.snare_hat_freq = read_short(ins_data) + opl_drum.tom_top_freq = read_short(ins_data) + self.features.append(opl_drum) + + # clear macros + if True: + if self.meta.version < 63 and self.meta.type == InstrumentType.PCE: + duty_mac.data.clear() + if self.meta.version < 70 and self.meta.type == InstrumentType.FM_OPLL: + wave_mac.data.clear() + + # sample map + if True: + if self.meta.version >= 67: + note_map = InsFeatureAmiga() + note_map.use_note_map = bool(read_byte(ins_data)) + if note_map.use_note_map: + for i in range(len(note_map.sample_map)): + note_map.sample_map[i].freq = read_int(ins_data) + for i in range(len(note_map.sample_map)): + note_map.sample_map[i].sample_index = read_short(ins_data) + self.features.append(note_map) + + # n163 + if True: + if self.meta.version >= 73: + n163 = InsFeatureN163( + wave=read_int(ins_data), + wave_pos=read_byte(ins_data), + wave_len=read_byte(ins_data), + wave_mode=read_byte(ins_data) + ) + read_byte(ins_data) # reserved + self.features.append(n163) + + # moar macroes + if True: + if self.meta.version >= 76: + pan_l_mac = SingleMacro(kind=MacroCode.PAN_L) + pan_r_mac = SingleMacro(kind=MacroCode.PAN_R) + phase_res_mac = SingleMacro(kind=MacroCode.PHASE_RESET) + x4_mac = SingleMacro(kind=MacroCode.EX4) + x5_mac = SingleMacro(kind=MacroCode.EX5) + x6_mac = SingleMacro(kind=MacroCode.EX6) + x7_mac = SingleMacro(kind=MacroCode.EX7) + x8_mac = SingleMacro(kind=MacroCode.EX8) + + pan_l_mac.data.clear() + pan_r_mac.data.clear() + phase_res_mac.data.clear() + x4_mac.data.clear() + x5_mac.data.clear() + x6_mac.data.clear() + x7_mac.data.clear() + x8_mac.data.clear() + + pan_l_mac_len = read_int(ins_data) + pan_r_mac_len = read_int(ins_data) + phase_res_mac_len = read_int(ins_data) + x4_mac_len = read_int(ins_data) + x5_mac_len = read_int(ins_data) + x6_mac_len = read_int(ins_data) + x7_mac_len = read_int(ins_data) + x8_mac_len = read_int(ins_data) + + pan_l_mac_loop = read_int(ins_data) + pan_r_mac_loop = read_int(ins_data) + phase_res_mac_loop = read_int(ins_data) + x4_mac_loop = read_int(ins_data) + x5_mac_loop = read_int(ins_data) + x6_mac_loop = read_int(ins_data) + x7_mac_loop = read_int(ins_data) + x8_mac_loop = read_int(ins_data) + + pan_l_mac_rel = read_int(ins_data) + pan_r_mac_rel = read_int(ins_data) + phase_res_mac_rel = read_int(ins_data) + x4_mac_rel = read_int(ins_data) + x5_mac_rel = read_int(ins_data) + x6_mac_rel = read_int(ins_data) + x7_mac_rel = read_int(ins_data) + x8_mac_rel = read_int(ins_data) + + pan_l_mac.open = bool(read_byte(ins_data)) + pan_r_mac.open = bool(read_byte(ins_data)) + phase_res_mac.open = bool(read_byte(ins_data)) + x4_mac.open = bool(read_byte(ins_data)) + x5_mac.open = bool(read_byte(ins_data)) + x6_mac.open = bool(read_byte(ins_data)) + x7_mac.open = bool(read_byte(ins_data)) + x8_mac.open = bool(read_byte(ins_data)) + + add_to_macro_data(pan_l_mac.data, pan_l_mac_loop, pan_l_mac_rel, [ + read_int(ins_data) for _ in range(pan_l_mac_len) + ]) + add_to_macro_data(pan_r_mac.data, pan_r_mac_loop, pan_r_mac_rel, [ + read_int(ins_data) for _ in range(pan_r_mac_len) + ]) + add_to_macro_data(phase_res_mac.data, phase_res_mac_loop, phase_res_mac_rel, [ + read_int(ins_data) for _ in range(phase_res_mac_len) + ]) + add_to_macro_data(x4_mac.data, x4_mac_loop, x4_mac_rel, [ + read_int(ins_data) for _ in range(x4_mac_len) + ]) + add_to_macro_data(x5_mac.data, x5_mac_loop, x5_mac_rel, [ + read_int(ins_data) for _ in range(x5_mac_len) + ]) + add_to_macro_data(x6_mac.data, x6_mac_loop, x6_mac_rel, [ + read_int(ins_data) for _ in range(x6_mac_len) + ]) + add_to_macro_data(x7_mac.data, x7_mac_loop, x7_mac_rel, [ + read_int(ins_data) for _ in range(x7_mac_len) + ]) + add_to_macro_data(x8_mac.data, x8_mac_loop, x8_mac_rel, [ + read_int(ins_data) for _ in range(x8_mac_len) + ]) + + mac_list.extend([ + pan_l_mac, pan_r_mac, phase_res_mac, x4_mac, + x5_mac, x6_mac, x7_mac, x8_mac + ]) + + # fds + if True: + if self.meta.version >= 76: + fds = InsFeatureFDS( + mod_speed=read_int(ins_data), + mod_depth=read_int(ins_data), + init_table_with_first_wave=bool(read_byte(ins_data)) + ) + read_byte(ins_data) # reserved + read_byte(ins_data) + read_byte(ins_data) + fds.mod_table = [read_byte(ins_data) for _ in range(32)] + self.features.append(fds) + + # opz + if True: + if self.meta.version >= 77: + fm.fms2 = read_byte(ins_data) + fm.ams2 = read_byte(ins_data) + + # wave synth + if True: + if self.meta.version >= 79: + ws = InsFeatureWaveSynth( + wave_indices=[read_int(ins_data), read_int(ins_data)], + rate_divider=read_byte(ins_data), + effect=WaveFX(read_byte(ins_data)), + enabled=bool(read_byte(ins_data)), + global_effect=bool(read_byte(ins_data)), + speed=read_byte(ins_data), + params=[read_byte(ins_data) for _ in range(4)] + ) + self.features.append(ws) + + # macro moads + if True: + if self.meta.version >= 84: + vol_mac.mode = read_byte(ins_data) + duty_mac.mode = read_byte(ins_data) + wave_mac.mode = read_byte(ins_data) + pitch_mac.mode = read_byte(ins_data) + x1_mac.mode = read_byte(ins_data) + x2_mac.mode = read_byte(ins_data) + x3_mac.mode = read_byte(ins_data) + alg_mac.mode = read_byte(ins_data) + fb_mac.mode = read_byte(ins_data) + fms_mac.mode = read_byte(ins_data) + ams_mac.mode = read_byte(ins_data) + pan_l_mac.mode = read_byte(ins_data) + pan_r_mac.mode = read_byte(ins_data) + phase_res_mac.mode = read_byte(ins_data) + x4_mac.mode = read_byte(ins_data) + x5_mac.mode = read_byte(ins_data) + x6_mac.mode = read_byte(ins_data) + x7_mac.mode = read_byte(ins_data) + x8_mac.mode = read_byte(ins_data) + + # c64 no test + if True: + if self.meta.version >= 89: + c64.no_test = bool(read_byte(ins_data)) + + # multipcm + if True: + if self.meta.version >= 93: + mp = InsFeatureMultiPCM( + ar=read_byte(ins_data), + d1r=read_byte(ins_data), + dl=read_byte(ins_data), + d2r=read_byte(ins_data), + rr=read_byte(ins_data), + rc=read_byte(ins_data), + lfo=read_byte(ins_data), + vib=read_byte(ins_data), + am=read_byte(ins_data) + ) + for _ in range(23): # reserved + read_byte(ins_data) + self.features.append(mp) + + # sound unit + if True: + if self.meta.version >= 104: + amiga.use_sample = bool(read_byte(ins_data)) + su = InsFeatureSoundUnit( + switch_roles=bool(read_byte(ins_data)) + ) + self.features.append(su) + + # gb hw seq + if True: + if self.meta.version >= 105: + gb_hwseq_len = read_byte(ins_data) + gb.hw_seq.clear() + for i in range(gb_hwseq_len): + gb.hw_seq.append( + GBHwSeq( + command=GBHwCommand(read_byte(ins_data)), + data=[read_byte(ins_data), read_byte(ins_data)] + ) + ) + + # additional gb + if True: + if self.meta.version >= 106: + gb.soft_env = bool(read_byte(ins_data)) + gb.always_init = bool(read_byte(ins_data)) + + # es5506 + if True: + if self.meta.version >= 107: + es = InsFeatureES5506( + filter_mode=ESFilterMode(read_byte(ins_data)), + k1=read_short(ins_data), + k2=read_short(ins_data), + env_count=read_short(ins_data), + left_volume_ramp=read_byte(ins_data), + right_volume_ramp=read_byte(ins_data), + k1_ramp=read_byte(ins_data), + k2_ramp=read_byte(ins_data), + k1_slow=read_byte(ins_data), + k2_slow=read_byte(ins_data) + ) + self.features.append(es) + + # snes + if True: + if self.meta.version >= 109: + snes = InsFeatureSNES() + snes.use_env = bool(read_byte(ins_data)) + if self.meta.version >= 118: + snes.gain_mode = GainMode(read_byte(ins_data)) + snes.gain = read_byte(ins_data) + else: + read_byte(ins_data) + read_byte(ins_data) + snes.envelope.a = read_byte(ins_data) + snes.envelope.d = read_byte(ins_data) + snes_env_s = read_byte(ins_data) + snes.envelope.s = snes_env_s & 0b111 + snes.envelope.r = read_byte(ins_data) + snes.sus = SNESSusMode((snes_env_s >> 3) & 1) # ??? + self.features.append(snes) + + # macro speed delay + if True: + if self.meta.version >= 111: + vol_mac.speed = read_byte(ins_data) + arp_mac.speed = read_byte(ins_data) + duty_mac.speed = read_byte(ins_data) + wave_mac.speed = read_byte(ins_data) + pitch_mac.speed = read_byte(ins_data) + x1_mac.speed = read_byte(ins_data) + x2_mac.speed = read_byte(ins_data) + x3_mac.speed = read_byte(ins_data) + alg_mac.speed = read_byte(ins_data) + fb_mac.speed = read_byte(ins_data) + fms_mac.speed = read_byte(ins_data) + ams_mac.speed = read_byte(ins_data) + pan_l_mac.speed = read_byte(ins_data) + pan_r_mac.speed = read_byte(ins_data) + phase_res_mac.speed = read_byte(ins_data) + x4_mac.speed = read_byte(ins_data) + x5_mac.speed = read_byte(ins_data) + x6_mac.speed = read_byte(ins_data) + x7_mac.speed = read_byte(ins_data) + x8_mac.speed = read_byte(ins_data) + + vol_mac.delay = read_byte(ins_data) + arp_mac.delay = read_byte(ins_data) + duty_mac.delay = read_byte(ins_data) + wave_mac.delay = read_byte(ins_data) + pitch_mac.delay = read_byte(ins_data) + x1_mac.delay = read_byte(ins_data) + x2_mac.delay = read_byte(ins_data) + x3_mac.delay = read_byte(ins_data) + alg_mac.delay = read_byte(ins_data) + fb_mac.delay = read_byte(ins_data) + fms_mac.delay = read_byte(ins_data) + ams_mac.delay = read_byte(ins_data) + pan_l_mac.delay = read_byte(ins_data) + pan_r_mac.delay = read_byte(ins_data) + phase_res_mac.delay = read_byte(ins_data) + x4_mac.delay = read_byte(ins_data) + x5_mac.delay = read_byte(ins_data) + x6_mac.delay = read_byte(ins_data) + x7_mac.delay = read_byte(ins_data) + x8_mac.delay = read_byte(ins_data) + + for op in ops: + for i in range(20): + new_ops[op].macros[i].speed = read_byte(ins_data) + for i in range(20): + new_ops[op].macros[i].delay = read_byte(ins_data) + + # old arp mac format + if True: + if self.meta.version < 112: + if arp_mac.mode != 0: + arp_mac.mode = 0 + for i in range(len(arp_mac.data)): + if isinstance(arp_mac.data[i], int): + arp_mac.data[i] ^= 0x40000000 + + # add ops macros at the end + if True: + if self.meta.version >= 29: + for _, op_contents in new_ops.items(): + self.features.append(op_contents) diff --git a/loader/samples/minexample/furC64/chipchune/furnace/module.py b/loader/samples/minexample/furC64/chipchune/furnace/module.py new file mode 100644 index 0000000..e6e7b27 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/furnace/module.py @@ -0,0 +1,1111 @@ +import re +import zlib +from io import BytesIO, BufferedReader +from typing import BinaryIO, Optional, Literal, Union, Dict, List + +from chipchune._util import read_byte, read_short, read_int, read_float, read_str +from .data_types import ( + ModuleMeta, ChipList, ModuleCompatFlags, SubSong, PatchBay, ChannelDisplayInfo, + InputPatchBayEntry, OutputPatchBayEntry, ChipInfo, FurnacePattern, FurnaceRow +) +from .enums import ( + ChipType, LinearPitch, InputPortSet, OutputPortSet, LoopModality, + DelayBehavior, JumpTreatment, _FurInsImportType, _FurWavetableImportType, Note +) +from .instrument import FurnaceInstrument +from .wavetable import FurnaceWavetable +from .sample import FurnaceSample + +MAGIC_STR = b'-Furnace module-' +MAX_CHIPS = 32 + + +class FurnaceModule: + """ + Represents a Furnace .fur file. + + When possible, instrument objects etc. will use the latest format as its internal + representation. For example, old instruments will internally be converted into the + "new" instrument-feature-list format. + """ + + def __init__(self, file_name_or_stream: Optional[Union[BufferedReader, str]] = None) -> None: + """ + Creates or opens a new Furnace module as a Python object. + + :param file_name_or_stream: (Optional) + If specified, then it will parse a file as a FurnaceModule. If file name (str) is + given, it will load that file. If a stream (BufferedReader) instead is given, + it will parse it from the stream. + + Defaults to None. + """ + self.file_name: Optional[str] = None + """ + Original file name, if the object was initialized with one. + """ + self.meta: ModuleMeta = ModuleMeta() + """ + Metadata concerning the module. + """ + self.chips: ChipList = ChipList() + """ + List of chips used in the module. + """ + self.compat_flags: ModuleCompatFlags = ModuleCompatFlags() + """ + Compat flags settings within the module. + """ + self.subsongs: List[SubSong] = [SubSong()] + """ + Subsongs contained within the module. Although the first subsong + and the others are internally stored separately, they're organized + into a list here for convenience. + """ + self.patchbay: List[PatchBay] = [] + """ + List of patchbay connections. + """ + self.instruments: List[FurnaceInstrument] = [] + """ + List of all instruments in the module. + """ + self.patterns: List[FurnacePattern] = [] + """ + List of all patterns in the module. + """ + self.wavetables: List[FurnaceWavetable] = [] + + self.samples: List[FurnaceWavetable] = [] + + if isinstance(file_name_or_stream, BufferedReader): + self.load_from_stream(file_name_or_stream) + elif isinstance(file_name_or_stream, str): + self.load_from_file(file_name_or_stream) + + def load_from_file(self, file_name: Optional[str] = None) -> None: + """ + Load a module from a file name. The file may either be compressed or uncompressed. + + :param file_name: If not specified, it will grab from self.file_name instead. + """ + if isinstance(file_name, str): + self.file_name = file_name + if self.file_name is None: + raise RuntimeError('No file name set, either set self.file_name or pass file_name to the function') + with open(self.file_name, 'rb') as f: + detect_magic = f.peek(len(MAGIC_STR))[:len(MAGIC_STR)] + if detect_magic != MAGIC_STR: # this is probably compressed, so try decompressing it first + return self.load_from_bytes( + zlib.decompress(f.read()) + ) + else: # uncompressed for sure + return self.load_from_stream(f) + + @staticmethod + def decompress_to_file(in_name: str, out_name: str) -> int: + """ + Simple zlib wrapper. Decompresses a zlib-compressed .fur + from in_name to out_name. Does not need instantiation. + + :param in_name: input file name + :param out_name: output file name + :return: Results of file.write(). + """ + with open(in_name, 'rb') as fi: + with open(out_name, 'wb') as fo: + return fo.write(zlib.decompress(fi.read())) + + def load_from_bytes(self, data: bytes) -> None: + """ + Load a module from a series of bytes. + + :param data: Bytes + """ + return self.load_from_stream( + BytesIO(data) + ) + + def load_from_stream(self, stream: BinaryIO) -> None: + """ + Load a module from an **uncompressed** stream. + + :param stream: File-like object containing the uncompressed module. + """ + # assumes uncompressed stream + if stream.read(len(MAGIC_STR)) != MAGIC_STR: + raise RuntimeError('Bad magic value; this is not a Furnace file or is corrupt') + + # clear defaults + self.chips.list.clear() + self.patchbay.clear() + self.subsongs[0].order.clear() + self.subsongs[0].speed_pattern.clear() + + self.__read_header(stream) + self.__init_compat_flags() + self.__read_info(stream) + if self.meta.version >= 119: + self.__read_dev119_chip_flags(stream) + self.__read_instruments(stream) + self.__read_wavetables(stream) + self.__read_samples(stream) + if self.meta.version >= 95: + self.__read_subsongs(stream) + self.__read_patterns(stream) + + def get_num_channels(self) -> int: + """ + Retrieve the number of total channels in the module. + + :return: Channel sum across all chips. + """ + num_channels = 0 + for chip in self.chips.list: + num_channels += chip.type.channels + return num_channels + + def get_pattern(self, channel: int, index: int, subsong: int=0) -> Optional[FurnacePattern]: + """ + Gets one pattern object from a module. + + :param channel: Which channel to use (zero-indexed), e.g. to get VRC6 + in a NES+VRC6 module, use `5`. + :param index: The index of the pattern within the subsong. + :param subsong: The subsong number. + :return: FurnacePattern object or None if no such pattern exists. + """ + try: + return next( + filter(lambda x: x.channel==channel and x.index==index and x.subsong==subsong, self.patterns) + ) + except StopIteration: + return None + + def __init_compat_flags(self) -> None: + """ + Initializes appropriate compat flags based on module version + """ + if self.meta.version < 37: + self.compat_flags.limit_slides = True + self.compat_flags.linear_pitch = LinearPitch.ONLY_PITCH_CHANGE + self.compat_flags.loop_modality = LoopModality.HARD_RESET_CHANNELS + if self.meta.version < 43: + self.compat_flags.proper_noise_layout = False + self.compat_flags.wave_duty_is_volume = False + if self.meta.version < 45: + self.compat_flags.reset_macro_on_porta = True + self.compat_flags.legacy_volume_slides = True + self.compat_flags.compatible_arpeggio = True + self.compat_flags.note_off_resets_slides = True + self.compat_flags.target_resets_slides = True + if self.meta.version < 46: + self.compat_flags.arpeggio_inhibits_portamento = True + self.compat_flags.wack_algorithm_macro = True + if self.meta.version < 49: + self.compat_flags.broken_shortcut_slides = True + if self.meta.version < 50: + self.compat_flags.ignore_duplicates_slides = False + if self.meta.version < 62: + self.compat_flags.stop_portamento_on_note_off = True + if self.meta.version < 64: + self.compat_flags.broken_dac_mode = False + if self.meta.version < 65: + self.compat_flags.one_tick_cut = False + if self.meta.version < 66: + self.compat_flags.instrument_change_allowed_in_porta = False + if self.meta.version < 69: + self.compat_flags.reset_note_base_on_arpeggio_stop = False + if self.meta.version < 71: + self.compat_flags.no_slides_on_first_tick = False + self.compat_flags.next_row_reset_arp_pos = False + self.compat_flags.ignore_jump_at_end = True + if self.meta.version < 72: + self.compat_flags.buggy_portamento_after_slide = True + self.compat_flags.gb_ins_affects_env = False + if self.meta.version < 78: + self.compat_flags.shared_extch_state = False + if self.meta.version < 83: + self.compat_flags.ignore_outside_dac_mode_change = True + self.compat_flags.e1e2_takes_priority = False + if self.meta.version < 84: + self.compat_flags.new_sega_pcm = False + if self.meta.version < 85: + self.compat_flags.weird_fnum_pitch_slides = True + if self.meta.version < 86: + self.compat_flags.sn_duty_resets_phase = True + if self.meta.version < 90: + self.compat_flags.linear_pitch_macro = False + if self.meta.version < 97: + self.compat_flags.old_octave_boundary = True + self.compat_flags.disable_opn2_dac_volume_control = True # dev98 + if self.meta.version < 99: + self.compat_flags.new_volume_scaling = False + self.compat_flags.volume_macro_lingers = False + self.compat_flags.broken_out_vol = True + if self.meta.version < 100: + self.compat_flags.e1e2_stop_on_same_note = False + if self.meta.version < 101: + self.compat_flags.broken_porta_after_arp = True + if self.meta.version < 108: + self.compat_flags.sn_no_low_periods = True + if self.meta.version < 110: + self.compat_flags.cut_delay_effect_policy = DelayBehavior.BROKEN + if self.meta.version < 113: + self.compat_flags.jump_treatment = JumpTreatment.FIRST_JUMP_ONLY + if self.meta.version < 115: + self.compat_flags.auto_sys_name = True + if self.meta.version < 117: + self.compat_flags.disable_sample_macro = True + if self.meta.version < 121: + self.compat_flags.broken_out_vol_2 = False + if self.meta.version < 130: + self.compat_flags.old_arp_strategy = True + if self.meta.version < 138: + self.compat_flags.broken_porta_during_legato = True + if self.meta.version < 155: + self.compat_flags.broken_fm_off = True + if self.meta.version < 168: + self.compat_flags.pre_note_no_effect = True + if self.meta.version < 183: + self.compat_flags.old_dpcm = True + if self.meta.version < 184: + self.compat_flags.reset_arp_phase_on_new_note = False + if self.meta.version < 188: + self.compat_flags.ceil_volume_scaling = False + if self.meta.version < 191: + self.compat_flags.old_always_set_volume = True + if self.meta.version < 200: + self.compat_flags.old_sample_offset = True + + # XXX: update my signature whenever a new compat flag block is added + def __read_compat_flags(self, stream: BinaryIO, phase: Literal[1, 2, 3]) -> None: + """ + Reads the set compat flags in the module + """ + if phase == 1: + compat_flags_to_skip = 20 + if self.meta.version < 37: + self.compat_flags.limit_slides = True + self.compat_flags.linear_pitch = LinearPitch.ONLY_PITCH_CHANGE + self.compat_flags.loop_modality = LoopModality.HARD_RESET_CHANNELS + else: # >= 37 + self.compat_flags.limit_slides = bool(read_byte(stream)) + self.compat_flags.linear_pitch = LinearPitch(read_byte(stream)) + self.compat_flags.loop_modality = LoopModality(read_byte(stream)) + compat_flags_to_skip -= 3 + + if self.meta.version >= 43: + self.compat_flags.proper_noise_layout = bool(read_byte(stream)) + self.compat_flags.wave_duty_is_volume = bool(read_byte(stream)) + compat_flags_to_skip -= 2 + + if self.meta.version >= 45: + self.compat_flags.reset_macro_on_porta = bool(read_byte(stream)) + self.compat_flags.legacy_volume_slides = bool(read_byte(stream)) + self.compat_flags.compatible_arpeggio = bool(read_byte(stream)) + self.compat_flags.note_off_resets_slides = bool(read_byte(stream)) + self.compat_flags.target_resets_slides = bool(read_byte(stream)) + compat_flags_to_skip -= 5 + + if self.meta.version >= 47: + self.compat_flags.arpeggio_inhibits_portamento = bool(read_byte(stream)) + self.compat_flags.wack_algorithm_macro = bool(read_byte(stream)) + compat_flags_to_skip -= 2 + + if self.meta.version >= 49: + self.compat_flags.broken_shortcut_slides = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 50: + self.compat_flags.ignore_duplicates_slides = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 62: + self.compat_flags.stop_portamento_on_note_off = bool(read_byte(stream)) + self.compat_flags.continuous_vibrato = bool(read_byte(stream)) + compat_flags_to_skip -= 2 + + if self.meta.version >= 64: + self.compat_flags.broken_dac_mode = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 65: + self.compat_flags.one_tick_cut = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 66: + self.compat_flags.instrument_change_allowed_in_porta = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 69: + self.compat_flags.reset_note_base_on_arpeggio_stop = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + elif phase == 2: + compat_flags_to_skip = 28 + if self.meta.version >= 70: + self.compat_flags.broken_speed_selection = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 71: + self.compat_flags.no_slides_on_first_tick = bool(read_byte(stream)) + self.compat_flags.next_row_reset_arp_pos = bool(read_byte(stream)) + self.compat_flags.ignore_jump_at_end = bool(read_byte(stream)) + compat_flags_to_skip -= 3 + + if self.meta.version >= 72: + self.compat_flags.buggy_portamento_after_slide = bool(read_byte(stream)) + self.compat_flags.gb_ins_affects_env = bool(read_byte(stream)) + compat_flags_to_skip -= 2 + + if self.meta.version >= 78: + self.compat_flags.shared_extch_state = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 83: + self.compat_flags.ignore_outside_dac_mode_change = bool(read_byte(stream)) + self.compat_flags.e1e2_takes_priority = bool(read_byte(stream)) + compat_flags_to_skip -= 2 + + if self.meta.version >= 84: + self.compat_flags.new_sega_pcm = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 85: + self.compat_flags.weird_fnum_pitch_slides = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 86: + self.compat_flags.sn_duty_resets_phase = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 90: + self.compat_flags.linear_pitch_macro = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 94: + self.compat_flags.pitch_slide_speed_in_linear = read_byte(stream) + compat_flags_to_skip -= 1 + + if self.meta.version >= 97: + self.compat_flags.old_octave_boundary = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 98: + self.compat_flags.disable_opn2_dac_volume_control = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 99: + self.compat_flags.new_volume_scaling = bool(read_byte(stream)) + self.compat_flags.volume_macro_lingers = bool(read_byte(stream)) + self.compat_flags.broken_out_vol = bool(read_byte(stream)) + compat_flags_to_skip -= 3 + + if self.meta.version >= 100: + self.compat_flags.e1e2_stop_on_same_note = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 101: + self.compat_flags.broken_porta_after_arp = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 108: + self.compat_flags.sn_no_low_periods = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 110: + self.compat_flags.cut_delay_effect_policy = DelayBehavior(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 113: + self.compat_flags.jump_treatment = JumpTreatment(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 115: + self.compat_flags.auto_sys_name = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 117: + self.compat_flags.disable_sample_macro = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 121: + self.compat_flags.broken_out_vol_2 = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 130: + self.compat_flags.old_arp_strategy = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + elif phase == 3: + compat_flags_to_skip = 8 + if self.meta.version >= 138: + self.compat_flags.broken_porta_during_legato = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 155: + self.compat_flags.broken_fm_off = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 168: + self.compat_flags.pre_note_no_effect = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 183: + self.compat_flags.old_dpcm = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 184: + self.compat_flags.reset_arp_phase_on_new_note = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 188: + self.compat_flags.ceil_volume_scaling = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + + if self.meta.version >= 191: + self.compat_flags.old_always_set_volume = bool(read_byte(stream)) + compat_flags_to_skip -= 1 + else: + raise ValueError( + 'Compat flag phase must be in between: 1, 2, 3' + ) + stream.read(compat_flags_to_skip) + + def __read_dev119_chip_flags(self, stream: BinaryIO) -> None: + for i in range(len(self.chips.list)): + # skip if this chip doesn't have flags + if self.__chip_flag_ptr[i] == 0: + continue + stream.seek(self.__chip_flag_ptr[i]) + + if stream.read(4) != b'FLAG': + raise ValueError('No "FLAG" magic') + + # i assume this will grow, you never know + blk_size = read_int(stream) + flag_blk = BytesIO(stream.read(blk_size)) + + # read entries in FLAG + for entry in [flag.split('=') for flag in read_str(flag_blk).split()]: + key = entry[0] + value = entry[1] + # cast by regex + if re.match(r'true', value): + self.chips.list[i].flags[key] = True + elif re.match(r'false', value): + self.chips.list[i].flags[key] = False + elif re.match(r'\d+$', value): + self.chips.list[i].flags[key] = int(value) + elif re.match(r'\d+\.\d+', value): + self.chips.list[i].flags[key] = float(value) + else: # all other values should be treated as a string + self.chips.list[i].flags[key] = value + + @staticmethod + def __convert_old_chip_flags(chip: ChipType, flag: int) -> Dict[str, Union[bool, int]]: + """ + Convert pre-v119 binary chip flags to the newer dict-style form. + + :param chip: ChipType + :param flag: flag value as a 32-bit number + :return: dictionary containing the flag's equivalent values + """ + n = {} + + if chip in [ChipType.GENESIS, ChipType.GENESIS_EX]: + n['clockSel'] = flag & 2147483647 # bits 0-30 + n['ladderEffect'] = bool((flag >> 31) & 1) + elif chip == ChipType.SMS: + cs = flag & 0xff03 + if cs > 0x100: + cs = cs - 252 # 0x100 + 4 + n['clockSel'] = cs + ct = (flag & 0xcc) // 4 + if ct >= 32: + ct -= 24 + elif ct >= 16: + ct -= 12 + n['chipType'] = ct + n['noPhaseReset'] = flag >> 4 + elif chip == ChipType.GB: + n['chipType'] = flag & 0b11 + n['noAntiClick'] = bool((flag >> 3) & 1) + elif chip == ChipType.PCE: + n['clockSel'] = flag & 1 + n['chipType'] = (flag >> 2) & 1 + n['noAntiClick'] = bool((flag >> 3) & 1) + elif chip in [ChipType.NES, ChipType.VRC6, ChipType.FDS, ChipType.MMC5]: + n['clockSel'] = flag & 0b11 + elif chip in [ChipType.C64_8580, ChipType.C64_6581]: + n['clockSel'] = flag & 0b1111 + elif chip == ChipType.SEGA_ARCADE: + n['clockSel'] = flag & 0b11111111 + elif chip in [ChipType.NEO_GEO_CD, ChipType.NEO_GEO, ChipType.NEO_GEO_EX, + ChipType.NEO_GEO_CD_EX, ChipType.YM2610B, ChipType.YM2610B_EX]: + n['clockSel'] = flag & 0b11111111 + elif chip == ChipType.AY38910: + n['clockSel'] = flag & 0b1111 + n['chipType'] = (flag >> 4) & 0b11 + n['stereo'] = bool((flag >> 6) & 1) + n['halfClock'] = bool((flag >> 7) & 1) + n['stereoSep'] = (flag >> 8) & 0b11111111 + elif chip == ChipType.AMIGA: + n['clockSel'] = flag & 1 + n['chipType'] = (flag >> 1) & 1 + n['bypassLimits'] = bool((flag >> 2) & 1) + n['stereoSep'] = (flag >> 8) & 0b1111111 + elif chip == ChipType.YM2151: + n['clockSel'] = flag & 0b11111111 + elif chip in [ChipType.YM2612, ChipType.YM2612_EX, ChipType.YM2612_PLUS, + ChipType.YM2612_PLUS_EX]: + n['clockSel'] = flag & 2147483647 # bits 0-30 + n['ladderEffect'] = bool((flag >> 31) & 1) + elif chip == ChipType.TIA: + n['clockSel'] = flag & 1 + n['mixingType'] = (flag >> 1) & 0b11 + elif chip == ChipType.VIC20: + n['clockSel'] = flag & 1 + elif chip == ChipType.SNES: + n['volScaleL'] = flag & 0b1111111 + n['volScaleR'] = (flag >> 8) & 0b1111111 + elif chip in [ChipType.OPLL, ChipType.OPLL_DRUMS]: + n['clockSel'] = flag & 0b1111 + n['patchSet'] = flag >> 4 # safe + elif chip == ChipType.N163: + n['clockSel'] = flag & 0b1111 + n['channels'] = (flag >> 4) & 0b111 + n['multiplex'] = bool((flag >> 7) & 1) + elif chip in [ChipType.OPN, ChipType.YM2203_EX]: + n['clockSel'] = flag & 0b11111 + n['prescale'] = (flag >> 5) & 0b11 + elif chip in [ChipType.OPL, ChipType.OPL_DRUMS, ChipType.OPL2, ChipType.OPL2_DRUMS, + ChipType.Y8950, ChipType.Y8950_DRUMS]: + n['clockSel'] = flag & 0b11111111 + elif chip in [ChipType.OPL3, ChipType.OPL3_DRUMS]: + n['clockSel'] = flag & 0b11111111 + elif chip == ChipType.PC_SPEAKER: + n['speakerType'] = flag & 0b11 + elif chip == ChipType.RF5C68: + n['clockSel'] = flag & 0b1111 + n['chipType'] = flag >> 4 # safe + elif chip in [ChipType.SAA1099, ChipType.OPZ]: + n['clockSel'] = flag & 0b11 + elif chip == ChipType.AY8930: + n['clockSel'] = flag & 0b1111 + n['stereo'] = bool((flag >> 6) & 1) + n['halfClock'] = bool((flag >> 7) & 1) + n['stereoSep'] = (flag >> 8) & 0b11111111 + elif chip == ChipType.VRC7: + n['clockSel'] = flag & 0b11 + elif chip == ChipType.ZX_BEEPER: + n['clockSel'] = flag & 1 + elif chip in [ChipType.SCC, ChipType.SCC_PLUS]: + n['clockSel'] = flag & 0b11 + elif chip == ChipType.MSM6295: + n['clockSel'] = flag & 0b1111111 + n['rateSel'] = bool((flag >> 7) & 1) + elif chip == ChipType.MSM6258: + n['clockSel'] = flag & 0b11 + elif chip in [ChipType.OPL4, ChipType.OPL4_DRUMS]: + n['clockSel'] = flag & 0b11111111 + elif chip == ChipType.SETA: + n['clockSel'] = flag & 0b1111 + n['stereo'] = bool((flag >> 4) & 1) + elif chip == ChipType.ES5506: + n['channels'] = flag & 0b11111 + elif chip == ChipType.TSU: + n['clockSel'] = flag & 1 + n['echo'] = bool((flag >> 2) & 1) + n['swapEcho'] = bool((flag >> 3) & 1) + n['sampleMemSize'] = (flag >> 4) & 1 + n['pdm'] = bool((flag >> 5) & 1) + n['echoDelay'] = (flag >> 8) & 0b111111 + n['echoFeedback'] = (flag >> 16) & 0b1111 + n['echoResolution'] = (flag >> 20) & 0b1111 + n['echoVol'] = (flag >> 24) & 0b11111111 + elif chip == ChipType.YMZ280B: + n['clockSel'] = flag & 0b11111111 + elif chip == ChipType.PCM_DAC: + n['rate'] = (flag & 0b1111111111111111) + 1 + n['outDepth'] = (flag >> 16) & 0b1111 + n['stereo'] = bool((flag >> 20) & 1) + elif chip == ChipType.QSOUND: + n['echoDelay'] = flag & 0b1111111111111 + n['echoFeedback'] = (flag >> 16) & 0b11111111 + return n + + def __read_header(self, stream: BinaryIO) -> None: + # assuming we passed the magic number check + self.meta.version = read_short(stream) + stream.read(2) # RESERVED + self.__song_info_ptr = read_int(stream) + stream.read(8) # RESERVED + + def __read_info(self, stream: BinaryIO) -> None: + stream.seek(self.__song_info_ptr) + if stream.read(4) != b'INFO': + raise ValueError('No "INFO" magic') + + if self.meta.version < 100: # don't read size prior to 0.6pre1 + stream.read(4) + info_blk = stream + else: + blk_size = read_int(stream) + info_blk = BytesIO(stream.read(blk_size)) + + # info of first subsong + self.subsongs[0].timing.timebase = (read_byte(info_blk) + 1) + self.subsongs[0].timing.speed = ( + read_byte(info_blk), + read_byte(info_blk) + ) + self.subsongs[0].timing.arp_speed = read_byte(info_blk) + self.subsongs[0].timing.clock_speed = read_float(info_blk) + self.subsongs[0].pattern_length = read_short(info_blk) + len_orders = read_short(info_blk) + self.subsongs[0].timing.highlight = ( + read_byte(info_blk), + read_byte(info_blk) + ) + + # global + num_insts = read_short(info_blk) + num_waves = read_short(info_blk) + num_samples = read_short(info_blk) + num_patterns = read_int(info_blk) + + # fetch chip list + for chip_id in info_blk.read(MAX_CHIPS): + if chip_id == 0: + break # seek position is after chips here + self.chips.list.append( + ChipInfo(ChipType(chip_id)) # type: ignore + ) + + # fetch volume + for i in range(MAX_CHIPS): + vol = read_byte(info_blk, True) / 64.0 + if i >= len(self.chips.list): # cut here + continue + self.chips.list[i].volume = vol + + for i in range(MAX_CHIPS): + pan = read_byte(info_blk, True) / 128.0 + if i >= len(self.chips.list): # cut here + continue + self.chips.list[i].panning = pan + + if self.meta.version >= 119: + self.__chip_flag_ptr: List[int] = [ + read_int(info_blk) for _ in range(MAX_CHIPS) + ] + else: + for i in range(MAX_CHIPS): + flag = read_int(info_blk) + if i < len(self.chips.list): + self.chips.list[i].flags.update( + self.__convert_old_chip_flags(self.chips.list[i].type, flag) + ) + + self.meta.name = read_str(info_blk) + self.meta.author = read_str(info_blk) + self.meta.tuning = read_float(info_blk) + + # Compat flags, part I + self.__read_compat_flags(info_blk, 1) + + self.__instrument_ptr = [ + read_int(info_blk) for _ in range(num_insts) + ] + + self.__wavetable_ptr = [ + read_int(info_blk) for _ in range(num_waves) + ] + + self.__sample_ptr = [ + read_int(info_blk) for _ in range(num_samples) + ] + + self.__pattern_ptr = [ + read_int(info_blk) for _ in range(num_patterns) + ] + + num_channels = self.get_num_channels() + + for channel in range(self.get_num_channels()): + self.subsongs[0].order[channel] = [ + read_byte(info_blk) for _ in range(len_orders) + ] + + self.subsongs[0].effect_columns = [ + read_byte(info_blk) for _ in range(num_channels) + ] + + # set up channels display info + self.subsongs[0].channel_display = [ + ChannelDisplayInfo() for _ in range(num_channels) + ] + + for i in range(num_channels): + self.subsongs[0].channel_display[i].shown = bool(read_byte(info_blk)) + + for i in range(num_channels): + self.subsongs[0].channel_display[i].collapsed = bool(read_byte(info_blk)) + + for i in range(num_channels): + self.subsongs[0].channel_display[i].name = read_str(info_blk) + + for i in range(num_channels): + self.subsongs[0].channel_display[i].abbreviation = read_str(info_blk) + + self.meta.comment = read_str(info_blk) + + # Master volume + if self.meta.version >= 59: + self.chips.master_volume = read_float(info_blk) + + # Compat flags, part II + if self.meta.version >= 70: + self.__read_compat_flags(info_blk, 2) + if self.meta.version >= 96: + self.subsongs[0].timing.virtual_tempo = ( + read_short(info_blk), read_short(info_blk) + ) + else: + info_blk.read(4) # reserved in self.meta.version < 96 + + # Subsongs + if self.meta.version >= 95: + self.subsongs[0].name = read_str(info_blk) + self.subsongs[0].comment = read_str(info_blk) + num_extra_subsongs = read_byte(info_blk) + info_blk.read(3) # reserved + self.__subsong_ptr = [ + read_int(info_blk) for _ in range(num_extra_subsongs) + ] + + # Extra metadata + if self.meta.version >= 103: + self.meta.sys_name = read_str(info_blk) + self.meta.album = read_str(info_blk) + # TODO: need to take encoding into account + self.meta.name_jp = read_str(info_blk) + self.meta.author_jp = read_str(info_blk) + self.meta.sys_name_jp = read_str(info_blk) + self.meta.album_jp = read_str(info_blk) + + # New chip mixer and patchbay + if self.meta.version >= 135: + for i in range(len(self.chips.list)): + # new chip volume/panning format takes precedence over the legacy one + # if you save a .fur with this, legacy and new volume/panning formats + # have the same value. different values shouldn't be possible + self.chips.list[i].volume = read_float(info_blk) + self.chips.list[i].panning = read_float(info_blk) + self.chips.list[i].surround = read_float(info_blk) + num_patchbay_connections = read_int(info_blk) + for _ in range(num_patchbay_connections): + src = read_short(info_blk) + dst = read_short(info_blk) + self.patchbay.append( + PatchBay( + dest=InputPatchBayEntry( + set=InputPortSet(src >> 4), + port=src & 0b1111 + ), + source=OutputPatchBayEntry( + set=OutputPortSet(dst >> 4), + port=dst & 0b1111 + ) + ) + ) + + if self.meta.version >= 136: + self.compat_flags.auto_patchbay = bool(read_byte(info_blk)) + + # Compat flags, part III + if self.meta.version >= 138: + self.__read_compat_flags(info_blk, 3) + + # Speed patterns and grooves + if self.meta.version >= 139: + # speed pattern + len_speed_pattern = read_byte(info_blk) + if (len_speed_pattern < 0) or (len_speed_pattern > 16): + raise ValueError('Invalid speed pattern length value') + self.subsongs[0].speed_pattern = [ + read_byte(info_blk) for _ in range(len_speed_pattern) + ] + info_blk.read(16 - len_speed_pattern) # skip that many bytes, because it's always 0x06 + + # groove + len_groove_list = read_byte(info_blk) + for _ in range(len_groove_list): + len_groove = read_byte(info_blk) + self.subsongs[0].grooves.append([ + read_byte(info_blk) for _ in range(len_groove) + ]) + info_blk.read(16 - len_groove) # TODO: i assume the same as above. i hope i'm right + + def __read_instruments(self, stream: BinaryIO) -> None: + for i in self.__instrument_ptr: + if i == 0: + break + stream.seek(i) + new_ins = FurnaceInstrument() + if self.meta.version < 127: # i trust this not to screw up + new_ins.load_from_stream(stream, _FurInsImportType.FORMAT_0_EMBED) + else: + new_ins.load_from_stream(stream, _FurInsImportType.FORMAT_1_EMBED) + self.instruments.append(new_ins) + + def __read_wavetables(self, stream: BinaryIO) -> None: + for i in self.__wavetable_ptr: + if i == 0: + break + stream.seek(i) + new_wt = FurnaceWavetable() + new_wt.load_from_stream(stream, _FurWavetableImportType.EMBED) + self.wavetables.append(new_wt) + + def __read_samples(self, stream: BinaryIO) -> None: + for i in self.__sample_ptr: + if i == 0: + break + stream.seek(i) + new_wt = FurnaceSample() + new_wt.load_from_stream(stream) + self.samples.append(new_wt) + + def __read_patterns(self, stream: BinaryIO) -> None: + for i in self.__pattern_ptr: + if i == 0: + break + stream.seek(i) + + # Old pattern + if self.meta.version < 157: + if stream.read(4) != b'PATR': + raise ValueError('No "PATR" magic') + sz = read_int(stream) + if sz == 0: + patr_blk = stream + else: + patr_blk = BytesIO(stream.read(sz)) + + new_patr = FurnacePattern() + new_patr.channel = read_short(patr_blk) + new_patr.index = read_short(patr_blk) + new_patr.subsong = read_short(patr_blk) + if self.meta.version < 95: + assert new_patr.subsong == 0 + read_short(patr_blk) # reserved + + num_rows = self.subsongs[new_patr.subsong].pattern_length + + for _ in range(num_rows): + row = FurnaceRow( + note=Note(read_short(patr_blk)), + octave=read_short(patr_blk), + instrument=read_short(patr_blk), + volume=read_short(patr_blk) + ) + row.octave += (1 if row.note == Note.C_ else 0) + effect_columns = self.subsongs[new_patr.subsong].effect_columns[new_patr.channel] + row.effects = [ + (read_short(patr_blk), read_short(patr_blk)) for _ in range(effect_columns) + ] + new_patr.data.append(row) + + if self.meta.version >= 51: + new_patr.name = read_str(patr_blk) + + # New pattern + else: + if stream.read(4) != b'PATN': + raise ValueError('No "PATN" magic') + sz = read_int(stream) + if sz == 0: + patr_blk = stream + else: + patr_blk = BytesIO(stream.read(sz)) + + new_patr = FurnacePattern() + new_patr.subsong = read_byte(patr_blk) + new_patr.channel = read_byte(patr_blk) + new_patr.index = read_short(patr_blk) + new_patr.name = read_str(patr_blk) + + num_rows = self.subsongs[new_patr.subsong].pattern_length + effect_columns = self.subsongs[new_patr.subsong].effect_columns[new_patr.channel] + + empty_row = lambda: FurnaceRow(Note.__, 0, 0xffff, 0xffff, [(0xffff,0xffff)] * effect_columns) + + row_idx = 0 + while row_idx < num_rows: + char = read_byte(patr_blk) + # end of pattern + if char == 0xff: + break + # skip N+2 rows + if char & 0x80: + skip = (char & 0x7f) + 2 + row_idx += skip + for _ in range(skip): + new_patr.data.append(empty_row()) + continue + # check if some values present + effect_present_list = [False] * 8 + effect_val_present_list = [False] * 8 + note_present = bool(char & 0x01) + ins_present = bool(char & 0x02) + volume_present = bool(char & 0x04) + effect_present_list[0] = bool(char & 0x08) + effect_val_present_list[0] = bool(char & 0x10) + effect_0_3_present = bool(char & 0x20) + effect_4_7_present = bool(char & 0x40) + if effect_0_3_present: + char = read_byte(patr_blk) + assert effect_present_list[0] == bool(char & 0x01) + assert effect_val_present_list[0] == bool(char & 0x02) + effect_present_list[1] = bool(char & 0x04) + effect_val_present_list[1] = bool(char & 0x08) + effect_present_list[2] = bool(char & 0x10) + effect_val_present_list[2] = bool(char & 0x20) + effect_present_list[3] = bool(char & 0x40) + effect_val_present_list[3] = bool(char & 0x80) + if effect_4_7_present: + char = read_byte(patr_blk) + effect_present_list[4] = bool(char & 0x01) + effect_val_present_list[4] = bool(char & 0x02) + effect_present_list[5] = bool(char & 0x04) + effect_val_present_list[5] = bool(char & 0x08) + effect_present_list[6] = bool(char & 0x10) + effect_val_present_list[6] = bool(char & 0x20) + effect_present_list[7] = bool(char & 0x40) + effect_val_present_list[7] = bool(char & 0x80) + + # actually read present values + note, octave = Note(0), 0 + if note_present: + raw_note = read_byte(patr_blk) + if raw_note == 180: + note = Note.OFF + elif raw_note == 181: + note = Note.OFF_REL + elif raw_note == 182: + note = Note.REL + else: + note = raw_note % 12 + note = 12 if note == 0 else note + note = Note(note) + octave = -5 + raw_note // 12 + + ins, volume = 0xffff, 0xffff + if ins_present: + ins = read_byte(patr_blk) + if volume_present: + volume = read_byte(patr_blk) + + row = FurnaceRow( + note=note, + octave=octave, + instrument=ins, + volume=volume + ) + + row.effects = [(0xffff,0xffff)] * effect_columns + for i, fx_presents in enumerate(zip(effect_present_list, effect_val_present_list)): + if i >= effect_columns: + break + fx_cmd, fx_val = 0xffff, 0xffff + if fx_presents[0]: + fx_cmd = read_byte(patr_blk) + if fx_presents[1]: + fx_val = read_byte(patr_blk) + row.effects[i] = (fx_cmd, fx_val) + + new_patr.data.append(row) + row_idx += 1 + + # fill the rest of the pattern with EMPTY + while row_idx < num_rows: + new_patr.data.append(empty_row()) + row_idx += 1 + + self.patterns.append(new_patr) + + def __read_subsongs(self, stream: BinaryIO) -> None: + for i in self.__subsong_ptr: + if i == 0: + break + stream.seek(i) + if stream.read(4) != b'SONG': + raise ValueError('No "SONG" magic') + subsong_blk = BytesIO(stream.read(read_int(stream))) + new_subsong = SubSong() + new_subsong.order.clear() + new_subsong.speed_pattern.clear() + + new_subsong.timing.timebase = read_byte(subsong_blk) + new_subsong.timing.speed = ( + read_byte(subsong_blk), read_byte(subsong_blk) + ) + new_subsong.timing.arp_speed = read_byte(subsong_blk) + new_subsong.timing.clock_speed = read_float(subsong_blk) + new_subsong.pattern_length = read_short(subsong_blk) + new_subsong_len_orders = read_short(subsong_blk) + new_subsong.timing.highlight = ( + read_byte(subsong_blk), read_byte(subsong_blk) + ) + new_subsong.timing.virtual_tempo = ( + read_short(subsong_blk), read_short(subsong_blk) + ) + new_subsong.name = read_str(subsong_blk) + new_subsong.comment = read_str(subsong_blk) + + num_channels = self.get_num_channels() + + for channel in range(self.get_num_channels()): + new_subsong.order[channel] = [ + read_byte(subsong_blk) for _ in range(new_subsong_len_orders) + ] + + new_subsong.effect_columns = [ + read_byte(subsong_blk) for _ in range(num_channels) + ] + + # set up channels display info + new_subsong.channel_display = [ + ChannelDisplayInfo() for _ in range(num_channels) + ] + + for i in range(num_channels): + new_subsong.channel_display[i].shown = bool(read_byte(subsong_blk)) + + for i in range(num_channels): + new_subsong.channel_display[i].collapsed = bool(read_byte(subsong_blk)) + + for i in range(num_channels): + new_subsong.channel_display[i].name = read_str(subsong_blk) + + for i in range(num_channels): + new_subsong.channel_display[i].abbreviation = read_str(subsong_blk) + + # Speed patterns and grooves + if self.meta.version >= 139: + # speed pattern + len_speed_pattern = read_byte(subsong_blk) + if (len_speed_pattern < 0) or (len_speed_pattern > 16): + raise ValueError('Invalid speed pattern length value') + new_subsong.speed_pattern = [ + read_byte(subsong_blk) for _ in range(len_speed_pattern) + ] + + self.subsongs.append(new_subsong) + + def __str__(self) -> str: + return '' % ( + self.meta.version, self.meta.name, self.meta.author + ) diff --git a/loader/samples/minexample/furC64/chipchune/furnace/sample.py b/loader/samples/minexample/furC64/chipchune/furnace/sample.py new file mode 100644 index 0000000..1139050 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/furnace/sample.py @@ -0,0 +1,47 @@ +from io import BytesIO +from typing import Optional, Union, BinaryIO, List + +from chipchune._util import read_short, read_int, read_str +from .data_types import SampleMeta +from .enums import _FurSampleType + +FILE_MAGIC_STR = b'SMP2' + + +class FurnaceSample: + def __init__(self) -> None: + self.meta: SampleMeta = SampleMeta() + """ + Sample metadata. + """ + self.data: bytearray = b'' + """ + Sample data. + """ + + def load_from_stream(self, stream: BinaryIO) -> None: + """ + Load a sample from an **uncompressed** stream. + + :param stream: File-like object containing the uncompressed wavetable. + """ + if stream.read(len(FILE_MAGIC_STR)) != FILE_MAGIC_STR: + raise ValueError('Bad magic value for a wavetable file') + blk_size = read_int(stream) + if blk_size > 0: + smp_data = BytesIO(stream.read(blk_size)) + else: + smp_data = stream + + self.meta.name = read_str(smp_data) + self.meta.length = read_int(smp_data) + read_int(smp_data) # compatablity rate + self.meta.sample_rate = read_int(smp_data) + self.meta.depth = int(smp_data.read(1)[0]) + smp_data.read(1) # loop direction + smp_data.read(1) # flags + smp_data.read(1) # flags 2 + self.meta.loop_start = read_int(smp_data) + self.meta.loop_end = read_int(smp_data) + smp_data.read(16) # sample presence bitfields + self.data = smp_data.read(self.meta.length) diff --git a/loader/samples/minexample/furC64/chipchune/furnace/wavetable.py b/loader/samples/minexample/furC64/chipchune/furnace/wavetable.py new file mode 100644 index 0000000..cec13cb --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/furnace/wavetable.py @@ -0,0 +1,101 @@ +from io import BytesIO +from typing import Optional, Union, BinaryIO, List + +from chipchune._util import read_short, read_int, read_str +from .data_types import WavetableMeta +from .enums import _FurWavetableImportType + +FILE_MAGIC_STR = b'-Furnace waveta-' +EMBED_MAGIC_STR = b'WAVE' + + +class FurnaceWavetable: + def __init__(self, file_name: Optional[str] = None) -> None: + """ + Creates or opens a new Furnace wavetable as a Python object. + + :param file_name: (Optional) + If specified, then it will parse a file as a FurnaceWavetable. If file name (str) is + given, it will load that file. + + Defaults to None. + """ + self.file_name: Optional[str] = None + """ + Original file name, if the object was initialized with one. + """ + self.meta: WavetableMeta = WavetableMeta() + """ + Wavetable metadata. + """ + self.data: List[int] = [] + """ + Wavetable data. + """ + + if isinstance(file_name, str): + self.load_from_file(file_name) + + def load_from_file(self, file_name: Optional[str] = None) -> None: + if isinstance(file_name, str): + self.file_name = file_name + if self.file_name is None: + raise RuntimeError('No file name set, either set self.file_name or pass file_name to the function') + + # since we're loading from an uncompressed file, we can just check the file magic number + with open(self.file_name, 'rb') as f: + detect_magic = f.peek(len(FILE_MAGIC_STR))[:len(FILE_MAGIC_STR)] + if detect_magic == FILE_MAGIC_STR: + return self.load_from_stream(f, _FurWavetableImportType.FILE) + else: # uncompressed for sure + raise ValueError('No recognized file type magic') + + def load_from_bytes(self, data: bytes, import_as: Union[int, _FurWavetableImportType]) -> None: + """ + Load a wavetable from a series of bytes. + + :param data: Bytes + """ + return self.load_from_stream( + BytesIO(data), + import_as + ) + + def load_from_stream(self, stream: BinaryIO, import_as: Union[int, _FurWavetableImportType]) -> None: + """ + Load a wavetable from an **uncompressed** stream. + + :param stream: File-like object containing the uncompressed wavetable. + :param import_as: int + - 0 = wavetable file + - 1 = wavetable embedded in module + """ + if import_as == _FurWavetableImportType.FILE: + if stream.read(len(FILE_MAGIC_STR)) != FILE_MAGIC_STR: + raise ValueError('Bad magic value for a wavetable file') + version = read_short(stream) + read_short(stream) # reserved + self.__load_embed(stream) + + elif import_as == _FurWavetableImportType.EMBED: + return self.__load_embed(stream) + + else: + raise ValueError('Invalid import type') + + def __load_embed(self, stream: BinaryIO) -> None: + if stream.read(len(EMBED_MAGIC_STR)) != EMBED_MAGIC_STR: + raise RuntimeError('Bad magic value for a wavetable embed') + + blk_size = read_int(stream) + if blk_size > 0: + wt_data = BytesIO(stream.read(blk_size)) + else: + wt_data = stream + + self.meta.name = read_str(wt_data) + self.meta.width = read_int(wt_data) + read_int(wt_data) # reserved + self.meta.height = read_int(wt_data) + 1 # serialized height is 1 lower than actual value + + self.data = [read_int(wt_data) for _ in range(self.meta.width)] diff --git a/loader/samples/minexample/furC64/chipchune/interchange/__init__.py b/loader/samples/minexample/furC64/chipchune/interchange/__init__.py new file mode 100644 index 0000000..ec33a22 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/interchange/__init__.py @@ -0,0 +1,7 @@ +""" +Generic format for manipulating to, from, and between tracker formats. + +- :mod:`chipchune.interchange.enums`: Various constants. +- :mod:`chipchune.interchange.furnace`: Adapters for Furnace. + +""" diff --git a/loader/samples/minexample/furC64/chipchune/interchange/enums.py b/loader/samples/minexample/furC64/chipchune/interchange/enums.py new file mode 100644 index 0000000..6d553b6 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/interchange/enums.py @@ -0,0 +1,24 @@ +import enum +from chipchune._util import EnumShowNameOnly + +class InterNote(EnumShowNameOnly): + """ + Common note interchange format. + """ + __ = enum.auto() # Signifies a blank space in tracker + C_ = enum.auto() + Cs = enum.auto() + D_ = enum.auto() + Ds = enum.auto() + E_ = enum.auto() + F_ = enum.auto() + Fs = enum.auto() + G_ = enum.auto() + Gs = enum.auto() + A_ = enum.auto() + As = enum.auto() + B_ = enum.auto() + Off = enum.auto() + OffRel = enum.auto() + Rel = enum.auto() + Echo = enum.auto() diff --git a/loader/samples/minexample/furC64/chipchune/interchange/furnace.py b/loader/samples/minexample/furC64/chipchune/interchange/furnace.py new file mode 100644 index 0000000..4f39640 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/interchange/furnace.py @@ -0,0 +1,52 @@ +from chipchune.furnace.enums import Note as FurnaceNote +from chipchune.interchange.enums import InterNote + +def furnace_note_to_internote(note: FurnaceNote) -> InterNote: + """ + Convert a Furnace note into an InterNote. + + Raises: + - Exception: If the supplied note is out of range. + """ + if note == FurnaceNote.__: return InterNote.__ + elif note == FurnaceNote.C_: return InterNote.C_ + elif note == FurnaceNote.Cs: return InterNote.Cs + elif note == FurnaceNote.D_: return InterNote.D_ + elif note == FurnaceNote.Ds: return InterNote.Ds + elif note == FurnaceNote.E_: return InterNote.E_ + elif note == FurnaceNote.F_: return InterNote.F_ + elif note == FurnaceNote.Fs: return InterNote.Fs + elif note == FurnaceNote.G_: return InterNote.G_ + elif note == FurnaceNote.Gs: return InterNote.Gs + elif note == FurnaceNote.A_: return InterNote.A_ + elif note == FurnaceNote.As: return InterNote.As + elif note == FurnaceNote.B_: return InterNote.B_ + elif note == FurnaceNote.OFF: return InterNote.Off + elif note == FurnaceNote.OFF_REL: return InterNote.OffRel + elif note == FurnaceNote.REL: return InterNote.Rel + else: + raise Exception("Invalid note value %s" % note) + +def internote_to_furnace_note(note: InterNote) -> FurnaceNote: + """ + Convert an InterNote into a Furnace note. If the equivalent + value is unable to be determined, a blank note `__` is returned. + """ + if note == InterNote.__: return FurnaceNote.__ + elif note == InterNote.C_: return FurnaceNote.C_ + elif note == InterNote.Cs: return FurnaceNote.Cs + elif note == InterNote.D_: return FurnaceNote.D_ + elif note == InterNote.Ds: return FurnaceNote.Ds + elif note == InterNote.E_: return FurnaceNote.E_ + elif note == InterNote.F_: return FurnaceNote.F_ + elif note == InterNote.Fs: return FurnaceNote.Fs + elif note == InterNote.G_: return FurnaceNote.G_ + elif note == InterNote.Gs: return FurnaceNote.Gs + elif note == InterNote.A_: return FurnaceNote.A_ + elif note == InterNote.As: return FurnaceNote.As + elif note == InterNote.B_: return FurnaceNote.B_ + elif note == InterNote.Off: return FurnaceNote.OFF + elif note == InterNote.OffRel: return FurnaceNote.OFF_REL + elif note == InterNote.Rel: return FurnaceNote.REL + else: + return FurnaceNote.__ \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/utils/__init__.py b/loader/samples/minexample/furC64/chipchune/utils/__init__.py new file mode 100644 index 0000000..88e24f3 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/utils/__init__.py @@ -0,0 +1,5 @@ +""" +Utilities for manipulating, converting, etc. tracker data. + +- :mod:`chipchune.utils.conversion`: Conversion tools. +""" \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/utils/conversion.py b/loader/samples/minexample/furC64/chipchune/utils/conversion.py new file mode 100644 index 0000000..0c6c5b1 --- /dev/null +++ b/loader/samples/minexample/furC64/chipchune/utils/conversion.py @@ -0,0 +1,94 @@ +from chipchune.furnace.module import FurnacePattern +from chipchune.interchange.enums import InterNote +from chipchune.interchange.furnace import furnace_note_to_internote +from typing import Union, List, Tuple +from dataclasses import dataclass, field + +@dataclass +class SequenceEntry: + """ + A representation of a row in note-length format. Such a format is commonly + used across different sound engines and sequenced data. + + A pattern can be turned into a list of SequenceEntries, which should be easier + to convert into a format of your choice. + """ + note: InterNote + length: int + volume: int + """ + Tracker-defined volume; although this should be -1 for undefined values. + """ + octave: int + """ + Tracker-defined octave; although this should be -1 for undefined values. + """ + instrument: int + """ + Tracker-defined instrument number; although this should be -1 for undefined values. + """ + effects: List[Tuple[int, int]] = field(default_factory=list) + """ + Tracker-defined effects list; if undefined, this should be empty. + """ + +def pattern_to_sequence(pattern: Union[FurnacePattern, None]) -> List[SequenceEntry]: + """ + Interface to convert a pattern from tracker rows to a "sequence", which is + really a list of SequenceEntries. + + :param pattern: + A pattern object. Supported types at the moment: `FurnacePattern`. + Anything outside of the supported types will throw a `TypeError`. + """ + if isinstance(pattern, FurnacePattern): + return furnace_pattern_to_sequence(pattern) + else: + raise TypeError("Invalid pattern type; must be one of: FurnacePattern") + +def furnace_pattern_to_sequence(pattern: FurnacePattern) -> List[SequenceEntry]: + converted: List[SequenceEntry] = [] + last_volume = -1 + for i in pattern.data: + note = furnace_note_to_internote(i.note) + effects = i.effects + volume = i.volume + instrument = i.instrument + + if effects == [(65535, 65535)]: + effects = [] + + if volume == 65535: + volume = last_volume + else: + last_volume = volume + + if instrument == 65535: + instrument = -1 + + if note == InterNote.__: + if len(converted) == 0: + converted.append( + SequenceEntry( + note=InterNote.__, + length=1, + volume=volume, + octave=i.octave, + instrument=instrument, + effects=effects, + ) + ) + else: + converted[-1].length += 1 + else: + converted.append( + SequenceEntry( + note=note, + length=1, + volume=volume, + octave=i.octave, + instrument=instrument, + effects=effects, + ) + ) + return converted diff --git a/loader/samples/minexample/furC64/convert.bat b/loader/samples/minexample/furC64/convert.bat new file mode 100644 index 0000000..5044a81 --- /dev/null +++ b/loader/samples/minexample/furC64/convert.bat @@ -0,0 +1,14 @@ +@echo off +if [%1]==[] goto usage +python3 convert_to_asm.py %1 +echo converted .fur file to .asm! +cd asm +cl65 -d -vm -l furC64.lst -g -u __EXEHDR__ -t c64 -C .\c64-asm.cfg -m furC64.map -Ln furC64.lbl -o furC64-test.prg furC64.asm +@echo compiled .prg file at asm/furC64-test.prg +cd .. +goto :eof +:usage +@echo No arguments supplied +@echo Make sure to run this command with an argument +@echo example: convert.bat test_file.fur +exit /B 1 diff --git a/loader/samples/minexample/furC64/convert.sh b/loader/samples/minexample/furC64/convert.sh new file mode 100755 index 0000000..ffcc96b --- /dev/null +++ b/loader/samples/minexample/furC64/convert.sh @@ -0,0 +1,15 @@ +#!/bin/bash +if [ $# -eq 0 ] +then + echo "No arguments supplied" + echo "Make sure to run this command with an argument" + echo "example: convert.sh test_file.fur" +else +python3 convert_to_asm.py $1 +echo "converted .fur file to .asm!" +cd asm +cl65 -d -vm -l furC64.lst -g -u __EXEHDR__ -t c64 -C ./exe.cfg -m furC64.map -Ln furC64.lbl -o furC64-test.prg furC64.asm +cl65 -d -C ./bin.cfg -o song.bin furC64.asm +echo "compiled .prg file at asm/furC64-test.prg" +cd .. +fi diff --git a/loader/samples/minexample/furC64/convert_to_asm.py b/loader/samples/minexample/furC64/convert_to_asm.py new file mode 100644 index 0000000..14ac9aa --- /dev/null +++ b/loader/samples/minexample/furC64/convert_to_asm.py @@ -0,0 +1,780 @@ +from chipchune.furnace.module import FurnaceModule +from chipchune.furnace.data_types import InsFeatureMacro, InsFeatureC64, InsFeatureAmiga +from chipchune.furnace.enums import MacroCode, MacroItem, MacroType +from chipchune.furnace.enums import InstrumentType +import sys + +subsong = 0 +note_transpose = 0 +dups = {} + +print(sys.argv) +module = FurnaceModule(sys.argv[1]) +chnum = module.get_num_channels() + +speed_type = len(module.subsongs[subsong].speed_pattern) + +notes = ["C_","Cs","D_","Ds","E_","F_","Fs","G_","Gs","A_","As","B_"] + +def comp(pat): + i = 0 + o = [] + n = 0 + while i < len(pat): + j = i + k = 0 + if pat[i] >= 0x40 and pat[i] < 128: i += 1 + elif pat[i] == 0xFB: i += 2 + elif pat[i] == 0xFC: i += 2 + elif pat[i] == 0xE0: i += 2 + elif pat[i] == 0xE1: i += 2 + elif pat[i] == 0xE2: i += 2 + elif pat[i] == 0xE3: i += 2 + elif pat[i] == 0xE4: i += 2 + elif pat[i] == 0xE5: i += 3 + elif pat[i] == 0xE6: i += 2 + elif pat[i] == 0xE7: i += 2 + elif pat[i] == 0xE8: i += 2 + elif pat[i] == 0xE9: i += 3 + elif pat[i] == 0xEA: i += 3 + elif pat[i] == 0xEB: i += 2 + elif pat[i] == 0xEC: i += 2 + elif pat[i] == 0xED: i += 2 + elif pat[i] == 0xEE: i += 2 + elif pat[i] == 0xEF: i += 1 + elif pat[i] == 0xF0: i += 1 + elif pat[i] == 0xF1: i += 2 + elif pat[i] == 0xFF: i += 2 + elif pat[i] == 0xFD: + i += 1 + n = 2 + elif pat[i] == 0xFE: + i += 1 + n = 2 + elif pat[i] >= 128: + i += 1 + n = 2 + else: + k = 1 + if n == 0: + o.append(pat[i]) + elif pat[i] > 1: + o.append(pat[i]-1) + #print(i,pat[i]) + i += 1 + n = max(n-1,0) + if k == 0: + o.extend(pat[j:i]) + #print(pat,"\n",o,"\n") + return o + +def conv_pattern(pattern): + out = [0] + oldtemp = [0,0] + r = 0 + bitind = 0 + oldins = -1 + for row in pattern.data: + has03xx = 0 + for l in row.effects: + k = list(l) + if k[0] == 0x03 and k[1] > 0: + has03xx = 1 + break + + temp = [] + notnote = 0 + new_byte = 0 + if row.instrument != 65535 and oldins != row.instrument: + new_byte = 1 + if row.instrument < 0x40: + temp.append(row.instrument+0x40) + else: + temp.append(0xFB) + temp.append(row.instrument) + oldins = row.instrument + if row.volume != 65535: + new_byte = 1 + temp.append(0xFC) + temp.append(row.volume) + + hasEffect = [-1,-1] + has0Dxx = -1 + for l in row.effects: + k = list(l) + if k[1] == 65535: + k[1] = 0 + + if k[0] == 0xD: + new_byte = 1 + has0Dxx = k[1] + continue + if k[0] == 0x0B: + new_byte = 1 + temp.extend([0xED, k[1]]) + has0Dxx = 0 + continue + if (k[0] == 0x09 or k[0] == 0x0F) and (speed_type == 1): + new_byte = 1 + temp.extend([0xE1, k[1]]) + temp.extend([0xE0, k[1]]) + continue + if k[0] == 0x0F and (speed_type == 2): + new_byte = 1 + temp.extend([0xE1, k[1]]) + continue + if k[0] == 0x09 and (speed_type == 2): + new_byte = 1 + temp.extend([0xE0, k[1]]) + continue + if k[0] == 0x00: + new_byte = 1 + temp.extend([0xE2, k[1]]) + continue + if k[0] == 0x01: + new_byte = 1 + temp.extend([0xE3, k[1]]) + continue + if k[0] == 0x02: + new_byte = 1 + temp.extend([0xE4, k[1]]) + continue + if k[0] == 0x03 and k[1] == 0: + new_byte = 1 + temp.extend([0xE4, 0]) + continue + if k[0] == 0x03 and k[1] > 0: + new_byte = 1 + temp.extend([0xE5, k[1], max(min(notes.index(str(row.note))+(row.octave*12)+note_transpose,95),0)]) + continue + if k[0] == 0x04: + new_byte = 1 + temp.extend([0xE6, k[1]]) + continue + if k[0] == 0x1B: + new_byte = 1 + temp.extend([0xE7, k[1]]) + continue + if k[0] == 0x1C: + new_byte = 1 + temp.extend([0xE8, k[1]]) + continue + if k[0] == 0xE1: + new_byte = 1 + temp.extend([0xE9, k[1]>>4, k[1]&15]) + continue + if k[0] == 0xE2: + new_byte = 1 + temp.extend([0xEA, k[1]>>4, k[1]&15]) + continue + if k[0] == 0xE5: + new_byte = 1 + temp.extend([0xEB, k[1]]) + continue + if k[0] == 0xEC: + new_byte = 1 + temp.extend([0xEC, k[1]]) + continue + if (k[0]>>4) == 4: + new_byte = 1 + temp.extend([0xEE, (k[1]|(k[0]&0xf)<<8)>>3]) + continue + if k[0] == 0xEA: + new_byte = 1 + if k[1] == 0: + temp.extend([0xEF]) + else: + temp.extend([0xF0]) + continue + if k[0] == 0x1A: + new_byte = 1 + if k[1] > 0: + temp.extend([0xF1, 0x00]) + else: + temp.extend([0xF1, 0xFF]) + continue + if str(row.note) == "OFF_REL": + notnote = 1 + new_byte = 1 + temp.append(0xFD) + elif str(row.note) == "REL": + notnote = 1 + new_byte = 1 + temp.append(0xFD) + elif str(row.note) == "OFF": + notnote = 1 + new_byte = 1 + temp.append(0xFE) + elif str(row.note) == "__" or (has03xx == 1): + if has03xx == 0: + notnote = 1 + #temp.append(0x80) + else: + new_byte = 1 + temp.append(max(min(notes.index(str(row.note))+(row.octave*12)+note_transpose,95),0)+0x80) + + if new_byte == 1: + temp.append(0) + out.extend(temp) + durpass = False + if out[-1] >= 63: + out.append(0) + if has0Dxx > -1: + out[-1] += 1 + if out[0] == 0: out = out[1:] + out.extend([0xFF, has0Dxx]) + return out + out[-1] += 1 + r += 1 + out.extend([0xFF, 0]) + if out[0] == 0: out = out[1:] + return out + +f = open("asm/song.asm","w") + +relW = [] +relA = [] +relD = [] +relC = [] + +f.write("ticks_init:") +f.write(".byte ") +if speed_type == 1: + f.write(str(module.subsongs[subsong].speed_pattern[0])+", ") + f.write(str(module.subsongs[subsong].speed_pattern[0])+"\n") +elif speed_type == 2: + f.write(str(module.subsongs[subsong].speed_pattern[0])+", ") + f.write(str(module.subsongs[subsong].speed_pattern[1])+"\n") + +f.write("insFL:\n") +f.write(".lobytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"F") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") +f.write("insFH:\n") +f.write(".hibytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"F") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") + +f.write("insAL:\n") +f.write(".lobytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"A") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") +f.write("insAH:\n") +f.write(".hibytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"A") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") + +f.write("insDL:\n") +f.write(".lobytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"D") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") +f.write("insDH:\n") +f.write(".hibytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"D") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") + +f.write("insWL:\n") +f.write(".lobytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"W") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") +f.write("insWH:\n") +f.write(".hibytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"W") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") + +f.write("insCL:\n") +f.write(".lobytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"C") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") +f.write("insCH:\n") +f.write(".hibytes ") +for i in range(len(module.instruments)): + f.write("ins"+str(i)+"C") + if i == len(module.instruments)-1: + f.write("\n") + else: + f.write(", ") + +for i in range(len(module.instruments)): + features = module.instruments[i].features + a = filter( + lambda x: ( + type(x) == InsFeatureMacro + ), features + ) + macros = [] + for j in a: + macros = j.macros + hasWaveMacro = 0 + hasCutMacro = 0 + for j in macros: + kind = j.kind + if kind == MacroCode.WAVE: + hasWaveMacro = 1 + continue + if kind == MacroCode.ALG: + hasCutMacro = 1 + continue + + hasAbsFilter = False + hasAbsDuty = False + written_ins = False + + a = filter( + lambda x: ( + type(x) == InsFeatureMacro + ), features + ) + macros = [] + for j in a: + macros = j.macros + for j in macros: + kind = j.kind + if kind == MacroCode.DUTY and j.type == MacroType.LFO: + hasAbsDuty = True + + a = filter( + lambda x: ( + type(x) == InsFeatureC64 + ), features + ) + for j in a: + wave = j.tri_on + wave |= j.saw_on<<1 + wave |= j.pulse_on<<2 + wave |= j.noise_on<<3 + wave <<= 4 + wave |= j.ring_mod<<2 + wave |= j.osc_sync<<1 + f.write("ins"+str(i)+"F:\n") + f.write(".byte ") + f.write(str(wave)+", ") + ad = (j.envelope.a<<4)|j.envelope.d + sr = (j.envelope.s<<4)|j.envelope.r + f.write(str(ad)+", ") + f.write(str(sr)+", ") + f.write(str(j.duty&0xff)+", ") + f.write(str(j.duty>>8)+", ") + flags = 0 + if j.duty_is_abs: + flags |= 1 + if hasWaveMacro: + flags |= 2 + if j.to_filter: + flags |= 4 + if j.init_filter: + flags |= 8 + if j.filter_is_abs: + flags |= 16 + if hasCutMacro: + flags |= 32 + if not j.no_test: + flags |= 64 + f.write(str(flags)+", ") + fil = 0 + fil = j.lp<<4 + fil |= j.bp<<5 + fil |= j.hp<<6 + fil |= j.ch3_off<<7 + f.write(str(j.res<<4)+", ") + f.write(str(fil)+", ") + f.write(str(j.cut&0xff)+", ") + f.write(str((j.cut>>8)&15)+"\n") + f.write("\n") + written_ins = True + hasAbsDuty |= j.duty_is_abs + hasAbsFilter = j.filter_is_abs + if written_ins == False: + f.write("ins"+str(i)+"F:\n") + f.write(".byte 32, 8, 0, 255, 7, 0\n") + a = filter( + lambda x: ( + type(x) == InsFeatureMacro + ), features + ) + arp = [128,0xFF,0xFF] + duty = [0xFF,0xFF] + wave = [0xFF,0xFF] + cutoff = [0xFF,0xFF] + macros = [] + for j in a: + macros = j.macros + hasRelTotal = [0,0,0,0] + for j in macros: + kind = j.kind + if kind == MacroCode.ARP: + s = j.speed + arp = [] + loop = 0xff + hasRel = 0 + oldlen = 0 + if j.data[-1] == MacroItem.LOOP: + arr = [MacroItem.LOOP, j.data[-2]] + j.data = j.data[:-2] + arr + for k in j.data: + if k == MacroItem.LOOP: + loop = oldlen + elif k == MacroItem.RELEASE: + arp.append(0xFF) + arp.append(loop) + relA.append(len(arp)) + oldlen = max(len(arp),0) + hasRel = 1 + elif (k>>30) > 0: + arp.append(0xFE) + k = abs(k^(1<<30)) + k = max(min(k,95),0) + arp.append(k%120) + oldlen = max(len(arp),0) + else: + if k < 0: + arp.append((k%120)-120+128) + else: + arp.append((k%120)+128) + oldlen = max(len(arp),0) + if hasRel == 0: + relA.append(len(arp)) + hasRelTotal[1] = 1 + len_temp = len(arp) + arp.append(0xFF) + arp.append(loop if loop!=len_temp else 0xff) + if kind == MacroCode.DUTY and j.type == MacroType.LFO: + while type(j.data[0]) is not int: + j.data = j.data[1:] + + s = j.speed + duty = [] + hasRel = 0 + lfo = j.data[13] + while lfo <= 1023: + lfo += j.data[11] + if lfo > 1023: break + k = lfo + if k & 512: + k = 1023-lfo + k >>= 1 + k = j.data[0]+((k+(j.data[1]-j.data[0])*k)>>8) + if (k&0xff) == 255: + duty.append(254) + else: + duty.append(k&0xff) + duty.append(k>>8) + if hasRel == 0: + relD.append(0) + hasRelTotal[2] = 1 + duty.append(0xFF) + duty.append(0) + elif kind == MacroCode.DUTY: + s = j.speed + duty = [] + loop = 0xff + loop2 = 0 + hasRel = 0 + for k in j.data: + if k == MacroItem.LOOP: + loop = loop2 + elif k == MacroItem.RELEASE: + duty.append(0xFF) + duty.append(loop) + relD.append(len(duty)) + hasRel = 1 + else: + loop2 = len(duty)+2 + if hasAbsDuty: + if (k&0xff) == 255: + duty.append(254) + else: + duty.append(k&0xff) + duty.append(k>>8) + else: + k = 32768-(k*4) #4) + duty.append(k&0xff) + duty.append(k>>8) + if hasRel == 0: + relD.append(len(duty)) + hasRelTotal[2] = 1 + len_temp = len(duty) + duty.append(0xFF) + duty.append(loop if loop!=len_temp else 0xff) + if kind == MacroCode.ALG and j.type == MacroType.LFO: + while type(j.data[0]) is not int: + j.data = j.data[1:] + + s = j.speed + cutoff = [] + hasRel = 0 + lfo = j.data[13] + while lfo <= 1023: + lfo += j.data[11] + k = lfo + if k & 512: + k = 1023-lfo + k >>= 1 + k = j.data[0]+((k+(j.data[1]-j.data[0])*k)>>8) + if (k&0xff) == 255: + cutoff.append(254) + else: + cutoff.append(k&0xff) + cutoff.append(k>>8) + if hasRel == 0: + relC.append(len(cutoff)) + hasRelTotal[3] = 1 + cutoff.append(0xFF) + cutoff.append(0) + elif kind == MacroCode.ALG: + s = j.speed + cutoff = [] + loop = 0xff + loop2 = 0 + hasRel = 0 + for k in j.data: + if k == MacroItem.LOOP: + loop = loop2 + elif k == MacroItem.RELEASE: + cutoff.append(0xFF) + cutoff.append(loop) + relC.append(len(cutoff)) + hasRel = 1 + else: + loop2 = len(cutoff)+1 + if hasAbsFilter: + if (k&0xff) == 255: + cutoff.append(254) + else: + cutoff.append(k&0xff) + cutoff.append(k>>8) + else: + k = 32768+k*7 + cutoff.append(k&0xff) + cutoff.append(k>>8) + if hasRel == 0: + relC.append(len(cutoff)) + hasRelTotal[3] = 1 + len_temp = len(cutoff) + cutoff.append(0xFF) + cutoff.append(loop if loop!=len_temp else 0xff) + if kind == MacroCode.WAVE: + s = j.speed + wave = [] + loop = 0xff + loop2 = 0 + hasRel = 0 + for k in j.data: + if k == MacroItem.LOOP: + loop = len(wave) + elif k == MacroItem.RELEASE: + wave.append(0xFF) + wave.append(loop) + relW.append(len(wave)) + hasRel = 1 + else: + wave.append(k<<4) + if hasRel == 0: + relW.append(len(wave)) + hasRelTotal[0] = 1 + len_temp = len(wave) + wave.append(0xFF) + wave.append(loop if loop!=len_temp else 0xff) + if hasRelTotal[0] == 0: + relW.append(0) + if hasRelTotal[1] == 0: + relA.append(0) + if hasRelTotal[2] == 0: + relD.append(0) + if hasRelTotal[3] == 0: + relC.append(0) + wave = str(wave)[1:-1] + duty = str(duty)[1:-1] + arp = str(arp)[1:-1] + cutoff = str(cutoff)[1:-1] + if arp in dups: + f.write("ins"+str(i)+"A = "+dups[arp]+"\n") + else: + f.write("ins"+str(i)+"A:\n") + f.write(".byte "+arp+"\n") + dups[arp] = "ins"+str(i)+"A" + + if duty in dups: + f.write("ins"+str(i)+"D = "+dups[duty]+"\n") + else: + f.write("ins"+str(i)+"D:\n") + f.write(".byte "+duty+"\n") + dups[duty] = "ins"+str(i)+"D" + + if wave in dups: + f.write("ins"+str(i)+"W = "+dups[wave]+"\n") + else: + f.write("ins"+str(i)+"W:\n") + f.write(".byte "+wave+"\n") + dups[wave] = "ins"+str(i)+"W" + + if cutoff in dups: + f.write("ins"+str(i)+"C = "+dups[cutoff]+"\n") + else: + f.write("ins"+str(i)+"C:\n") + f.write(".byte "+cutoff+"\n") + dups[cutoff] = "ins"+str(i)+"C" + +relW = str(relW)[1:-1] +relD = str(relD)[1:-1] +relA = str(relA)[1:-1] +f.write("insArel:\n") +f.write(".byte "+relA+"\n") +f.write("insDrel:\n") +f.write(".byte "+relD+"\n") +f.write("insWrel:\n") +f.write(".byte "+relW+"\n") + +for i in range(chnum): + order = module.subsongs[subsong].order[i] + f.write("order"+str(i)+"len = "+str(len(order))+"\n") + f.write("order"+str(i)+"L:\n") + f.write(".byte ") + for o in range(len(order)): + f.write("<(patCH"+str(i)+"N"+str(order[o])+"-1)") + if o == len(order)-1: + f.write("\n") + else: + f.write(", ") + f.write("order"+str(i)+"H:\n") + f.write(".byte ") + for o in range(len(order)): + f.write(">(patCH"+str(i)+"N"+str(order[o])+"-1)") + if o == len(order)-1: + f.write("\n") + else: + f.write(", ") + +for i in range(chnum): + order = module.subsongs[subsong].order[i] + avail_patterns = filter( + lambda x: ( + x.channel == i and + x.subsong == subsong + ), + module.patterns + ) + for p in avail_patterns: + patnum = p.index + #print(patnum,i) + g = str(comp(conv_pattern(p)))[1:-1] + f.write("patCH"+str(i)+"N"+str(patnum)+":\n") + f.write(".byte "+g+"\n") + +if chnum == 4: + f.write("sampleHS:\n.hibytes ") + for i in range(len(module.samples)): + f.write("PCM"+str(i)) + if i == (len(module.samples)-1): + f.write("\n") + else: + f.write(", ") + + f.write("sampleHE:\n.hibytes ") + for i in range(len(module.samples)): + f.write("PCMe"+str(i)) + if i == (len(module.samples)-1): + f.write("\n") + else: + f.write(", ") + + total_maps = [] + f.write("insSI:\n.byte ") + for i in range(len(module.instruments)): + features = module.instruments[i].features + a = filter( + lambda x: ( + type(x) == InsFeatureAmiga + ), features + ) + init_sample = 0 + for j in a: + if j.init_sample > 0 and j.init_sample != 65535: + init_sample = j.init_sample + break + f.write(str(init_sample)) + if i == (len(module.instruments)-1): + f.write("\n") + else: + f.write(", ") + + f.write(".res 256-(*&$ff), 0\n") + for i in range(len(module.samples)): + sample = [] + rate = max(min(module.samples[i].meta.sample_rate,384000),100) + smp = list(module.samples[i].data) + k = 0 + while k < len(smp): + j = smp[int(k)] + s = float(((int(j)+128)&0xff)) + s = ((s-128)/1.65)+128 + #s = ((s-128)/1.6)+128 + s = int(s/16) + #s = (s>>1)+8 + sample.append(s) + k += rate/7812 + s = sample[-1] + if (len(sample)%256) == 0: + sample.extend([s]*256) + else: + while (len(sample)%256) != 0: + sample.append(s) + f.write("PCM"+str(i)+":\n.byte "+str(sample)[1:-1]+"\n") + f.write("PCMe"+str(i)+":\n") + +f.close() + +# frequency calculation code taken from +# https://codebase64.org/doku.php?id=base:how_to_calculate_your_own_sid_frequency_table + +tuning = module.meta.tuning +f = open("asm/note_lo.bin","wb") +for i in range(96): + hz = tuning * (2**(float(i-57)/12.0)) + cnst = (256**3)/985248.0 # PAL frequency + freq = min(max(hz*cnst,0),0xffff) + f.write(bytearray([int(freq)&0xff])) +f.close() +f = open("asm/note_hi.bin","wb") +for i in range(96): + hz = tuning * (2**(float(i-57)/12.0)) + cnst = (256**3)/985248.0 # PAL frequency + freq = min(max(hz*cnst,0),0xffff) + f.write(bytearray([(int(freq)>>8)&0xff])) +f.close() diff --git a/loader/samples/minexample/guy_amb.fur b/loader/samples/minexample/guy_amb.fur new file mode 100644 index 0000000000000000000000000000000000000000..2368704a597982277fc7b5131683d9e9d95d328c GIT binary patch literal 415 zcmV;Q0bu@koVAh9N&-<7htHiEM;-s}3f#=1MJ)uC3>QUCnl(^kH0~p8C`g?!g<2&+ z&~}{e#f7dq&ga~@_k4$Y?oC&^?bd1C(VOmBx8bDwM5NOs zOsi6TkT6hH_IS6yQzS-8Qufxwe~{)!aX~E5=~Y^k@y}rx?M^nA-@x#zL?kgW$(X;) z*bjENgrg_{7u?PzZ#91|lE|VjvC@p8YXoKmsyQKme#92tptXG!Ow% z5Cd_L07M)foCW#rvzrCrkY1z3Iy!%MAj2M}%>rT7dbXpxfLmTU1acW6% zRLNayPHxuAWpC75oSXAl(UF)>D`M{V2_{~Wg6?qqZMB`iPIh%{D7=5U+& z3nwh16_?-!Jcz*t3n7LpU9C{)s;?fF(bQkM#it)Tm8wPO91qjh*;Rh@NfzK}0u z7DfsoGT|wLGX065E=>S~`qPO56U4wIh=T-3f>dC?`3y85fDR^r0U{s@Ob`Q;APy2B z2~vPa!k6$Rd|z0s%SNCU?(8IwEtsS?TtKheX4!L%MoaR}l-97c19Vsidname - jsr loadraw + ldx #song0name + lda #$a0 + jsr load_8000_zx02 ldx #towername @@ -1246,7 +1247,7 @@ irq_badguy: badguy: .byte "badguy",0 fontname: .byte "font",0 -sidname: .byte "sid", 0 +song0name: .byte "song0", 0 introname: .byte "intrbmp", 0 towername: .byte "tower", 0 towerbeamname: .byte "towerbm", 0 diff --git a/loader/samples/minexample/use_this_sid.bin b/loader/samples/minexample/use_this_sid.bin index 7a9ce8fc8b8313d2537a2ae58d4200f25bfc34f9..07c064103cb46c6983f9cc6d5ccdb1897d4ba9cb 100644 GIT binary patch delta 2183 zcmcIkUu;uV7{BM<_O@e4*R4fe$lPSig%JkE&awcxgUNK1+X7><2UK46VEi-DCpF&j zfJU>%kQ+^-BfV^E$II4>dGz-__aOtDH+LIQASK zj>Tf}Ri>l4BuR2HlU#k$hq=ER4xW&ZxomNogv6NJeZ+l_Ez>H2TS1<)#2s)CTq6V0 zb8gCrmuOT}kH@I!ik)(QGH>11Gsu`_J;tQv8?9W?!o5*MGvIKsD4BgGYZr%BC$@?E z#eVTc@vQifsQ$hwddgrKUMeS521`pfm)sj9sv((&Mh&&niZC=({m%88mj!qp>kgv` zvUot}Jiq(F#OY%Q`6d@NTQrujESiEH7KgU?Q!Fc@=5uYc-B7ROFs?vyrY|tl1`d1Ul4jYMSh%YywwRy}`^|&hM^Q z2t6$t&+(#}CnC4A@#MmcGsJJ?aN>O#A&k2BO~*v z6`N-E>%vo?E*@QsGu4_`it+gZixpq7Hjdf3;@2cC+)*fe( zM!N}Scu1i)L4ju)U3JZ>)j{*>9XrtXIB4G6j&AgGjt2C%98Kha$~zx@?7(dgh*b25eTS1r=aza7Ckb2nJj2T1DExT|zX-ivjmV#}@U|&Xd&Xz-V z7AF(H&?b21>LWBY=iG~_e>?Y~e{yrTf&ys*f-%!(Xe)AkH@}PTD{^uWg5V8;CkXO5 zg%b>hDZIqs*g4h=TIYJ^3S&m{53uDy@ zWRfoBZ7%*$(Ig_gh$VRNvj zQy|BwFJU8n5jsf1TFyPg?ukLzfcjDb3n+far?ATc5t(UDx}E!#{;YEUK*hH1>=1B*CKWN}$Z zh%t-S2QOkDB-{b*0%h$jrT?HU5Emcx#YCCTIJX2bKKL+WOlD%v^>#eu2ReZCN^F zA7^kzYqcMflMF6L6YtyW1>yCCA%_HEU!rHvyEfmRc;E#+e<&V!QO~!>13h~F<#^zP zoYJ=&pR@&nx=B&R%@BU;%~!|20km26mejn{QTE@Pm8n1c7@d8 z`9jJ{AKGpTy#f)!Y)h9|`YlCk zuQ+6Hln>z1`YUSuV)^}Ll1*kiwG5k0mTZEZ7@7JvX0DgEox2{pS>+iVw7B_rd=4X# zNMO!mSlz2X);xW*|3VNmlKHc_+2Rh)&nNE;Uow@l_^A&*{;gy5_UH-BwELZ_O%``J zl}e>CGHhnE*#(Qc@C#WZl3RViw;y z$`pqyJB1GI%gSe9zjM}Tb!jYD9a>21s6j_2u&XI#i7Lzj&dVscH zIlvU1RY$M}UsW6IM^&mH0%?JY#hI39gGrvd@vYHj5_O!8Q|~zSj8k=z!6^>I3|``J z`VO>2IV^H{nod1q6kfpKwD)A}%fo{0QeqI3LTySpkC+X6-9JJIMPtHFu})jnHYTZpar;X@>&;rXQl7 z5cSS7>sPT{I1y&mSqd1ZYKR_9CPSf2CKTE_0W=0%1RGn7QjbAZG~g2TCYZeoLl`a0 z@OD};Y9Kew+m_tGeuVy~5@|X|W4P2@{#Z~53b;S~y|MlvZml0jjc|x<9G#s-=)b5% q<^;v<3R7IId+P31wh?!muYlj#FvLxQA3By~uuG4A^L88jkKrGx;(Fcy diff --git a/loader/samples/minexample/ys2_new.bin b/loader/samples/minexample/ys2_new.bin deleted file mode 100644 index 836c63251924c5450866e3adda58712f2598c93b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8351 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 K`&DZCH2oiS?mBb; diff --git a/loader/samples/minexample/ys2sid.bin b/loader/samples/minexample/ys2sid.bin deleted file mode 100644 index 372de98305807a8ba074e688de211c43918cdea2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8305 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 XwGHLxpbqgh5$!5sbl-Pq>C^PzfY%=4 From 6c7de32c6e8224e95cdba7bb326a9181feab6e55 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 26 Nov 2025 20:54:53 +0700 Subject: [PATCH 05/26] Add conditional jump to music player --- .gitignore | 1 + loader/samples/minexample/Makefile | 6 ++--- .../samples/minexample/furC64/asm/furC64.asm | 25 ++++++++++++++++-- .../minexample/furC64/convert_to_asm.py | 6 +++++ loader/samples/minexample/minexample.s | 9 +++++++ loader/samples/minexample/use_this_sid.bin | Bin 6904 -> 0 bytes loader/samples/minexample/ys2_fixed_drums.fur | Bin 0 -> 6189 bytes loader/samples/minexample/ys2_port_legato.fur | Bin 6501 -> 0 bytes 8 files changed, 42 insertions(+), 5 deletions(-) delete mode 100644 loader/samples/minexample/use_this_sid.bin create mode 100644 loader/samples/minexample/ys2_fixed_drums.fur delete mode 100644 loader/samples/minexample/ys2_port_legato.fur diff --git a/.gitignore b/.gitignore index 32b1aee..07aa64f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ loader/samples/minexample/*.o loader/samples/minexample/*.zx0.prg loader/samples/minexample/*.lz.prg loader/samples/minexample/*.tmp +loader/samples/minexample/song0.bin diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index 2241425..276c2f2 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -131,7 +131,7 @@ DISKIMAGE = $(BUILDDIR)/$(NAME)-$(_PLATFORM_).d64 AS_FLAGS = -Wa -I../../../shared -I ../../include -u __EXEHDR__ ZX0PRGS = \ - use_this_sid.zx0.prg \ + song0.zx0.prg \ badguy.zx0.prg \ title_320-prepared.zx0.prg \ tower.zx0.prg \ @@ -180,7 +180,7 @@ $(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.bin $(RM) $@ $(CC1541) -n "otomata labs" -i " 2025" \ -f "ys2intro" -w $< \ - -f "song0" -w use_this_sid.zx0.prg \ + -f "song0" -w song0.zx0.prg \ -f "badguy" -w badguy.zx0.prg \ -f "font" -w font.bin \ -f "intrbmp" -w title_320-prepared.zx0.prg \ @@ -226,7 +226,7 @@ $(ZX02): $(PRINTF) "\x00\x90" | cat - $@.tmp > $@ $(RM) $@.tmp -use_this_sid.bin: ys2_port_legato.fur +song0.bin: ys2_fixed_drums.fur cd $(FURC64) && ./convert.sh $(abspath $<) cp $(FURC64)/asm/song.bin $@ diff --git a/loader/samples/minexample/furC64/asm/furC64.asm b/loader/samples/minexample/furC64/asm/furC64.asm index 5629d5a..0459488 100644 --- a/loader/samples/minexample/furC64/asm/furC64.asm +++ b/loader/samples/minexample/furC64/asm/furC64.asm @@ -116,6 +116,7 @@ fil_hi_n: .res CHIP_AMT base: .res 1 chipnum: .res 1 has_played: .res chnum +extin: .res 1 vars_len = *-start_vars .endmacro @@ -357,6 +358,7 @@ init: jmp initaddr play: jmp playaddr +jmp extaddr .byte " furC64 driver by AArt1256" .if actual_use_zp = 0 @@ -779,6 +781,18 @@ effectF0: jmp begnote .endmacro +.macro add_EExx +effectF2: + get_patzp + ldx extin + beq :+ + sta patind + lda #$ff + sta jumppat +: + jmp begnote +.endmacro + add_09xx add_0Fxx add_00xx @@ -796,6 +810,7 @@ add_E5xx add_EAxx add_ECxx add_4xxx +add_EExx other_effects: lda effects_temp @@ -866,11 +881,11 @@ effect_smc: jmp cont_advance eff_lo: -.repeat $12, I +.repeat $13, I .lobytes .ident(.concat ("effect", .sprintf("%02X",I+$e0))) .endrepeat eff_hi: -.repeat $12, I +.repeat $13, I .hibytes .ident(.concat ("effect", .sprintf("%02X",I+$e0))) .endrepeat @@ -2142,6 +2157,12 @@ clamp_note: : rts +.proc extaddr + sta extin + lda patind + rts +.endproc + note_table_lo: .incbin "note_lo.bin" note_table_hi: diff --git a/loader/samples/minexample/furC64/convert_to_asm.py b/loader/samples/minexample/furC64/convert_to_asm.py index 14ac9aa..531f72f 100644 --- a/loader/samples/minexample/furC64/convert_to_asm.py +++ b/loader/samples/minexample/furC64/convert_to_asm.py @@ -44,6 +44,7 @@ def comp(pat): elif pat[i] == 0xEF: i += 1 elif pat[i] == 0xF0: i += 1 elif pat[i] == 0xF1: i += 2 + elif pat[i] == 0xF2: i += 2 elif pat[i] == 0xFF: i += 2 elif pat[i] == 0xFD: i += 1 @@ -114,6 +115,11 @@ def conv_pattern(pattern): temp.extend([0xED, k[1]]) has0Dxx = 0 continue + if k[0] == 0xEE: + new_byte = 1 + temp.extend([0xF2, k[1]]) + has0Dxx = 0 + continue if (k[0] == 0x09 or k[0] == 0x0F) and (speed_type == 1): new_byte = 1 temp.extend([0xE1, k[1]]) diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index f87c15d..9e68f72 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -1502,6 +1502,15 @@ part_10: @finish: jsr position_2x_to_display +part_11: + ; tell the music to end and wait +: + lda #1 + jsr $a006 + cmp #17 + bne :- + jmp end + .res ((*+$ff)&$ff00|2)-* end: ldx #Hro;wH@WO_ug}8A;fN%;?;S_{1l!q{e01XKQ@p2)D@Jb+rU@RVX zfVC2rO;S5};KNwPFWHifkZm-wjVZz8EEPT8oQ7V5nEpwJFX`AvROZt*|%V#gKq^+>Dwk}!v)TGH% zg#RBc+P{?u6*G%_M0YNl%hAo}^hMwb7NN zOBI6a0C}FTaXHDevc|O^qOLVmqN#97CkVd^QL=KlQyim|q%$PVCdormB}rK%Z6awm zNe4;FBk2f9`6NvzX&On#N!m=3g`}+{?I39kNjo`83RRe-NmQYe=8`lS_6th{%l}lt z<_2=DB}XRL;Thp8_rhZ#9?YV~qduI{ z#*;prQtl^rL^v*7G+FMJhCU{3< zS$Fc|!B4L_{95sj?EF(`CA^(R<3ouDDX)~5QZAF1QEn8vH>@OEaa>@yFR{5@F4%EK z*0{Ucqmf9h-0m2P%#PXpnA?rSVzTg<;tX5JKBf%%V-$Di%CmVn znoS!YL5ZAA%%Vn-Mv*LzmQIcOTA+=rRWmf}zCdP?eLKfX>j`8gg-7)SA}fKQ3WRtd zA+mo|h9G1fM2Ofd{&UFFltP%CJ)N+P)2SSc)Wm-n%5;Hz(7NtUzdlT8#!=2rU`Ypmck$uT02@yN4? zyOGX=pT)yY<7-Lt%Ns9I^#v-L$)`5F%^-_crR<@;xMT}OMv&lRsfpM~kvc_Lo-_+AiDV6P-~fz9i)>jGI0msW`J z6HVO25JLr6tGL78V5=&=SVNvQ)IJ2&fqyhuKB&TX1OHwCvYnN4S+#DI2yZH8 z)^l5}F@w|2AVS2SLM0+!7F}32K4@9Pmo6hG5Q=#`{@hrn@OiyvEcoR{r9 ziX`HDAbA6`WK{FF302U>!*Bg+Sv8*hul&^oT4-NM`UMQ~cSl6aCX?Jo*hQ`K zP4*dHm#*XvPmo+AIy^FJh9^Y1-N|#hv%2~QcbDtoj(#y_Rq+_JcYkx7S4%WUlQ#*K zmRn^*FVc0$&jGTOiZmVaD#|{C$FoS= zaV06}$oslx4ax03*HV(N`&`RN{@mwUPV(12*Uv~ET<3b0r=SlY|ww??fv{=0FnU;V+MPZzgLsek(7ivN}}%)c(#|I*L592$x-W;<2`c7-gj3c_U#m(QpeD?G0_MD-njnPJscoj!B+ zyo@D3Te)`QmYsVK{?k7fyK5UShX3t9{~Q%HI(DyH5R#HCmWdN>w#-b2W7{^Tv!H;; z>uqTXhi~1ApxwF^4!5*;y+j2CPUp654o7CD%{FnO#gddH2+m!b*FKw(K6PTsKMpnF zZCD-;FMIFa*Z1ssZTIe1cR8K=4;(mn=umE6-W!JxA35qga47Ha(fl_Hj=lYE z;d{j=oCoucx(eR@<$EVim6li4)Hx3wdGpvWi^*MCQ{ND5z2wZxKUR36w9sHn&CV~Jhkx;2N!8iludaT0^Y@XjqRyjlpD3>jUJ75o^TnU> zf6Qc>Fm;wWF?saZA5NT_K0hb7?(^^dc!9IFw$|IP`OqfYY_`ctvrS%Vdn@>-(X*D> zAlcizTnU1;R_j9ReXUn4p5Ri$W1=gpE84{swim2iz#Eg|m_BbU$LwpXtnXbjJ@(Tq zMY0D@k>u7bCLwARUg7^XRni%a+Vq(^(@g$9d6?k|!*s)P!;6OfhIb4eLyO_JhCdjz z#u3Kx#x&z|#+Qt_#v-HFc+vQ=@h;BjNYfzVW|if zUxMW{cre1KHU0q}wZOA?;Ngq#bUHj9W)KWfK@CS8Z9UP&Gh<6PBh~~P57wsNR;-2{ zThVUYHfUcs=_M^&jRZLX0x1o{Fr3Rjp!Jxs#i_C<*yAh(03R8i5mM0eHMhhSq9B$D zS(qW+1BEkLree?Lrz zG+L$|ptf2~0$j4eDZ7^Uk2GbP6`B-{P5e@D2@92IoTf2?X;nC>K-*W-L{Tf42PNn= z#s}mq#u8(9ji52;HKIWnKV|=A?UXg|{_7OekGB?IyY_G$TD{WFD$PG(@*Wrc>UaNz zOE)AVKmVG)uborcozG_X@GeG^|SLwHUp)>SFi1frzTwaJMaTu}$fB1FV6a$EDtbECzL6VE~NP1F{YReRMrg zYjM>nYpP;M0clpoGIpj1rb6GDuJ07!KsBp1bf)V-t7`TA)io@nVa*!Ws_9W}W+B$Z zf>26;Qh?LA26FxIp{_@zUdOyTRP$k>@~R^sdz(KorNV}FB-K7F;%ulM;I^!^6fpeC-(pm>ZV=y?8-4h_4kV{OupUcb zkm;0PPM z;;I+V;ZpAbfTZ0P{Kf|3d1J`fI;dG2N>o@4iJ`>S#E|y9HmD706;@De0!YBzrftqGih6`?*cUH?4qc4#_!rTQSA(OWH@Fz zAO>M};OK`r8Q1+QD#wouH6h^&NI+!pj9&pgdm<_FY$p!nP7Jh5gK1n6mDp)*)ewv#HCgLbnA}?j%iY{UH61GSgGrk243rG(#gM?PI z3@;yJw5naf>@_T-j*p8}TJ;F>Rf>F-A`kDdQJ^7H#y3sve^>ZLRjh(##L!_5R{jQj zH?zChqG~>7z**2$3SG@W`dEgWE%y7}?uG`pyEpwv3j%~R0<2+nFUvsqXV{{8KK7%5 ziv%_($&9CA1G)hvY5qR?|HwiBZyo-6SKyZvia6$_Ou5J0FT{bxHiPTtVI!^8;C!=W l3B$oEV>nfRXIPxpGFI|O5x987;ggpic%)m&wpS?${|i+#JF5Ty diff --git a/loader/samples/minexample/ys2_fixed_drums.fur b/loader/samples/minexample/ys2_fixed_drums.fur new file mode 100644 index 0000000000000000000000000000000000000000..7b8418b6d0a8bfd1d61c5ba3cb93e924b87d485c GIT binary patch literal 6189 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 LGV*@_x>B)k_*Drb literal 0 HcmV?d00001 diff --git a/loader/samples/minexample/ys2_port_legato.fur b/loader/samples/minexample/ys2_port_legato.fur deleted file mode 100644 index 6a638f997c595639dbc1c0e563ebaa526184d6ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6501 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 Date: Thu, 27 Nov 2025 04:12:31 +0700 Subject: [PATCH 06/26] Fix badguys blurry border --- assets/build_macos.sh | 2 +- assets/ys2/01_badguyz/koala/png/00.png | Bin 721 -> 689 bytes assets/ys2/01_badguyz/koala/png/01.png | Bin 1075 -> 1042 bytes assets/ys2/01_badguyz/koala/png/02.png | Bin 1800 -> 1772 bytes assets/ys2/01_badguyz/koala/png/03.png | Bin 2023 -> 1999 bytes assets/ys2/01_badguyz/koala/png/04.png | Bin 2165 -> 2140 bytes assets/ys2/01_badguyz/koala/png/05.png | Bin 2697 -> 2670 bytes assets/ys2/01_badguyz/koala/png/06.png | Bin 2045 -> 2019 bytes assets/ys2/01_badguyz/koala/png/07.png | Bin 2595 -> 2569 bytes assets/ys2/01_badguyz/koala/png/08.png | Bin 3432 -> 3405 bytes assets/ys2/01_badguyz/koala/png/09.png | Bin 4400 -> 4373 bytes assets/ys2/01_badguyz/koala/png/10.png | Bin 5240 -> 5213 bytes assets/ys2/01_badguyz/koala/png/11.png | Bin 6608 -> 6581 bytes assets/ys2/01_badguyz/koala/png/12.png | Bin 7354 -> 7326 bytes assets/ys2/01_badguyz/koala/png/13.png | Bin 2158 -> 2133 bytes assets/ys2/01_badguyz/koala/png/14.png | Bin 2781 -> 2755 bytes assets/ys2/01_badguyz/koala/png/15.png | Bin 2088 -> 2060 bytes assets/ys2/01_badguyz/koala/png/16.png | Bin 1212 -> 1195 bytes assets/ys2/01_badguyz/koala/png/17.png | Bin 1353 -> 1323 bytes assets/ys2/01_badguyz/koala/png/18.png | Bin 1102 -> 1070 bytes assets/ys2/01_badguyz/koala/png/19.png | Bin 892 -> 856 bytes loader/samples/minexample/badguy.bin | Bin 27828 -> 27948 bytes 22 files changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/build_macos.sh b/assets/build_macos.sh index ea65917..49c17cb 100644 --- a/assets/build_macos.sh +++ b/assets/build_macos.sh @@ -1,4 +1,4 @@ -../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/badguy.bin 01_badguyz_cut.csv +../png2prg/png2prg_darwin_arm64 -m koala -bpc 0,6,14,-1 -o ../loader/samples/minexample/badguy.bin 01_badguyz_cut.csv ../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/tower_beam.bin 04_tower_beam.csv ../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/tower.bin 03_tower.csv ../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/lilia_hero.bin ys2/08_lilia_hero/koala/png/01.png diff --git a/assets/ys2/01_badguyz/koala/png/00.png b/assets/ys2/01_badguyz/koala/png/00.png index e50131d30733e10dda93ded71a3e67f7775b175a..e0f15f78525e2ba5b91b98396f094f7d9ae1b0c1 100644 GIT binary patch delta 117 zcmV-*0E++71+fK?Bqw-DL_t(|0qwz25kUa}1i*76i~{&kOakE)(1sA^eckS!l6(U& zsFP6vjFI5|8`S`eI)}epFVDbH-k(=E&N=+$etQIt^8SPak)av}PD#E27}SyBj28L< X3Tg=5y?2M200000NkvXXu0mjfa4a#~ literal 721 zcmeAS@N?(olHy`uVBq!ia0y~yU~~YoPjIjS$(bw`s~H%WW_Y?dhEy=VJ?QAm%)r31 z;qj*bJPHiV2iTK?8+J&}m@RnVU;^ipTXrft*%AVn4OTHqTxICVVsJBMSS-~L$a`P~ zTSCaF@BoBKDTn>1KP6muPXGKQ_wKns9*}ct`St1B5B#0;>19nN|Nix;QPo~B`SD}R z`}dgs__s6EU;FrRj{fulc5nnbP0l+XkK Dg^%ee diff --git a/assets/ys2/01_badguyz/koala/png/01.png b/assets/ys2/01_badguyz/koala/png/01.png index 95262e43797911c96ce5b5e5ecee31cdfda866f4..da2c493228570f8d16ec06853a408ca93ca2490b 100644 GIT binary patch literal 1042 zcmeAS@N?(olHy`uVBq!ia0y~yU~~YoPjIjS$(bw`s~H%WZ+f~ohEy=VJ-D$q`lTf6 zh1LA)CDSU+5i3F{7<_6?{WLh)wZ&q-_OaWCf&0*o^x4OHxhP^Ol)Y!@@ci{48@4DAtOU}Hj zvrPeN*~i(=I3&YL}at>+rlb$;&0W-^ySG9_5uwq0XhQgzx{GRf3fbH%4suUYZy@d z|5n`(4UmA?TwPUnGH>nF|3`pcD+4*OdfNf!sO(f=ps?OME%w9y11N-`CR}S*na>oE z0d&}iMcnaE`|E#1KiK={&*}Szf8RV5{`2$vf50SW|6l0dMV19uaG}8(bg$xn-lvf4& literal 1075 zcmeAS@N?(olHy`uVBq!ia0y~yU~~YoPjIjS$(bw`s~H%We|fq%hEy=VJ-9J9CS8j4 z!fJl~a%Q~)jKS5y?UOI@_ArMz%vh*Z;E}8~BjM%&qbv6tFL7S!74zq2Ze!3FGukQf zdS3B8m7fv~PQndAl%VJbT{3*_Z|?1_o__c6<>IpafByvUJEH&pPk34X@!NmQ`Tft| z{QK>*|H9*9JCw}JzyDl(`lm>RZgfM;x#btqxoeKa}fm+Vqt^M}`q~~eP ziM+K_rRjGh(HRU=X2H-cCRd>456Xew z2P%v`xBNi%Ool19n8F_v**%^7I5+MPs(TK+S7TVZ?Lhb&kPCpm_;E*U2UGUiH*)jl zZLYSt#};>6Y)2B%i#OM9Wzx^(7KzAa1^Md4)0$K2$8R6VzReU4cKq?jxngWFk#dH2FS=nTU+-(`TZUk{-=NQ?{B-lxmEwu-}3y; zzmN0Vv&Egi{pMc%57Rw+I2~3ZBi)*b`TJ_;|Nmil;QnQ?2U)eB-~O)oq`0REqR8CS jj%~pOV7eP@Xg_1k@!DT@uT8vxg#m-7tDnm{r-UW|(Y~)< diff --git a/assets/ys2/01_badguyz/koala/png/02.png b/assets/ys2/01_badguyz/koala/png/02.png index c672408670422e4c0c64b15e6ae62e9be01cbceb..f4493313177f14e68899c980cb96c1ceea51a02d 100644 GIT binary patch literal 1772 zcmbuAe^8Tk9LEO;O}ym|SYCoU2Sy^DVUq}040v`t^T&oTeu#&VrLqL%qR8!>3sPaL zfQKV+Lnp&W`C$x;DQy~7T5>7J79q-MqSr+m)Adgp6&a6KHvA} z{dv8gDdGijG|!cu6bgmLN09^y#f1y^9aInaR4oZRPoa3U@{wrKA(w~Wgyj0AJjd-G zo4k7B+3<@v_l@YC61TzH6-@TIn3l|ML*I61Y&)14-kLFznO)Dw3-O4YVN>&{JF57P zYn784D`V=Jipu!tii#jKA;F!$rHRSsGXmB(76q(JD#vlpib~N_E-Lk`bW8V~tw+dy zFdJjN_Wu1xJ_|FJt71WH*YL-~%Q~0emwoi80p0LLl%L_CDiA-=i0)AZRtkC2@2Vuf z+&1}hL|Ag|Sh%{!)C2psBYE4QkT?Cs(}XC@YuC`yLAb2!TA?oCN(iw^y{r8iW*5W? zTW_t}j!aclNn)DNmOD@K5a~8v+UN8As5kw}(O(a16;%B1oi(9~VC&I$>!Ix=oB^dr z(}`fhO`-O4WNOvRJO8XMJ#nf(kbaT2`}Zldu<7NSTKf zaB02eZGJPz?8#fwd8nP4zLj_P127{vKhB$ub|qoS*{Z-?8ppi#Jn9QBilL0bIjJVp z_hry}Gji=$l}h~{dUR`)->g@b8=LPh zv7HSvZz%XvrU2Xn2UtZ1MvSF)mh0dSI9wj~P6jfy9;STqxMpMbd#gI1b;oDT7bxXN$_ zOst2|z;-->A^wnDH<4ZrCkkTAKtHLAxHSivJ&3+k5$clK=K+cylhx;Dq&5=Ve+bV5 zUcQ$IlZy7K0@Ya5spG3hLm1*?M%|g$XdHPQG8F|~gpdO!u+&HSNlF(hku2gQi~i}m zAPG$*x3dvIYW^avkQ31G34tn;lLY9H%s61*BqRnF`W75r!j^fDB#`h67Mdv!Gb2kZ7jAj~-~cz}GlxVX zIRSq?oUr)t7J^uqULuy9Cg=kejRX@Kme44lxSnsVo1!&m#o*J2TMHB zWCFo31hIvbxm!#2S!O%oP#w%F*AZPYaN3=R1>*$~c(n-gN*h|*==gEeSgIQ<-yH+! z)ztW^`*MNi$T)Y}#dXod`!jn=ug!9hhF2>!`l7rWBPs z%`+Gb{p-Q07g*&JfH9FgqUE3jSKyx`Di3WK3peUwrKLss=*xYjeYwRpKX>u9*N@C~ z+$dXvY3f)xrp``UXKverd`FqpkRKm98#W7J9z^&!=a@OEvgyL#C)~`5B0MF_nf-0N zyBF@u=hR(rDi}z!4_ZzeCTsep*;f~4Hk&hMJ!jlFKfZc-vRisZX4Tk_%>K6j(s)~q zyl$*J0fgiG7H(>+w%CW1Z8~wuATl=RaK>z(3xw9eK=dbtgfPXOxpC>?cF_}ew09y4YMF0Q* literal 1800 zcmb_dZA?>V6t373QUgnsqCo_AL1#-C8Y==)SD+Ve3$wLYx>W0kI<>Rn2QWrO7n>NM z3#BE*56~jBvj`E~?A!o_F_&PRtfeI@1Q4AYrLxKKkfT@-t#=? zdCsj8Z^;g&N75-2N~nO~ODL2DJQ&{z35MTu)Z|tQCDTyN^ouhOZ<*F|2{9}K@fGz}Xj&(&7w@Ruvndr53+tO=m*@Q$w69`-WNV)!<#dQGF&tLb;# zx!RPiZpIRL&Js>vlR4%5_Z&v=h81wFlIIJD9JO^raJXGtXM0$DxhkYi2AQ@Hi>{4% zI;NAooSDG^KJ^So6f42iy*IkJ_T6l|=3wcu`pO53!_4d7=CAx4P+Yjjm}T08fMN*{ z8qxs@*!G}%C>Ph_&bCV_VcdT5vB0rg1r?5Sd*N0E9OF~b9vrcMAvMuPo;>3)P8KVf ztdo^IgyT+H^=PEpbfA@3RGfSPI1sHDt$-{P!gRU5awVppi-8~{Zu2m@+oRs5THii&O7jA{j(4!oCaP=xcIy zlUd&?XDWL!&EBpN2fPB+==Ky^T`+vIDU93r`ItwE1)($epA2!OP@1lh*f9WaLHin@ zyfBp8cr;3lm`8aP!7!(lh%XM1qnS9I>WHc^n$MaUNMb6uugJmWpLq&JOBleaJ?gpR z$fO}U&k)f(m0JJEHdD%{&hMV|Ee6t7W8!G0@+5$b}P*p!t!kJGh1JN|6 zD~t45w3ZAqg5C%+@{8A11cK`aMOmeWd=MEZSl#9?4;1XpPoZE^6Z5Ru zV6F^7RzY9_I^>achxB3<+XGHyD$^&FKmCAKpkO4P9k-EfkZGZ0Pz7CPjaLlztGtM8 z)7O;Uc{<=|wq%zd-)6uU2$Mq^CvoV5FSFITxKL%xs*~aJi{xd$3CKPmzg8A`&dhK} zq8Ton1cLe0yGU(P(^5Z&vE0k#l=g9m=>Q9L4J9q9A+(`C*j>w(WPp}Q&si{q6A5wE zHWTx!j*g~bRT9X(h)l6;03TAi*)iT5Vt*(raT4qok}&i)_{hFRYR&I!n#$T|I4cv zvo}AQk9M=zcKX=ps7;l$e6!0RCX=Z=1yZ{{{42}fe~20u5uZPP^HO(Ng*Tk(rlkV8 zet%vanttnezl%>rT}J!r_mRZWS_IGc+H@4YUj&^tY3uA*_!<;ZseuV0iH+&N@F+RukxT|@% zeb@1snwrthbeY)SvIk{f#}JZ?|Io4j@gD)IKfN$Zq IWfW-s0CVIj0{{R3 diff --git a/assets/ys2/01_badguyz/koala/png/03.png b/assets/ys2/01_badguyz/koala/png/03.png index e77083016e4e29c5c464d3d122a6be35528c025a..c5e39828e0752a0521aaf741c944adf3952c0995 100644 GIT binary patch literal 1999 zcmbW2do+}J7{|wLi4!|*L%BCt5vH@%Cd#EV!%LYo8Cthux16$3dRy8Ev+bdgWz@Qa zXuVr84LX~h06uFEdD@BqbMkZqoP+esfgq`6QBhrU%{CCr0U2U2RHWPfo(K?l9){yFF*P z+{xq7Xi%^WLNy`ZhlOQxY>lSJ2*J1l%RuDY7r zJQL-w@mHw%3I46eK?~JwQ)c1;gtcAG!?VQH!-HaORm?HBV5ei4X2t~{*NhBngvI*5 zhb*dKlYcl8#PBSva1-ve8KEi{Q!UE(+NAgYH?mctWTI&zhVD>CwfLNjrrc8|1e^;< z++5z=^cI%iM;&v@vudmr&hI80=U@I^J0Y%9F?Nb=;`^0(2di0Kz86{-dc&oXg3*6z zG;5TQi`OA%>8fN`MVtqM52eu(_L*8tou|dO)YeE1bd0x(pVcQ-{rE<6a1U>VgK-+# z{P?0B)!T_;b)(F<8VeV6FjOBDE%AkSH>%=FipB+ZhUaK*S#42o)zhNbB~DQY?b#mb z{H3YW3%8_0U)uVGx8^n^j;-H}C%e4e$H3JDoA7&C2DrPkblvd6xq(h2sT1T7o!}z{ zyTel>D*Zd--i(x?1F;K6!wWORwHTk)jgk}5K5J3f%|HQh<(N1%(PZ*r_dv%&<~~tH z7kEqHK3E$#y*X7SYeIhV`UN?NZW@%uonCF@7hW2wua4J09ieh|b@&(MHYgQCMQqIA zk?c?6%W?<{K}xJy)aJ+fgn)~3{KHXl-H9ioGmv`n8e;h!1dv`72D*VneRWJ|En4nh z+J!{38J_zq{mrWR)cnH1!(Mu1q(DXy#BP_z?vXMavvo0`S4Zsnf;q%++WODD4VtI4HadE%syJ>W~z_&P7$IoCvv+1hm@+ z`{K_)!Ml~6_U%SPZZf?~=7oVXa{DfUMRrB*c(Tj?2Gw7;)Q59};J``d@vZBBw@b9ayZ*2oa*jU?I z>IgU#6rQT{O=%ajJ;_E_3uwi!aZ#;c>4ci-2poi-NO=5Y4LiyDNM3&lB2?V- zBa>xmS14GS_65X2EMw=QbTUlT6f}wmq7b@t)nOw=`NxZqw@>6gW6=P`2;ZGX1iv3L zL0<3SjU^<@DnmQ%kM_%_%?Yb$I0-{7^Jbea8Qy`lU@bC=$`yLEd1L8|SK1d% z8(%|M?;0w?K$rbHY08POhN7qMg zX$i0^af)Nc%^4C@-~~ni=0k>#kuDikG#-1&;*IgT<6{%i-7@H@eIYRNhYZt80~ijj z|3=MPvIk3$=)LrI1u6ECumM2K0ofwvqRQG+nHzwA!!&m+r3A4wUDSv8v3bm7rg^)IJTtPQK8nQ%Zu3_(l0s^Bazlfts+%LjKyu=@#{P~ zVLLZZJFbK&barx@NQZS5W_+5yq_L+9>3}=RU-Dlq|7{@*w8;~DLMc>7QacMrQ7kB=us^9 vM`;Q1W**BHwS3(8pYrAT^l#SxzbRF(F=?!hc#&!ZA8L{ZgGn#lzMu0ClF_2= literal 2023 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 KT|`a+3BLoYxbpG< literal 2165 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 literal 2697 zcmcImjXTuo8lIWMK~rncrqi;6XyjnFUz}ovrV(m8mZ`KYBvAB511 zvZThM&_-$!qjLFZG!vutWPRjg5=moHzDDPHN84X;_PWMg<2UoZ&;8ubec$h!;qB?V zYQ?%0I2>-3yBpmHhr>I==Qhp1!#h`PYb6f1!rPs`-S;SdvbibRAgZWUE_PHty7fBr zgSL5E&!BVPx}D8xqbKXiwYHQu@4a%)G`7xs6Hnqui8vrJw>SIkj;Hk>JMGPj1_|23 zEJB_(q^{YO zLyy3?ngOe+#Vs^V!kQKpqS^o+e^r8da)2gmG-m3MSLVZc-aLNMNik4%F8LJrweQB;nt;@!b$0teZ;_nC{6j6zb3D~WPB8IZ=}Lfl|5Pye zYcu06kL%~*5TE*_?8(U=|Iy?q5j7ttQK^G^HAz!+4~^D@crGRmYg`EAT-2|5bbIP@ zTU>%zdZBT5ICPwxp)WCs;&r5v-WxB5Sloho{Q5!`mvn*$5QK@)^3|w{%HR9@^EWCO z5wDiYd5g}mdF%~?+o;7ZOS6*&yt!Ml7ybQvyPqhTolF^5ln_jubqNwueqEaxcDue_ zeNmShq6Od?EUno{*iR|%rK%vUI2SfvQObro{Nz1avv#oI?Y$puytw~vE1?P0JL+a=10cpdFY#y>pPkLhMmlnt_LbAGZ`h>3@Eu}3%MYd$#VL`ms%#CtLnCkQuG^1WH{VN0U}pG*`FOUdE$_g5vIC7mFVL5eU5 z1aO20J26=C(zuvo{t*lP8P?(qip;ysmX_T@CUxvc~^2trH1gLD9{nSXqOsN z&3ye0S?OektvC$R85&iu70x|vjF?7}k&bBafCAQ7TLbjKAL#Y&e(Wzs^${aTT9uWV zqL1RYZEyZ?>Tv)8_0;A&NKd)t&^M$RJ!&OJW`}Ogv2%J+aQE(@Kqv7wxf2v5R7QUurm7E07Jh1hA7Nr?ZI|KW20wp~SFQ^Ob{$%cwcn>9 zmG?;dl1xFr6ctCMNyb5-wbc(*vpw9(>Wqc0ML>e6S`w^$YT#14K_lBzNQ^AO#Bs<`KUFZ3&dR&@VFOP0 z*2l)gAZh|a`}#I>;UTZ=ULv2E5C(z{`zfx1Z{q=Oqd6eoo?H*BrQl*Lypa-nXCWYB z@qNCEZ-Yj=?muaMsG_;+)K;e#&lyGS2XDNMl5vwmqvO34VBffxnV`aAb;Rr@2<_0V zU496j%D)g8wjLYwz#PtJZp5_;&bMEWYsF^H(G+N)UVUAn%`A)MNtOu4+YXK<9$4pe z|60}_1gWUJd~IeL(pPaobn`TN z57+>@OMjB}A$)J6(noj&Oo^mneHJ2CUqXP<^V&C~A$&D(HlBNVp=^Ht)hG)+8fj=) zz1CTCJIEX|pxXq3iaAEp+|J2@m|I?DMcZW1j(~I-66MnblMm#SB`P2gVheAaY!x4! z#wR!@V688P>AVIK_W(;)iGBvgkm=S@tdg>N$b0x%Of(=IglF%r>icwA6hLq z4IMqn@S*3w|vw`46d z1j%`U&F9w-R{^P(g94~+@tIgkNCr9p`nKuC7%m@&Y2y{^g~R{?*o2$+Hh^3T-c8>L zpo6s_I*pb)N6LWbhkL$`VF4cSKhh;q*6?_K>V!FPHZh1m~X=8Nzj+dXrBdl^_wBR&|`ns8RPee7v zE3HNT!1dp|zwH1aKbTo~`81YGZJhgoJTxZJQw-`%>-TtB9g!BaY$L1;90BT{YTX;j|;}f>`|Ik*+Yby zJ%a<|eIkWd2Js5nr`GTa?m5#BT<0dIf+rrF#930PxEnLQ15M9F^Z?cQ4HF#SlCxxt noTm~9&&wheDndC{Ob0!c)sOuv&BHZ zID47ME-FxTY%4V~;+rt+2A8k^*EQ=aPpq*j5Q?vTS&LZlQNinXf+UYxI`wD;MZQ;Q zu${lkWwwibQ&})SK<+r;1-MT(Bzaan|2hrfO;Z zx zhOONj+V|d1^LCDc-m(U6)MLd?ky7v2q_M&rqUO=a6U{?rL;qAMx6Z|>LNLy2LVqu#E>l5re6P^1}U3LIXZ z+OWU#@d(A+gDhU8&pY4K%7;qVM;EYu(($qgd|p-{LRx9qEaN^GfmQ?0dWou~Rw{fZ zIhwu1L?@=OrxX>wFCEVuc)zX`d}*T5N5z{ zvR7u1SqbVEaK!GoAKBqqgR6mbN2z+TtaZJB=x$;2WW!(i%{v8lR4^-=2LN?U zo;NS+%D?XN6;4*sUO!nYk^Gp8B3ICbu zBOv&aYa@gYNL=YBWsQtub5ie;4lWU{*160jFW=>6|90W^(#b1S>Ya(Zte3^Zdt5J3 zSS||#7ybHOpqoObIy$G?i@Umd?;2!%@<%LUNB}GL{aW-!-puIkr+2k zYhluR#D10t52RSlK;wA&I7b79Qkq|0BTnkO$<&_8ao6Sb9`MA!aQJK(n1$3UWYcbU zlDz+EAlf2{D(d7j$5nsLk=8@rJzp-8i4e0`IHV3b{6LvG6U zT;8Br&`r*|K1n$Oy}gdDobzc5owa?7w0^rq4?jxb^rIVxKMF{-`EPxkB=3 z9X77Y@XYghWj>`bkJ)!K%)j=5{PDfqfY4}~VXKl!*J&hPsnYy5bzvav(ws=sO=RCo zU28XsmOMXV+^1OD$SeDLs>V-sSDVf@(;zUd{ODFImr^5iQCUkf!bMhjs8k75wIY>*( zsluod_HM)AJbum1U4nDlb2H2mRV8Fwt7)rt3O*C|UgvYBghS0iX#=x_i<^=JCp-OM z`gq68JxoUo{P8a=5L`$R?S3n^#Xf0dI)&3W!*DQFt~U~`0_d$5aX~C)XTfiZ{yjlGOP!d zPRP3p3X2vbCfUko*k&#jn+CoBpi=2}a5GGaxb=7zI$OR# zpf+x8I#)prpR3zO>QJHyj$;he#e@bqNxM%0ANbBQf+Mk~v=uUTWF{~j7E07G(60dc z)>wxId=w=%ozJk^6>lrJ!b<2`J2Ls?0vWjc2Hbf3_Bc`xheb9qdO4w;37x|?PVbxI zw6~XF5R4HX0uRKHCiOx%EtqWBsE^P}(D^Bq3xN4k!CHW%I9vw~L=1_Ldf-7sZy9EGU zh73?Tup`=mLz-(##S$GTX4`)l|IO>6|A|gN$8I;o9dRr8D%aq+O4;vvBwc;j8gdlnoZx-W;n+~Nj zaVyrJ(MWV^`Y#tCz_5deS+BJ|q-)u$YLLxR7V{9DW%GUFSA>NXCj2It7?Rbo8?K^8 zMzN`F@b`oY)k`kf_BG_pky8(&5$8Si2zIfE!S53JUR-6b-4iSRuxBj391GVvft9c> KUb}kB-hTn)eW&pN diff --git a/assets/ys2/01_badguyz/koala/png/07.png b/assets/ys2/01_badguyz/koala/png/07.png index a5acdc1c08afc3f40506bf9b93df12a417d6f767..9093780aab916ff02e8a386612518593d7fd0153 100644 GIT binary patch literal 2569 zcmd5;X;f2Z8irs%gCTVe6cH38=>RUcFl?C`!lJpE3d%0ZB4rUppp77FKy)-!DItMc ziijY$tPXG_-~cK|b2w$GhZtZ)C@5n90|O$&g_LF9?}9xuXXgLRpWJ)D-0%I~_j#Y^ zdGF=J9vmuV6GcNqgUZF+yfid4*>K;!RvUhQSmRKwp|MWJb#wMf(wus@Cw8#^*13@k zz5a4Tx%P{;UUO&m=DuWFaHjEhM>GFqADsEVIQt)KOt2~)v)z9g88*&udM|6guu%M_ z|8icte@e79x?vih?I zYAI{hWpKvD)UlGq^BLSdL6^6Epnfn`>YOw_z;{zCDY$8c5HqBIOj^DnMk_{YA8j0E zj9>LL+x&!+eG1-G_(H@aviy%Kktd20C%4N|e-polg2%}?!#_d;`*~J!r5V_#lDm5Cx}29kmuc@MovAeczfs-WAeHU%W!WA%W_FOP;3lmG7ii@S4AwY}yjX z?d&*@m%6Gg$np&#OX?f0=tt2#qx1Zhu&{3?>8dJNQ)xJ(+C8cay`tJemg}5N%xKfq zDlO+-QN>YkU4UX~F2eoJPz(l9!;e~X(FIb;%Owjg{d7z`KkmqVn!vDs8Z91qa}A$l z=GBsv=NHDi3S1LxUp^BnddByaW_mgXe09(yhR?S#z1hUmGKBQHfs9p7?M<0l4HY7%ja>l~Cj4KN)mL0(n2DvBqVR zK=FFvUB+nm!&Ja?*0-2eB20_oD;Pyv%Cdf+HF4^|ouNI=lQmdu%~Nc-3{bu~LQBU_ zHZdxzjcScnL9K~oBs7fWPsK`0reZJnm<82M#kzX=+lZSBMC*mA!(X-xepOKuX)-{w z41@fCRV8=V8wr|g=#Vy1pLj}7xvY;lu@U87L)DDIp-VX0v04*>kx_RfV^BctNI$aG z0Mk*oSHw6}2^W0e)v)R5T8BUE{Qlk;fk(zg1SNZJz7Q|`8Jjru_*ie>dSx|<9~C35 z5C%$EJg-AEZ*k@^G4IX`Tj|T4Txdzu3a4hhkru2UoxMA9IOs73fj3gKIw#5URD)Np zlk|Xo+V-NIT!4cC`#Ode4Fqs+l9G}yK5dHdrzfZ6&)#;Ox5}}`V1Hu^l?xXZzi96C zA;7WcJu)NP*y8k%3g)pb!Evi1RwF%sG@KO1{v1E$$JZCTpR;-7uZZR>y4JPnHP|*9&|ywqgn=Ydi%1TLc2e|ZoZgH zQm$9GbEgCbf_GY_*C%ZW0@qAJqYYQV$3hG+!{bi35rC<`426h(39RKd*Sy>Z-1vO* za5^YL0#ZO6F-;0xQG;T7>7y_{-mW6>PD&ZAUNwUQF;ZQ=qT*zeLZ8JSw%N4t@%Wjd zDbObgnxxE9x7$N~&u>9lOs3vK!fpJaNJMx*fY4ohJOh{!25u1k;#zo1m=6$j@!Vd&;vH{Axf677n)-rk zUldJ=hO5~D(a008OIGZaAg8~L9t13hU3e|Bz}X;myC+|PmyL?O`ymTxpoo(9BLd!9 z4lLS-%DN9LEZ(PxerdVj4JW*_=Lr=&f2j=Ztk(l*QuY(}U4;ztwLD>SHxoazJtz1H zXBZcn^x55$anh?mPXGY0{{(ckBaLMNE$8X=@VIwO{Rm!cv(Ob!Nwt-MXhxBgT2>ai zxHnKywjv<#8fRt$%&sanvy{lNlMoYx3yvb(|JTs{UjES@CtJYLksBjH?ox>o0pCJ7 zyvz43-XWpFNa6ND(CGIh2pul~f|cO#L!ddVGaDjGZ_CWz>?av_`|7{VVUs{fsyhi{Z}mqyFO#yU#$E4PVoOC_hcb(nhq8b z&mya>fsf;LihMK*3U@e2O#P5c%F>UBdix4s1#6@kgF}AZ@lK0bN>Y;g`m(}X250tx z)61QpXZ`6%-V~Gzth$-QVT2051y>8I1Fa(4>F5EQ|Fivy<{zc8IBJ;o{CfCT-UJ*e znOpatUn=QZO9#Yz_5T$%@!o$!@&Ea8(Qxd<*Dd2~rysy4o(6Znhg*%y@$>%#bThjB literal 2595 zcmd5;X;hPE7Dg&!S=7Q18}tZ>U`4{tDNq(`f+TDLi6VwY95#_fF)qZQRwWP#OV~vv z5*z4s9 zrK#nTRG}1WD7{y5gVJw&ClkTGlv93OyhwHnVaq=|>mnZ5NDdIF=H^#iVUVcbQs)wU z)O=DIeKwf!s@cLLaCs3g-o|jrLzXPXlN@bKWTpwFJ`Fo$)9dq}lwU31?-{_(?OP-*brghWEd`~t*H6&XuQ|?RBPMF1*VKq5Mcl@Z|v+pan|JndZ{$80XAM8 zuQH4s!pZm%WPZ1Em{CgQ75NRz%PXBl&6hlu^&-jYB{u>Uv^>y%X73*q=V0eLqBCA& z;_sCqKM3(Q{l5538hZ5b-)$bbH?`z9HbxNB)v&OZpIUD}NOKg^!S(Cm6+KI?cj>&N zxcNm+Cz)!!)K#S2lhAAeUVEIwzR(^kiK#lW1stb6`zKw{Hh#4to-VjGrQP$}1+QKa z!84G}IPh^HvbC(bB3ZPvp>BII*L!{-_wVqDsU6iB4z}c+`wziC$eeTZXueQOru$V! zNlb0DO_!7efc#zQ^8^bE_0oTlGTM;q{8B9$clsClrULhlvhZNt;o!vd+1Y;5(qb<0 z=}KXRdF&<^msdAmb)VjPSWohcXz^&DQm0d2m#aJncDXnyfsycEC zzS9wImgr}~pvYa;4pxh-*pM!YGxAcL@9y(t$hQ7uWqN|}Yw{;kBC`$Xx`ZV+?KI0M z>E~wGl9u8qG@OFrsM^sah-qgeIXVtPD{%LLjh^2e{!M@g)7k|S-ByC@usJPBdK=VH zCW`0GPnnELBuR#YGrW%nL7{d?$3Cmnpa_RAd4Z2K1w*~gk2&Wy(*@zd#*p5IQVR7n zt$%?!^9wzz{%NxWR4`Y9h=-H`>+;VDI86cTux>#cJJBC!FAl^n_oBi$(+3h_GK+OH z-yl6y;tdixa3b*!e$$0gb0x(-jPsYt`vNI#P&7^`-7(>O(w}LA**+Oc zp3Q2KNghC>vn7K*~u*aJ@M z+8|J>1TyRyfVzvX;9)Vt#Zn=rL#=hDaMUKGk{8ilg2F;5*Hhkz;x`bfw*r6u4_YP< zQAd(i2&F`YPpr1xPpqKN!lwi0{2Y$A=Lg@MG6}XLZ!Z*sU>YK z`V87)FKSaYKu>Z8OGIKmM&6gUDEt)7%@szU$*Qm0e&O(fi;~L*8!XUH&ywNdp=el7 zpTxhc!O8ALk}D^fO(0krb#6Zh9e4yersf-^+!abga2aYnpt@|Uu0T?2-2oY73khdt zhlp%oVo2e%=eY9VaHj$-nbxWbp^C&0(b&R^)nm;}L%M?S&+G%(^6wf-w<xq4U7y^R9ow!zU(JI_}ibxGz=7|PNg0*<)0$S{1zA+ zcaE<4z^LPI%2r8;rGlD zXe8(WmgKY^>(&X-6x3kNVne;4gK-`JXRVpVa(m W$pzf$B|cpKR4DGgB;o#JSN{v%tIWy( diff --git a/assets/ys2/01_badguyz/koala/png/08.png b/assets/ys2/01_badguyz/koala/png/08.png index 0788e60f6f78da703bde75f3fc5e2234061533fe..de200f4d436d6980535b5da0f1f7de58299b1a1e 100644 GIT binary patch literal 3405 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 i!?FMW{Q2?GcJRjehePE?Kfuo?jy+n literal 3432 zcmdT{`Bzi<6-N*=BASHFI#Lp2P>?0=kaHjed9oPU1O=ijRS*?WjHqCu7@_)5k0en+ zAp;K10S4R<%Cry_L?l3A%DCoG;|K|kl2Hhs@3_uh-+ zmijC4i~rbr&+*x~*URIjIG(7aGi1&=cwo6DgK>E!Jm~lzc(6>u>WYaQ7W-VR)oIKa zr8l^D>!!;4YG!3 zf}<``2iI$MQ`xqVYTzNcBN%+LIhNX0Y$yG3Z0odFQ2^U%i3FE|y6Vdn2+ezvN5YY_j`B8XL6a&Yb!f(7iy-Qt(p?hDr|E0MOtZrZwdALpfy|_RbgPw9Vi8ji@KG!_50)G0;@+uq~s$9yl z9^F1u%j8J5J+YNmtk*<}%#JZsf`TZpLPVz`V1ZydN$21tIC|@RExgWH+P`qfn!OOk zQH&yIz{%P^vw-~&1t+(b`6+n)>V5orlo?~`YdG6p051=1MTq1OFO+uEWA@w0wWYrm zp9Y}sc+Tn8pCazpX>4q8g_x}P>18BVQV=^3d`9{G#H^24x0-;mAVLFq;PSJk?Wa*h zg(xDzvlT569L$i0M$zN%Lv`8^j-4@w5H|CS*3tm3m3L?OPz~AL0t$`77Mjb<0icAX z$?TM8h2yD>cN)2xmrxZz8^Vco*vLcfbXwP->vpk{<}6{M zf+5#pR#I39HLKdRy{J|<8vofq!?GtQeKN_&D->y14A44#3U1{9KpztLoJS4C)F&;% z`h%e!Skk_AbqUBG#lYoAGWncM;~6>18cRle(@6jE*KIQxZBCRdGgRY1RGES7w^n&i*~gOylbIx1*#udyN|DK0j$0Y*hCJ%x=w2j?MKPx zEAK_netU zWe5+8HPzg1A_Hep0xLPI=1;8TpsCmQ*h-?ji_4B={z-J)-@%V>V#cj;H!Fr$9P_eMAw{cE=Y`nVmSHphpV=wnS z!1EWw{-!hLvQkqvk27?-7UTncXAX2d1n0E^gzAS+ZI|Y!l>4L2LRt3>wVin?VD?o$eqS;RGRRXjyUB@;cNrjp0a$ne!IS z5aLz{q`Y?(^kC=ud<(Dx=!#h|=b(U3r57YRARgU8{-N$FXmojZKS!U>(5-f=P()j= zsdfzawqK;@0hQ1jE)akQs6>3Io)WG6D5SkBEJXG6T7eD~V2&LIYL128QQ3d8GDiBi zh1%2Lw{i=Jm8^sLL2&H{PoAFJ=}s=!E}q-r%zBF3S95P0?Y-;)vm@n6#fTXfKv}&F z#lt1jaHouvI}(k*&$Zpmt#P8M5mc}C1MMCCT;u;8_wGytFrDZue1@@oe}fc5Ts(Gf z;UVcFZ{0GmFM+B}&jR=ZA&17{(6_+R^Lg)b4 zF&KT#q%qhe>WRU~c>qI~D2<&oA{>;2=I>y0UFwL~=g+mwk$*4*dn`293{AeGgqy|{ zh4D8hiopj;h1L;bg(`-vsC^klwQ?W749?WJNy$2m>&*$S0CugBa@bOAaouv`mv5gj zq5NB+(RQItCoYx3&N62RiM2;o-LSnkXSZs=Ea;xUMq`WHHxWP+>%^-6wsux=nP$^N zm^F(k-M9e5RwhxX?H7DCxgd?v^ju}Ya$GJx=&=Kuc2?+@XClSQ`Dj`g^@@M2HkGbg z?o@#*JpQxkCMJ40ta8Yw=Ka3-R&h0!*BTdudn=N+qG@WBkif}U#*k=Kwr~qg@GPxO zR`%fDhl>cZc|N=%7tDM5!qVVruHOn&sB}0d$zPsSXq;xmbR8WkNgLejA4z@>a?h>I z+J**BMcM{vQp!me3ftG%h83-uUjCYV8(e-1k}8D(!LqZ5 z>2LO<2@;ea^{{^h1NK{GkI^^9fVvc68Nph`J=Qr+ONl#6k&Z;t8A}I28bPN-CcoqG r8?<$d>Gvgg7kn{h#Q*t&Pprs>=EkDHsh98{lu6L~5bVafgcJV)69p^P diff --git a/assets/ys2/01_badguyz/koala/png/09.png b/assets/ys2/01_badguyz/koala/png/09.png index 1b2bd3c85772b5815913401ba6ef4fcde338c063..dd50168f135e6b18abd737156caa28344d5070ae 100644 GIT binary patch literal 4373 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 diff --git a/assets/ys2/01_badguyz/koala/png/10.png b/assets/ys2/01_badguyz/koala/png/10.png index f81e8f8c57fc78309caa3cf3625516de0829a16c..8b453f9cc8d784143d122371830b9663074cc412 100644 GIT binary patch literal 5213 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 S#rCj@iRjqb>ZG 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%0D#m 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 literal 7354 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 diff --git a/assets/ys2/01_badguyz/koala/png/13.png b/assets/ys2/01_badguyz/koala/png/13.png index 4c18b0ba1393e90acdf6dcd74dd4ed8d8f53d3ee..c7e44637bc3e0429299831c5177084a680f3fc7a 100644 GIT binary patch literal 2133 zcmcImdrZ@36m4Zyd1)p^m{?s`ods4zQG6BTX@5A8^3qKjQCtLMMF>nmTLd;B6a$59 zjE7Q$%5%atsnqxz;8@iK0i_~>LIt(8;H* z?CmUTi$xX$0>L@}^9vymh+gph%G}xTUi#kpMgn2(;s8JIuoU7S7gxpK+f|l+z1gK? zlO3L(XTFg(Nc63;(Re#2RI#1eb$-rImV9ev?_@9de2%qCN5W%X`XbH;Yp*%H=y%qi zb)B4QPiiA73dQLQipXI;MVVW%5Vm=Mg%dTvd-*cQx^I?|z7vWo-_2p{MMGPy=BPLV z!z_!FK2{x1wuDvV6VNndpvBPid6>Z1T=5^0m@#;EVaa7r1GG7sT zzdt)p*Hux~jwY&1;VgAjevewyn=E3zpC0IxoKvTqJuST;l9rsm(rB&uz0q2h;u*|r zT1US3r{8sV2SEl=7Ea|8x$@xS(Jteh(5owt3h<#P&W|6j7)eGgtUA-j>V*rxV2Y$S z-6;b#sVuG3Gh}haA#&<3qeD=vCGfIjKvkA!yTGE;1E#w}wT z)^&G^?B!~$Gn~Y6<%!&~;62cCcsK}GOWm!^{C6LGVS89_BTLz0h=hX&{n=4aZ>Z+p z8<<*NRZMyQI*RNCuc|~z3CWtwI3Qzr7o>zN*vQYZ1sIt}nJP9IWU zX^ttMr_QlZTOQ#zIqpZwjYb2@{=2!-n?{}K6&A4w7O_u}0U_l?Styl(-A*6DuRoey9P zD&MS)Hodt~SFFD?9K`7YJzxG@YoCp{yzc>4_^8?4=&w#!GzKZQJU=d{mg0Z1mGgrX z9Dq0~HLBHKxYNPqhzm%g4Z|#Vs2Bqq9lwCHu*rfd$Zm=IZL#Y{~I^ZW7~olO%XN8ezOJWnK@d1eItAR4|weWEr`Es~)F~ z1zr|u4IJHmW1y_IGCMe19MLG81h~5B#?#DhbyN}!*1EZEPc_Rz9~WK(|hn0 zG~3q~hROM8cOZZ0CL4$&(ft7&JM^v)N7P>vg{T+?9+17$$RyA2WGjy($9-EvPi;QU z-I#0{G2+(#2tuz@0y?&I7si>q25U#Zq_Tmq_+)TRwFB6uj=NC+bo4%)TB6p2mEF5H zr754CS9W)>P#SUbQ5ar?SVn7vHclppd}`n%{WP}D(8fY(KXdN#v-j0IAi^IW`sWRY nHZFkp&M(3L>27^nc82Kx)mV6fP*@z`BT2sERF6qCyZYqE0Oq3v%!L>col)jWVd(x*|1Hf$|}kp$4Y6 zS7gE#@S}jzQ6Or+f=or7GK{lWaez2c!~zOJwX_26+}0VB#r<2dKW*=Q&wJi;p65Bw z+ryl-5oDKXE+i6(j3Qy{NhAjr{JuGU9DEjzU92FH#s{Nep&ODNUR;@<(6cF~|@W!nBn$!;0!;6!eE z)Mk&0c4pV~eowT4!@?O;F!^dH`kY7yv|+=4^eDK}qAC?d%cbKH*Qs&z8;6oUCr-<{ zz!J53Ka7U&`7801V%f`5)|P5z5BAcRh8DUYuJ=^|L;xEC2A3VX=7H*zY^%^o?{O5^_Y3XC?d{BxDvcAj_&p&6&NgV&F#|oC!HJL}%N|L3a zR;H7FjFd;UAgwAoui0y)$kFInJT*&ZZ*|gVUo+%HOALt@eN$44H7B%(6lCgQ1^L#z zH}t9=+n0nWfl~*kaiZYGp097<@gaR^hp_%mGHekdEh=B5ZenLSYYP_JtK~+K)nzHR zQ)aa9rHd~;z7M(Jgr1QNdumpkhA5~iU;JA{i>h-YMNJ<}SqBA%oUwsz%&INi89X50{DL6+Yzc%i3t5!=Gf|kir9OAv2UJvD;FUpTpDw~pj`~e^Qh>v z!Q!X=Z?0B0zm`S!mE-Y?Uqi1LfT3KHU*aeTg}x}Z+VJwO0>$BY5A9h68I9SE{JoKp zpoJdvi~d}ye|MgdV7b{ec&$>?g4wACGJU9pccg$?;x4F-C<;J>UK2clC4SqUnhtM} z4&bA zEdK&=op*aFu3Iud0mOht8H`iN6A*#n)G#bAu*K1v8Uypis~8Xo7^A>&Q?1XJwU;pB z<@*RbzbEse>#jmi*BirIRWWN|GD5AVSX)l&ghM_ZLbm>{*k8F2_?vkS6b89&^;mC4 zG-&Lyws0tF*aL%ck9)ub-avw5<~%8gCddVll9K46)&b&IV=tN`%LO5oQTRWzQnvvz z!CvVbvo6p;!n=z0rIqT0SjKE@CX1p@`_3*!xuYNplo-?@JYd=ksshNPe5u4d35SAU zTBAH0q96gUS#0nE=gOBs`iZ*(5ilhX(Ljcu_8=nxElVNHC4dtnLUJOHCI#Bu&cq^; za$&aZ%EV)PWp!J?a>0gn7VRTatbtKi9!V>O6{w4tgF5|!J}hJWC(X#u=9K@iDi`?# zFa!A+w$lu4ZDQZHhXo9hqGA zC_}fAOX$K#7`vO>xD>L>K~YmgVsz1v{jG`p$9c{_XFunkHS1Yx*7v>d_r2fy{Z6>M zI%;b!&_obK+u6y%13@q}xUa>l!&Qh|n~xxxC!HPEZ;iqX{cazzutQYyVt5^uJ5XH| zY~+Ls_>DuHYw-|Qc-mPQqUC?uW6NFF?1%1~qFd+dZP-x~#@zAra>cArjC_v8qWiI$ zvu-E`6gAsR165>j*!hk6af;fh) z+|zJ_v?pCpOPyX(!B;Qe*LR#DFvTuErQ2eZ#E!jIZtBcbamJVZ=vs|+5;!;u-dwyT zoeUU?u-EOC<1CTb%EhsjIj3$^-MIE4HQbmDS;yb5!=yhTB)CIfVCbzvz)2RnIbzXv z1koJ6Oji9W?QWF?8{Kape8!CpFS^Puj&<2(pZ(Uu{jeOQMonn3k7P9 z|7`V*jt;%$&ihIoA>?Y;FDhZt@p+1lXl(a;>;j|Bo|%ro27-k2y}K|F<8~mGXAZ^8 zUSBmnva~TK=QiXWSpCi*Ohj&G8g$KjpHsni1C&g7&bRMVvor!WR{9!I5ka(BhZTK3 z6c^zx^06ht{;OAb6CXsfv3{rOPAHV$_NPy%EK%JYN>+bsa+5%u3++ot(tWRiVuOEE z&_IVNkEsoN&XJ9A#&*C6a1HlLl+p(3)NpLN1t)L5HyL82@XQa~N(XtV~BOr=d^ir z1y7|hrkaj4dB}yb(+k(cNAWOOd_X1cv?0DPJkM8Os$j50{WnaVFPb{XujOF~yD4G) z)RAXlQ7+c{3AOQ+irKyPP~T#o)M(5TbBVHh^%I+c#;g)-PfHawx_V z?YCTSu*ajT8 znieuzo`U8N1n&GP7$1Zs%4O%SOSAFz=Q>8)=D8HkA=hQnxp9;Jd3z$d(m_FKsM;TP zClX1dY|P0WW-zI;k+N&Nw2sv*a0jNkQo{Ta`Tf=o>4EI>kqwQ5>~&|*&zuDgr~qof z3dqe{(OzBftV^X2_vX~BVIACFnez1T2O3|ug$8xD1cB}S_4^NY4`&zEPmFyQ%Ys)B zdqL^NAD_4gNABfk^<5G(P&%llHXhkdf6dQC{-t zByD%V45oE>W~Xm|;B?oX_>`_v_{J849q^v{lehz76}@_@XW+^LYiJwC;7*Z2Eu_n5 zA7=S;&(=A>+_VI{3|)6+k>M&E+jM~ksvbxx43l4PnnOq7TDL%x{F)_RYXHLVCDq{M z7S8uZUCXWI=4&@*d8SvRCqRX9goMGE!Ky>qo<6IZA9iiXtl_jhmhGb7hru1K)Cn|) zwhHa$n#f^IfDW#L4!V41gG2t+2D{_vWQh_{^=coavKuT*YRa`xsOeDF2gL%vuq3V? zv`h!ky#jQPx)WuOleTM=S%Q9-6@?G9`Bt-FKAwa2ta#>VXW!*tZ@RJXle@~~iARZs zkd2NfLokp*dM<#V=g{%=7yxPWtn(2=)K3QSisAW{kG_zXcs)z1^n#n>T014FaY9i< zN!saKhuVe><_Czu5^1aekBle6_`+DV3fyfFb6veMVD)%qBrF*1rZahD7E5+3H%U{-9q5O->u155;Lfg7;rp8vED)-u$z6c!%8 zp;yhCmLUcY%zYR2?=+~XT7Wglhz=zI!ynm?o#zz&_6mqdEdZy2OS}LsSWWOnYWhlL z9?=D#R>JsedXeKMi_{8HRfmRZEbt!hKEXfr5@*SWCV)86d-QB!!dZ4Z zXHVTablt^QO?)K?btT6Vz|0Cd{Ze@!Cr&UR-t$1!Cg!W#8c4WQHla)_=(ACWAo}i9 zR^3~VoWg!8Sd9z}D`W7%%kN%{M!ksR*yi7Tpd9+DBP2p}zP0B2y}$Q;p67kuH*v3v z<9y9!nivdbzSAzcI|hTL!F#3pTzDdCn;&8@npsYC`+bqv-sfeZ%L6hh24!~9-NDQC zl=HOI5;=tA1^0|!-4ZwHr3IA>8&)kf{h)SSi~qCi>W%eFJhOM|B<-ozubj8e^~MYP ziTmql1nLx)(9zVwdto42qQ%hK8L)*L`uWr3cau)_Wonp3XK7-Y=}uhrbv`tDlRUZriNpMrj1TQ%{-a>Y#DgEh4a%nnx8)LyDwn); zR-6iTO!yw|kes+pe)_0i5>Fg)%nDj#jWEDiJ?IqD2EZEXJ#&Y0*x9I*PUbVA^D$h6uvdG+N~&JXSXh63be z`RHW#vCpGQ^2O)0gfz(I_kttIP>6WPAa2>my8PR@ySa3;Jst@00%y2g&5~o{lwy)t zvs-yv)-a_wYZT%l#tnEy4S7XTNj(Lvylkm8;#jOUVMS`w-lt`OoG&A_jYeV#mCW8M zh9l1I7J$KwolbS}P#}!E&MfNjAOpC@I%ebI0V`6beWTZt4X#K4`BDvQJUHtO@TToR zZ12EF4{Wa59T~1{{41i}v zA0KpOWZ*-a1Dxa*=y~Q^3^N3Jp1c6KIpe5zP6+jQ)skF4AoGAvbBYGAKY&~I0IIlZ z<4Q?BAyB=A@j?Rjv#9ll-?;4->^1#OLh$yLF>O=74Lv3K3GUx?>4>VpwGQEQXzTOP zScA`wA!*8mexkQ>KS*4W7FAXqX7h0N@?4t_&5NKY%gn9^ro*Ar-!>u4zR5Ljdh@!s zgBHg?i;AcUGTdeTD{Hpy5Mk_gL9CLNy?U6TXev6P;f?=v*G#EIE-#0v;EPMo^Li$ghO%Kp}uYt>dz%+H)Aig}Ei4NEv8` zylg#BTq$Sn?WBX`ZMGt-!qcA;6@U98-`kSUg?6gr05r( zl9$i)8%)zQk&h8~OP){7ZzwA6tI7jUNMW0uJqb1dt%rFfZ8}h}; z<>blcdAU7uyS*)AcUcj|eG>GTiIcHPZ4_@LV1}#O#EnW+T>dMpe z1a0Pk7|H&kwS`Z^nXHL{pQH<~J(7G8o#&6hP;E8nc z9fpHHu^7|BM5Q*jJ4L%paD_D+U|j%_ktOaWh3i> zn!>?g6X>8o;r-KxSUFo8cidu_p`qulxtuC>kIMT2{g!wEm24bH*6*fh+Ihw~13_%& zaWc4~is+iV8rhQ`2@)EZk3o=?2MKykP)A@}BcQC$Hz4mt>- z5THCg8)AY`HBZ6t04YBa{j|0apsLvpPV}ZOPU<^-87eZw`DbWErs)bRr@nc`sLO2{ zr6S^bl5gCe))aCT-yy(Ffk^-GnRPu&VeG`@6_%C8W^3@qddkv)#{lI%1ybWN<1^X= zH$fyIYn+{q3UgnWc!Xb8fiS>2(WXl(KZ)?adW+e^IAhe1QC!V^<3K?vv_VLGK(@<<+(xEzr_i+z*M_=p2JVYYl8dFaE6xKrr0qA@#K7S=b7;qp{FQ0Zu0kd%L(DM&CPt z0&M>E@U=2#U7}%I9>BK_9M?c)*ct;k9dDIA2WG(V2nR&PhtLIz6n%Z$bSK{>Pg8t! z2v_SJJ0;ounh{TEo82S+Z+qAOwzd6drzc5&=UmM=1r^YML_lH)P)e&rU?wqQ*#&}Am&za@ zL=7b@r4SYgh!P2FaI6i>uuRwnsEso)XxT(Wssi@B7wK51|2qCja&PXr=R4o`opXQm zW*jomH`PZF#DIR-)fYhsF7R8a`w4uCv>huDL`Ow;-R~Dmm~N$2d_K7Tx5q8_79~o{ zx|^9)PaD5qhJ1`3hUVCQYZ}E-YCE{so|&*cXw|UsKnY#cn$~#5*k;Lh!-J3+9o<%L z{KiXBKdAi=vnHDJ&koGSJ-YUy0x>Vxis)MDA?H0%LBTb|y!8JrNkdzTjpbD>D*@7c z6M46D>^CNJH%^%P z-z%d%eUZzJN|8u<%z0NNXWN4;ZDfBaAq6`uBx?6{r{;?E&U{I5@n$PFmku*VE|y#m zlvteN)O$?Y=_}Ez{{7KtuqA2e1aqVfZaIM8V*Wv?B;Au@cfzi%nri|jK8h$hFi|6* zRWpk0a{^d}*%l6VwLy5W`U1ud$?-eDRjDfFLZQxyFB9a+D+_;M2s4RO1WMNAgd0!n zzL%nMyD0*Qv103x^m8k%Z&02GdCgFfQ+n;3$bL$ycjhFa=jhQ{{W&Z-9a-bI4$&4u z>4tBYgtF!7+2p>c^7qQRKi7fs_U~|;8H;He{XIRYPiD9v9DSOsvzKDT@2?S<`FUhk z3^QiL4bJVf`g#A6=A|b_@};|36bga0lT^1KXfW`qoQP;@2MpuQeU_2M##k&9V!b^w z&2j=J=ALw&kmnCKKr!m_lLUu?2&boLoUiJBpSK zGZZAYf?!pQiKd|&DA|-zST?@0JB^x-N1(wa=Q~)_p78VGAqJ@AN_T!h2 z_eVz_JVqK~lB+M__j4%}dHJ+<&~Y+fFc6*%bSvCK2|CKoyOj}6;zJsrLU>AH88Med z<{PZuO`Q74S}kC5C8-;70(jyp;ER9DKKe6YyI3+1m+gyv$uujrrYfnm`tmJRX<7;S z**3OfPk_Y7%&T$|?|`<2dCZ@J!8VlFOHCUNi{Juhc!sC@G_^7Z!i_VCL0dG=42zH_ z1#6GW01kxSV-yMI+fkl^nikoV)X_Nx2_e2=x28@%GGD9n$VjO!VSCr$l)f zqBdZe<lojkf+76bI#k9{A} zUisI>aq`=trkJ;nv}lXBueKRV^7RKTNjD;4o$^p53e=&W^oMe~~#v&6+^2h_%bFGSPjPK!E{_3Ah?#;dDp7U*!^Ir5F z`g+EC2!iOl@7(Tc!)CR6AJ zWmqbN3ZD!AGAyNcM{8;kKkUMV?I!_hxd;%U7KtE36iMxp6}4v~pAJ z_mAvdIMxNFZ)dZQ$cDLn>3@_Wrnwe~uGK>1TMvwvn~s>?_^(THmsz2qII8YXH(|~) zvF+!RUaFDH2~)cw!`Om?xt&CFIK@zeE9{dop$7#i>suHxpPv39g^M&3{w$aQrk2AE9t)b{i{BR~oTiTYC#b0=MHR|l;Co#CuO;?;Px)e~n zip9LUTTRnzzzp_3jm3g2$z2B-ibg(v!#1Ld=|4s#>xKy2P+JR4nSkQG5{5eys5 zpyzM8>VG-!;;PNGszBnh@(hj+*)ACRD(k!v0fRc7n28f7%#8hvcbG;RK&TmNm20HH zZ40%NdxZ}z9ursxpZjK{;~Xa3MOo5yDj=nDM7(LBdg0*^wB6G)iadfp?v5<+{SeX4 zgwa!Gr>d%_2Zs}+jGOO`_3(K!7U{gsb?DclwLOEL@zUy)v8tYt1f4C^rJQFX-XUL) zw9;<+P_4qL$+2c^r=o7M-$y)EnL(wZmu<*3ZUBS+o-!4?wh4OZuX|D)U1*5k^@F=! z9%&z6^=FMJW#;0XZUqdZ6osJjT(-l3$H0Tyx4&h#YA2NnkvCeQE}1Nx}_9<&u`lGLXU97~>cU;YX-t47Hxdf_?-AYzI)f z`-KY^a00_a(ap+dM^i{Wl`v8N;-Nz?-t1p?kZGR;@7zx%^_UWMVFzoqBI^P}Ai&>T zC>$+lJsd#0Lw9X$`Pz6c8$cR82(`0XlM7%Uj)Z_1wQa@>+T-rzG&xR>ve5F3cfJc_ zM?l|D0$8tJVPZlC_bGXNK2JX9YQO?qEnzfcv5EXf4a#`Z5DK^CPQGlz`YeE$CM;G1 zv*5>$jx=6p6E?mRCT138EXS*60LM@j*oaO2R~e0t-6aMPCu-X3%2Az(Os5)KB@I;L zTP1)@uq%g5nCF9BV-2e1j`x0r7H1L}=WvS<0k0Xi2DnF70*>O{em|l?y7Odp@6*&Q zCBmsoOHE_vgX~|t!0V9)P)#C*vC(C)N+Ym5ZUnyf2d{oY6~_l@2l`Sf>gVGVqpyEo zn8Ax7aOG<8?6m5HBkS)UMI5tX6GuZ~&NEgt*rd1ih-aIl)QlTF#plF`I2+){i}&JG z*_@>-Uo(dK#Kn(By@nb`SPx$|W8>|;4io*^jxx8p*`%J^^-*NIGK=7p6SI%*OwOE( zB4zD>e(*c0_zyVy0GwmvZz50@0nYQlKJLW%?0c5T+jV3~>v2`DWw#wgNTd>gSG)Sv n7pSxIe4N4#o+y*L;T<1kb8wnKf@atM0S)y}%)kBk*sYfT}h7}#~VN35di4Tx_Cg-}d;qHMS zD*pRDCeK<~|L9g>?I*kQo2NffW8e*Cn6-+*B$P2@71MY;4Zt^h})p`Ro0E6K}rEnmNC?qGHBP3FQy=Xr^Xy*(fFVobl6J zZ)6>-%Pj8=v|Don^SAy!W9j54W*~9tWR`#NSe*pa>~#BVL`vDND7L)S$jaf; zDgR$sY&LYOJA3kJXj*d50sWaw{Wr>rr` z+)3FMx88X7jvX9-0+$_Nj#_`c@puxKO~dTjv(H?6U7DBNGx27*eVy=*e4z3**I%E} z)6+Am{`koCLBAQR+<~7zE7P7oe?D{V_1AZf&3@f{pmsJBe?oq~{)Zbrjj~%JbUtNo zo4xr!{>lSK45H2dJoC=DoXlV2w;QRII z>F1iCpDG{dEjz#`k(~1FZvTCjcc8d}2Kff(dol7)&VF@#V25s|<_2e=lg`ZBTO+q) zwdM!To4}Zm&*FNsVEw-@*U$W$C(pD$9AOYR!GR(H7|I{2A&JkFwd{n1^5)5>S09K) zPL5YZez44miAyy*#!<5Z=n$aOKfHNhRS*qNV?cv4fPMuTw%PnTd*f~FY23F_7MK*k zs@^`+LDCObensTnlg-QPIr-mzy`BF#*nj?@*oaR|fXCe3Cr385hGAt!vevE*fA dOru`ypK@hV_uisioxnnf!PC{xWt~$(699z8`oI7H literal 1212 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 literal 1102 zcmeAS@N?(olHy`uVBq!ia0y~yU~~YoPjIjS$(bw`s~H$rL_J*`Ln;{G9=zBqb6u46 zz-95z>sdq^geLr5JRy#K0f&gg{xvfiHc2kd<%kfNp$1n z6nW+pe8@YjggO{kMBNZRelA^X*>a zd0Qs=1NW@sAKRS2b1iD;+r7;76)bT#N@GFH`?r)o96I;;%>9ku&%OOw^K9F9zCRBI zD;%@e9;lw}FmY?xwW!A1KqWwPzJKD_v*7ivqTAKaqk(pQ*vaXz5{TS?ECZSvdwnX~ z@xmuS+oP-B*Z70&`F!p3&oe;B>?w^6-*>EX9?-tSzpGpFv)<3Web3tW+r6Lj-tPUJ z4)nwPo7L^t%^5XJ88yBFE%|K2{63e7b=~VzrLm3MA)d;8KQ}+|z3h*}EO8g^Spz*= zUB$95IeYD$bDw!?@|Xf%3I6Be1f_b`dCO-k*rl-VSs> zEc_CH&WO^^2Rh*zFf3$`3;u`)CbI+Vn}H#?Yu%nw8TSX?K$93XOu!BUx{aRbD@Xn5 z^Y(wGD)i^q{nyi(^Oy-V%Lk`0a%4^~fn5Hs-sXZ>B~`8PiQJaf8GrgG;x?GJI^52$~svHN_ja$e=@ zUF!~9zca~(dH#{dA5TO-uY7j?PTuwd*G)diR@ul^+Q>ETFXpdNdS1!4Z))`e>ymlt zapyjtsg^lDar*0Bhx)1?)PqbC?0bCTbZKnk{v!TA{dwD?|8+k9Ecqi$>cAWCccXG|X53O76#jdFRvP`W~M+T^ie%U&>$OaQ?Y* z{@mv?x37E6RdZJNr11ww8@c{HrSsDN&At6r?8hv&e@$}z?m+aQ{|>YKiOPA6@=xV{ za9f=>)_-34EL!IH#Obeh9qOxo;Qyt@?z0@!=>JdTehA;q+y2KKXx{_(%m>WYeaa5U z3t9FZxBbuv()8KpvpdL6UuFZKvmDmFJ{1i#Z|!3Xru#sC1CW2Za$conpR)e-Qr3M} zfi7cco@~hEF`1uH1L!f4s9o*9JwmtBF?fklbbLxKy-E(9%Sj8w& k>ivo5z=DZ|J>pmF87?%sX1~jr7Qz4op00i_>zopr0O_a50RR91 diff --git a/loader/samples/minexample/badguy.bin b/loader/samples/minexample/badguy.bin index 4d8173a6148c0cd04014ea1277cb2ef518b43dee..6d504ca7e39b64c77bc004a95fd42c2ec98a3068 100644 GIT binary patch delta 7099 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 USYz-rR8jChA+#E@m%PFJKZ=WxO#lD@ delta 6593 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 Date: Fri, 28 Nov 2025 00:32:13 +0700 Subject: [PATCH 07/26] Improve intro part, add second song --- loader/samples/minexample/Makefile | 6 + loader/samples/minexample/font.bin | Bin 517 -> 517 bytes loader/samples/minexample/minexample.s | 305 +++++++++----------- loader/samples/minexample/song1.bin | Bin 0 -> 4464 bytes loader/samples/minexample/ys2_lilia_sid.fur | Bin 0 -> 836 bytes 5 files changed, 143 insertions(+), 168 deletions(-) create mode 100644 loader/samples/minexample/song1.bin create mode 100644 loader/samples/minexample/ys2_lilia_sid.fur diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index 276c2f2..bedc2a7 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -132,6 +132,7 @@ AS_FLAGS = -Wa -I../../../shared -I ../../include -u __EXEHDR__ ZX0PRGS = \ song0.zx0.prg \ + song1.zx0.prg \ badguy.zx0.prg \ title_320-prepared.zx0.prg \ tower.zx0.prg \ @@ -181,6 +182,7 @@ $(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.bin $(CC1541) -n "otomata labs" -i " 2025" \ -f "ys2intro" -w $< \ -f "song0" -w song0.zx0.prg \ + -f "song1" -w song1.zx0.prg \ -f "badguy" -w badguy.zx0.prg \ -f "font" -w font.bin \ -f "intrbmp" -w title_320-prepared.zx0.prg \ @@ -230,6 +232,10 @@ song0.bin: ys2_fixed_drums.fur cd $(FURC64) && ./convert.sh $(abspath $<) cp $(FURC64)/asm/song.bin $@ +song1.bin: ys2_lilia_sid.fur + cd $(FURC64) && ./convert.sh $(abspath $<) + cp $(FURC64)/asm/song.bin $@ + clean: -$(RM) $(ZX0PRGS) $(LZPRGS) -$(RM) *.o $(ASSEMBLE) $(DISKIMAGE) diff --git a/loader/samples/minexample/font.bin b/loader/samples/minexample/font.bin index adddaf8aeab5ca99f88720d8b7361d394cd39ceb..05d4f39f805ad7436a42c1e1c701d71ebd05fd9e 100644 GIT binary patch delta 27 ecmZo=X=T~)iBY)W%0Gvz$+hyCII#<6Epw- diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 9e68f72..7190027 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -94,51 +94,44 @@ code_start: .org CODE_START_ADDR sei - - lda #0 - jsr load_font - - lda #$34 - sta $01 - - lda #0 - tax -: - .repeat 4, I - sta $d000+(I*250), x - .endrepeat - inx - cpx #250 - bne :- - - lda #$35 - sta $01 - + lda #$0b + sta $d011 lda #0 + sta $d020 sta ZX0_dst+0 + jsr load_font + ; we don't have the music player here yet + ; so just put an rts instruction at $a003 + lda #$60 + sta $a003 + jsr init_2x + jsr clr_txt + ldx #copyright + jsr write_txt3 + ldx #$30 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode ldx #badguy jsr load_8000_zx02_2000 - lda #127 - sta $dc0d +: + lda timer_reached + beq :- - and $d011 - sta $d011 + ldx #250 + ldy #0 + jsr txt_fade_out + lda #64 + sta frame_delay + jsr wait_loop - lda $dc0d - lda $dd0d - - lda #irq_badguy - sta $ffff - - lda #$1b - sta $d011 - lda #$d2 - sta $d012 + sei + jsr set_irq_badguy lda #1 sta $d01a @@ -150,10 +143,6 @@ code_start: cli - lda #64 - sta frame_delay - jsr wait_loop - jsr intro lda #$0b @@ -170,23 +159,17 @@ code_start: lda #$a0 jsr load_8000_zx02 - ldx #towername - jsr loadraw - lda #fake_kernal_irq sta $ffff - lda #1 - sta $d01a - jsr run_nufli_bmp sei jsr init_2x lda #$0b sta $d011 + ; jmp part_11 jsr clr_txt ldx #towername + jsr load_8000_zx02_2000 : lda timer_reached @@ -207,12 +191,7 @@ code_start: ldx #$b8 ldy #$01 - jsr init_timer - lda #2 - sta timer_mode -: - lda timer_reached - beq :- + jsr txt_fade_out jsr init_bmp @@ -253,12 +232,7 @@ code_start: ldx #$90 ldy #$01 - jsr init_timer - lda #2 - sta timer_mode -: - lda timer_reached - beq :- + jsr txt_fade_out jsr init_bmp @@ -316,13 +290,7 @@ code_start: ldx #$48 ldy #$01 - jsr init_timer - lda #2 - sta timer_mode - -: - lda timer_reached - beq :- + jsr txt_fade_out jsr init_bmp @@ -393,13 +361,7 @@ code_start: ldx #$48 ldy #$01 - jsr init_timer - lda #2 - sta timer_mode - -: - lda timer_reached - beq :- + jsr txt_fade_out jsr init_bmp @@ -483,13 +445,7 @@ code_start: ldx #$20 ldy #$01 - jsr init_timer - lda #2 - sta timer_mode - -: - lda timer_reached - beq :- + jsr txt_fade_out part_9: ; $0400-$07ff buffer 0 tilemap @@ -766,8 +722,7 @@ intro: lda #120 sta frame_delay - jsr wait_loop - rts + jmp wait_loop wait_frame: @loop: @@ -907,12 +862,14 @@ irq_music: bne :+ inc timer+1 : - lda timer - cmp timer_limit - bne :+ lda timer+1 cmp timer_limit+1 + bcc :++ bne :+ + lda timer + cmp timer_limit + bcc :++ +: lda #1 sta timer_reached : @@ -1199,19 +1156,14 @@ update_bmp: jmp update_bmp irq_badguy: - pha - txa - pha - tya pha - inc vbl - ;inc $d020 - - nop - nop - nop - nop + pha + pla + pha + pla + pha + pla lda #$1b sta $d011 lda #$c8 @@ -1221,11 +1173,21 @@ irq_badguy: lda #1 sta $d021 - lda #$fa -: - cmp $d012 - bcs :- + lda #irq_badguy2 + sta $ffff + lda #$fb + sta $d012 + asl $d019 + pla + rti + +irq_badguy2: + pha + + inc vbl lda #$3b sta $d011 lda #$d8 @@ -1235,19 +1197,42 @@ irq_badguy: lda #0 sta $d021 - ;dec $d020 + lda #irq_badguy + sta $ffff + lda #$d2 + sta $d012 asl $d019 pla - tay - pla - tax - pla rti +set_irq_badguy: + lda #127 + sta $dc0d + + and $d011 + sta $d011 + + lda $dc0d + lda $dd0d + + lda #irq_badguy + sta $ffff + + lda #$1b + sta $d011 + lda #$d2 + sta $d012 + rts + badguy: .byte "badguy",0 fontname: .byte "font",0 song0name: .byte "song0", 0 +song1name: .byte "song1", 0 introname: .byte "intrbmp", 0 towername: .byte "tower", 0 towerbeamname: .byte "towerbm", 0 @@ -1320,6 +1305,7 @@ run_nufli_bmp: sta $80 lda #0 sta $d01a + asl $d019 jsr $a000 cli jsr $3000 @@ -1509,6 +1495,16 @@ part_11: jsr $a006 cmp #17 bne :- + ; load new music + sei + jsr set_irq_badguy + + ldx #song1name + lda #$a0 + jsr load_8000_zx02 + cli + jmp end .res ((*+$ff)&$ff00|2)-* @@ -1517,8 +1513,7 @@ end: ldy #>fontname jsr fileexists bcc end - jsr load_font - jmp * + jmp code_start clear_2bufs: ldy #$44 @@ -1620,76 +1615,41 @@ copybuf: @tdstlo: .lobytes (16+4)*40+$6008, (16+4)*40+$0408 @tdsthi: .hibytes (16+4)*40+$6008, (16+4)*40+$0408 +copyright: +.byte " ys ^ " +.byte " copyright 1988 falcom " +.byte " all right reserved " + story_writ: -.res 11, ' ' -.byte "story written by" -.res 40-(16+11), ' ' -.res 11, ' ' -.res 5, ' ' -.byte "takahiro ohura" -.res 40-(14+11+5), ' ' -.res 11, ' ' -.res 5, ' ' -.byte "tomoo yamane" -.res 40-(12+11+5), ' ' +.byte " story written by " +.byte " takahiro ohura " +.byte " tomoo yamane " scenario_writ: -.res (40-24)/2, ' ' -.byte " scenario written by " -.res (40-24)/2, ' ' -.res (40-24)/2, ' ' -.byte " tomoyoshi miyazaki" -.res (40-24)/2, ' ' +.byte " scenario written by " +.byte " tomoyoshi miyazaki " prog_writ: -.res (40-22)/2, ' ' -.byte " programmed by " -.res (40-22)/2, ' ' -.res (40-22)/2, ' ' -.byte " masaya hashimoto" -.res (40-22)/2, ' ' +.byte " programmed by " +.byte " masaya hashimoto " gart_writ: -.res (40-24)/2, ' ' -.byte "graphic arts designed by" -.res (40-24)/2, ' ' -.res (40-24)/2, ' ' -.byte " takahiro ohura " -.res (40-24)/2, ' ' -.res (40-24)/2, ' ' -.byte " ayano koshiro " -.res (40-24)/2, ' ' -.res (40-24)/2, ' ' -.byte " kazuhiko tsuzuki " -.res (40-24)/2, ' ' -.res (40-24)/2, ' ' -.byte " tomoo yamane " -.res (40-24)/2, ' ' +.byte " graphic arts designed by " +.byte " takahiro ohura " +.byte " ayano koshiro " +.byte " kazuhiko tsuzuki " +.byte " tomoo yamane " music_writ: -.res (40-20)/2, ' ' -.byte " music composed by " -.res (40-20)/2, ' ' -.res (40-20)/2, ' ' -.byte " mieko ishikawa" -.res (40-20)/2, ' ' -.res (40-20)/2, ' ' -.byte " yuzo koshiro " -.res (40-20)/2, ' ' -.res (40-20)/2, ' ' -.byte " hideya nagata " -.res (40-20)/2, ' ' +.byte " music composed by " +.byte " mieko ishikawa " +.byte " yuzo koshiro " +.byte " hideya nagata " scene_writ: -.res (40-22)/2, ' ' -.byte "scene set by " -.res (40-22)/2, ' ' -.res (40-22)/2, ' ' -.byte " seigo oketani " -.res (40-22)/2, ' ' -.res (40-22)/2, ' ' -.byte " yoshihiko kurata" -.res (40-22)/2, ' ' +.byte " scene set by " +.byte " seigo oketani " +.byte " yoshihiko kurata " clr_txt: lda #$80 @@ -1909,4 +1869,13 @@ write_txt2: bne :- rts +txt_fade_out: + jsr init_timer + lda #2 + sta timer_mode +: + lda timer_reached + beq :- + rts + code_end: diff --git a/loader/samples/minexample/song1.bin b/loader/samples/minexample/song1.bin new file mode 100644 index 0000000000000000000000000000000000000000..98396cd3e31b4825764e60d6f075140ba51b16df GIT binary patch literal 4464 zcmdT{eNa#XSXBcoGNr~qpVilYMZry(4}gzT8bi1 zB@|eqsZ|T=#Umz2B8dUCLd}Dq!V-4IO*>3yhuK#5i`Lz#^ZwdxgWT*nFF}I#WB=Vd z;l6wBJ@kV81FD{Yt?0~&b|E1Q@V`YWiMyu>YiVx>+Q{5wQ$kX&j|k~ zB{aD-362WZ4Gw|z0P6sD4jduo19k}B0?Pu{4}+S1hhQ;- zOLSZIfoqT3Qi-aTJZMroM0OJJ=TNaF1ZN|R)4-g-vVnPkxquY`D+aa`SQW4uV0FL_ z080m!3ak;>7GQIMl>plgEE!lSq3FSpz@7$2EL#rDfcEQ~1l|3uXtNM3`CuC10rg0z zjiWcl%eLE6!gpQ%n8byCC`V@s385JUgats{g?qq-1#8AT?l%R;=I z(jYl5&v5sFbO~@lrOSZJiG2~iibfwT`S;Bw@03N0o`GCE(K8Tm>eTU2P2!v=-W8Ux zCUO2TP24=_7J{P>i^iLwa5E~d+M*cTT%_4Ynz&6@IqcYD{p=)`CMu_}P}OwGg^S^o)_|EyYr!1C*-5Ps1^6EDgud9z+q-0@)74;eLJ{6u0f1tpR(8tpyWdZ3p>R_@#hW zxy`(*+O6>MZh`U$%qEa6`nLg6-YFw}1&XNDPHV>LKh> zkheszYYDp!vArb-Y$l&>!^ld_2FUd0;jYWBPCUaBLynl9V>zM$SS4YpwuR+&0~5M-ct54y;{DV z2T_V`p@iB4?oIIAb1t7C$IM>r!Y;f#aWp|Tjwd42(I-JX=7$~_kT6vwVY6E?a7n2z z(*#{$mUIr}IH?2V>FDdZJCn6k1fLg!tR<_H(>RXc1xgt5d=}Bpq%qBl zEnS1q+6N68B&Oj#hq`!)N*>I3sH$vHX)eeQg3!kGNw|<0Z#hvF7sP;vgGwWbDilp_ zGu$i$S0Q}94?Ho(!w%){b(vwA3LgUak`OTU4r+qfO_|%$2fAjPLlrHkqXgIMATLBU z%mDd{J9M}0bll7XS04D|Fgwt5LU-c~z9{G=fyl;(9i$u18%@G~#mpwMbtPhO-DzZq z{PobJqG6Q zBs@>}RO-dIkYoc)Qulvh18fDRp=a2lJ&ge!)cge%8Yve)zM+xQb`8i$_)^g3b6s&O z-JkC{Q8fG`A`WUk!3n!DSkg|=R~Q+MYIVPCMeP=CS6OR$9k7GYHQZW`uc^am;8WDE z0(lc62j&^1IvB%zUWcpq#R2d(0!}fEDHFyHgEifF%c(`3az)1)!w-OQ<{5M_e5eo` zQE?34EKi=n*?9O3-XthXr1Nge z8jwDATh`)XcU#thbj5A?HAsH9wx-ILW`IhMpO%kJ&NsQ7rW%G;Ry$D_Tt@!wC zDfFr2IG#qIm~x;0HLKe3n#tm)V_ePGgoi^>hB+c|0Gk}3 z-O|!`c8KDhy?ggnR+_7--m9*zsTKEDR#n&5?YAC0bfo_1@kVi9RjtK(=)hFux{rDxF zSYGy;qh^Z&Im*ppogoyT;0jlVG+@1g@mtTRf@JR z;%v7s%w{sDi;De=ybHa!$S)|m5hLNyc)NR)Ky)iX>50@78tV5(>Tdk@q8#RUfp>I7 z9Bk(u{5;}f7r)@9PUQG~;~r&PF@JsnqJwuTfg*w(+=D=!2p1-~6gj5X^Ap_0W2rj9 z|3?9*HF3s|@L0yf4f_75fYXkl-f8^1`+J%n<;@WX#vO_N+R$7RM~FlG5Lb`?CJ7(# JM?wOT`Y(svn1lcT literal 0 HcmV?d00001 diff --git a/loader/samples/minexample/ys2_lilia_sid.fur b/loader/samples/minexample/ys2_lilia_sid.fur new file mode 100644 index 0000000000000000000000000000000000000000..96aad77303e360f84ec7fb61ee1a96a616d03b3a GIT binary patch literal 836 zcmV-K1H1fqoXu2APZLoTJ~MY(S_+iN2JM1bV4@2WKqTxe@`xl-8fY}egz#z%rqBQ_ zl2T(k7BH?{`4jvBhNX%A1b=`rv(U)G#0`m$P5sWD-Wf_q2tE=od}r=C_nznd(w_1B z`s(~*+FZ#lr6JSno!N zbd7hKrfizlA&82=N8p}8^cC0*5WNS!0Bb?q!g!tmpMf7hB}CK~CVB-lHFFqU7@p8| zO$dae@kz6fML&xxwUni6GQR}W7FCWe)#vzg)<|{*kC|Ohn}Y-9rJ0FQbLi?&?`87B z)K;(RMFt__%xD5HOoZa)+oE7XvBbqjoUGIew2|}vL~pAapaTLhfB+B#nt%`x2AY8g z&;qmqZ9o(tvf*#T--f>pe;fWb{B8K#@VDV_!{3I#4SyT{HvDb)v#)9*6s%wL2|axS z4D>ZTIx!utwaUF}Y%prByl+y6O!=Aqd3+Brki>A9@~gS!TqeDQx41}$d@*$)N^yLr z13?i7IkaNH;N#2!Nv6%u9A_QfL>4_O>ji#}?> zN8M^vIZc%-c%sM_vyjs{*ol=nzr`iszQtnK-R-$*#YeS#)UuCixi&YltY?pEWQY}H zJ*ZY};9Evr6w5odO}8trzs+Np%YPa`mXnm_h`MreZnRBhQ-QW2N>VS$Yo%kE+_+&G z7hLa*7*&@E%=K8YjtQI=Z+G?=77u*Xe7(BSzy$vBs0j|mzxVZ#}7mhi7ezp88yYpNGVWSyP3?=s;x17wcASW1?|Ojz@YmUV2o zI&vuv$aonya!w_3V+Unyut91Tsh|FohMRX;%t2V**4h2b<0F-T5@MF^cUVlz%W_+9 z^lX3kSXS~vR)V33+wS3_yE~Ijs<&7yG>*Y Date: Thu, 27 Nov 2025 21:08:51 +0300 Subject: [PATCH 08/26] added text before part 9 --- loader/samples/minexample/minexample.s | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 7190027..6d1cfe9 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -447,6 +447,19 @@ code_start: ldy #$01 jsr txt_fade_out + jsr init_bmp + + ldx #4 +: + lda #0 + sta vbl + lda #60 +: + cmp vbl + bne :- + dex + bpl :-- + part_9: ; $0400-$07ff buffer 0 tilemap ; $2000-$3fff buffer 0 bitmap @@ -457,6 +470,19 @@ part_9: ; $7800-$78ff tileset tile colors ; $7900-$79ff tileset CRAM colors ; $9000- compressed tilemap + + + jsr clr_txt + ldx #art_direct + jsr write_txt2 + ldx #$c0 + ldy #$01 + jsr init_timer + + lda #1 + sta timer_mode + ldx #islandname lda #$70 @@ -468,6 +494,22 @@ part_9: ldy #$90 jsr LZ_init_decomp +: + lda timer_reached + beq :- + + ldx #$90 + ldy #$01 + ;jsr txt_fade_out + jsr init_timer + lda #8 + sta timer + lda #2 + sta timer_mode +: + lda timer_reached + beq :- + lda #0 sta $d011 jsr clear_2bufs @@ -1651,6 +1693,10 @@ scene_writ: .byte " seigo oketani " .byte " yoshihiko kurata " +art_direct: +.byte " art directed by " +.byte " seigo oketani " + clr_txt: lda #$80 ldx #0 From 8649775d964430c3c4f8dbe3889e76d8ec010b9b Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Fri, 28 Nov 2025 02:47:40 +0700 Subject: [PATCH 09/26] Island transitions, more text --- loader/samples/minexample/minexample.s | 376 +++++++++---------------- 1 file changed, 133 insertions(+), 243 deletions(-) diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 6d1cfe9..079a5e9 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -109,7 +109,7 @@ code_start: ldx #copyright jsr write_txt3 - ldx #$30 + ldx #$00 ldy #$01 jsr init_timer lda #1 @@ -123,12 +123,9 @@ code_start: lda timer_reached beq :- - ldx #250 - ldy #0 + ldx #$90 + ldy #$01 jsr txt_fade_out - lda #64 - sta frame_delay - jsr wait_loop sei jsr set_irq_badguy @@ -169,7 +166,6 @@ code_start: jsr init_2x lda #$0b sta $d011 - ; jmp part_11 jsr clr_txt ldx #art_direct @@ -500,15 +489,8 @@ part_9: ldx #$90 ldy #$01 - ;jsr txt_fade_out - jsr init_timer lda #8 - sta timer - lda #2 - sta timer_mode -: - lda timer_reached - beq :- + jsr txt_fade_out_offset lda #0 sta $d011 @@ -606,7 +588,7 @@ part_9: lda #0 sta vbl lda frame - cmp #$e0 ; TODO + cmp #$e1 bcc :+ jmp @finish : @@ -642,10 +624,18 @@ part_9: jmp @loop @finish: + ldx #$a8 + ldy #$01 + jsr init_timer +: + lda timer_reached + beq :- + lda #$0b + sta $d011 lda #0 - sta timer_mode sta $d015 - ; TODO is there a delay here + lda #3 + sta $dd00 ; we run out of space before the fixed location vector return now jmp part_10 @@ -714,12 +704,7 @@ intro: sta frame_delay jsr wait_loop - ldx #empty_txt - jsr upload_text - ldx #empty_txt - jsr upload_text_bottom + jsr clear_text lda #$0d sta frame_until @@ -736,20 +721,16 @@ intro: sta frame_delay jsr wait_loop + jsr clear_text ldx #too_bad_txt jsr upload_text - ldx #empty_txt - jsr upload_text_bottom lda #50*5 sta frame_delay jsr wait_loop - ldx #empty_txt - jsr upload_text + jsr clear_text lda #$13 sta frame_until @@ -904,14 +885,12 @@ irq_music: bne :+ inc timer+1 : - lda timer+1 - cmp timer_limit+1 - bcc :++ - bne :+ lda timer - cmp timer_limit - bcc :++ -: + sec + sbc timer_limit + lda timer+1 + sbc timer_limit+1 + bcc :+ lda #1 sta timer_reached : @@ -998,23 +977,6 @@ wait_frame_until: : rts - -wait_loop_2x: -@loop: - lda vbl - cmp #2 - bcc @loop - - lda #0 - sta vbl - - dec frame_delay - lda frame_delay - beq :+ - jmp @loop -: - rts - wait_frame_until_2x: @loop: lda vbl @@ -1036,7 +998,6 @@ wait_frame_until_2x: : rts - init_bmp: lda #$0b sta $d011 @@ -1288,29 +1249,15 @@ cloudsname: .byte "clouds", 0 darmtower_txt: - .res (40-32)/2, ' ' - .byte "darm's tower has fallen silent. " - .res (40-32)/2, ' ' - .res (40-32)/2, ' ' - .byte "what should we do? " - .res (40-32)/2, ' ' - -empty_txt: - .res 40, ' ' - .res 40, ' ' + .byte " darm's tower has fallen silent. " + .byte " what should we do? " adol_win: - .res (40-28)/2, ' ' - .byte 34, "it must be adol, let's see " - .res (40-28)/2, ' ' - .res (40-28)/2, ' ' - .byte "how far he'll get!", 34, " " - .res (40-28)/2, ' ' + .byte " ", 34, "it must be adol, let's see " + .byte " how far he'll get!", 34, " " too_bad_txt: - .res (40-16)/2, ' ' - .byte "as you command. " - .res (40-16)/2, ' ' + .byte " as you command. " upload_text: stx text_ptr @@ -1340,6 +1287,16 @@ upload_text_bottom: bpl :- rts +clear_text: + lda #$80 + ldy #39 +: + sta $748, y + sta $748+40+40, y + dey + bpl :- + rts + run_nufli_bmp: lda #$01 sta $81 @@ -1433,9 +1390,28 @@ part_10: ; the sprite data is embedded into first few bitmap pixels ; which are hidden by black border attributes @y = $60 + jsr clr_txt + ldx #total_direct + jsr write_txt2 + ldx #$c0 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + ldx #cloudsname jsr load_8000_zx02_2000 +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + lda #$40 + jsr txt_fade_out_offset + jsr init_bmp ldx #0 stx $d010 @@ -1547,6 +1523,11 @@ part_11: jsr load_8000_zx02 cli + jsr clr_txt + ldx #turn_disk + jsr write_txt + jmp end .res ((*+$ff)&$ff00|2)-* @@ -1697,6 +1678,16 @@ art_direct: .byte " art directed by " .byte " seigo oketani " +total_direct: +.byte " total directed by " +.byte " masaya hashimoto " + +presented_by: +.byte " presented by falcom " + +turn_disk: +.byte " insert datadisk in drive 8 " + clr_txt: lda #$80 ldx #0 @@ -1725,190 +1716,84 @@ clr_txt: write_txt5: stx text_ptr sty text_ptr+1 - - ldx #0 ldy #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+8*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+10*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+12*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+14*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+16*40, x - iny - inx - cpx #40 - bne :- - rts + lda #<($400+8*40) + ldx #>($400+8*40) + jsr write_txt_to + lda #<($400+10*40) + ldx #>($400+10*40) + jsr write_txt_to + lda #<($400+12*40) + ldx #>($400+12*40) + jsr write_txt_to + lda #<($400+14*40) + ldx #>($400+14*40) + jsr write_txt_to + lda #<($400+16*40) + ldx #>($400+16*40) + jmp write_txt_to write_txt4: stx text_ptr sty text_ptr+1 - - ldx #0 ldy #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+9*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+11*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+13*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+15*40, x - iny - inx - cpx #40 - bne :- - - rts + lda #<($400+9*40) + ldx #>($400+9*40) + jsr write_txt_to + lda #<($400+11*40) + ldx #>($400+11*40) + jsr write_txt_to + lda #<($400+13*40) + ldx #>($400+13*40) + jsr write_txt_to + lda #<($400+15*40) + ldx #>($400+15*40) + jmp write_txt_to write_txt3: stx text_ptr sty text_ptr+1 - - ldx #0 ldy #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+10*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+12*40, x - iny - inx - cpx #40 - bne :- - - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+14*40, x - iny - inx - cpx #40 - bne :- - rts + lda #<($400+10*40) + ldx #>($400+10*40) + jsr write_txt_to + lda #<($400+12*40) + ldx #>($400+12*40) + jsr write_txt_to + lda #<($400+14*40) + ldx #>($400+14*40) + jmp write_txt_to write_txt2: stx text_ptr sty text_ptr+1 - - ldx #0 ldy #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 - sta $400+11*40, x - iny - inx - cpx #40 - bne :- + lda #<($400+11*40) + ldx #>($400+11*40) + jsr write_txt_to + lda #<($400+13*40) + ldx #>($400+13*40) + jmp write_txt_to +write_txt: + stx text_ptr + sty text_ptr+1 + ldy #0 + lda #<($400+12*40) + ldx #>($400+12*40) + ; fall through + +write_txt_to: + sta @dst+1 + stx @dst+2 ldx #0 : lda (text_ptr), y sec sbc #$20 ora #$80 - sta $400+13*40, x +@dst: + sta $400, x iny inx cpx #40 @@ -1916,7 +1801,12 @@ write_txt2: rts txt_fade_out: + lda #0 +txt_fade_out_offset: + pha jsr init_timer + pla + sta timer lda #2 sta timer_mode : From a38269cdf075cb1b96ccbf8189e50cbc0e209e62 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Fri, 28 Nov 2025 04:15:00 +0700 Subject: [PATCH 10/26] Finish clouds transition --- loader/samples/minexample/minexample.s | 124 +++++++++++++++++++------ 1 file changed, 96 insertions(+), 28 deletions(-) diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 079a5e9..0bae604 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -20,6 +20,7 @@ timer: .res 2 timer_limit: .res 2 timer_reached: .res 2 timer_mode: .res 1 +enable_music: .res 1 temp: .res 3 aart_lz_buffer := $fd00 @@ -99,11 +100,8 @@ code_start: lda #0 sta $d020 sta ZX0_dst+0 + sta enable_music jsr load_font - ; we don't have the music player here yet - ; so just put an rts instruction at $a003 - lda #$60 - sta $a003 jsr init_2x jsr clr_txt ldx #fake_kernal_irq sta $ffff + inc enable_music jsr run_nufli_bmp sei @@ -395,7 +394,6 @@ code_start: ldx #$10 ldy #$01 lda #8*11 - sta timer jsr txt_fade_out_offset ldx #$c4 @@ -777,7 +775,7 @@ init_2x: sta $d012 position_2x_to_display: - lda #51 + lda #50 position_2x: : bit $d011 @@ -850,7 +848,10 @@ irq_music: inc vbl ;inc $d020 + lda enable_music + beq :+ jsr $a003 +: ;dec $d020 lda timer_mode @@ -1389,7 +1390,7 @@ load_font: part_10: ; the sprite data is embedded into first few bitmap pixels ; which are hidden by black border attributes -@y = $60 +@y = 93 jsr clr_txt ldx #total_direct @@ -1426,6 +1427,8 @@ part_10: sta $d026 lda #@y+48 jsr position_2x + lda #0 + sta vbl ; draw top half @loop: bit $d011 @@ -1433,10 +1436,16 @@ part_10: ldx #0 ldy #0 lda frame - cmp #200 ; TODO - bcc :+ + bpl :+ jmp @finish : + cmp #$74 + bcc :+ + lda #$74 +: + pha +: + clc adc @sprxs,x sta $d000,y sta temp @@ -1467,7 +1476,7 @@ part_10: ldx #0 ldy #0 - lda frame + pla clc : adc @sprxs+8,x @@ -1485,15 +1494,18 @@ part_10: iny inx cpx #6 - nop bcc :- + lda vbl + and #15 + bne :+ inc frame +: jmp @loop @sprxs: - .byte 200, <-24, 24, 24, <-64, 24, 24, 24 - .byte 200-40, 24, 24, 24, <-44, 24 + .byte 48, <-24, 24, 24, <-64, 24, 24, 24 + .byte 48-40, 24, 24, 24, <-44, 24 @sprys: .byte @y-8, @y, @y, @y, @y+21, @y+21, @y+21, @y+21 @@ -1504,40 +1516,84 @@ part_10: .byte 2, 2, 2, 9, 2, 2 @finish: - jsr position_2x_to_display + lda #$0b + sta $d011 + lda #0 + sta $d015 + + jsr clr_txt + ldx #produced + jsr write_txt2 + ldx #$c0 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + lda #8*11 + jsr txt_fade_out_offset part_11: + jsr clr_txt + ldx #presented + jsr write_txt1 + ldx #$c0 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ; ldx #liliatalkname + ; jsr load_8000_zx02_2000 +: + lda timer_reached + beq :- + ; tell the music to end and wait : lda #1 jsr $a006 cmp #17 bne :- - ; load new music - sei - jsr set_irq_badguy + ldx #$00 + ldy #$01 + lda #8*11 + jsr txt_fade_out_offset +: + lda timer_reached + beq :- + + jmp * ; TEMP + + ; load new music + lda #0 + sta enable_music ldx #song1name lda #$a0 jsr load_8000_zx02 + + sei + jsr set_irq_badguy + inc enable_music cli jsr clr_txt ldx #turn_disk - jsr write_txt + jsr write_txt1 jmp end - .res ((*+$ff)&$ff00|2)-* -end: - ldx #fontname - jsr fileexists - bcc end - jmp code_start - clear_2bufs: ldy #$44 .byte $2c ; skip next instruction @@ -1682,7 +1738,11 @@ total_direct: .byte " total directed by " .byte " masaya hashimoto " -presented_by: +produced: +.byte " produced by " +.byte " masayuki katoh " + +presented: .byte " presented by falcom " turn_disk: @@ -1775,7 +1835,7 @@ write_txt2: ldx #>($400+13*40) jmp write_txt_to -write_txt: +write_txt1: stx text_ptr sty text_ptr+1 ldy #0 @@ -1814,4 +1874,12 @@ txt_fade_out_offset: beq :- rts + .res ((*+$ff)&$ff00|2)-* +end: + ldx #fontname + jsr fileexists + bcc end + jmp code_start + code_end: From 48569fe24598a62bfbc4e1c733802d095ebc045b Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Fri, 28 Nov 2025 15:15:49 +0700 Subject: [PATCH 11/26] WIP lilia talk --- assets/ys2/11_lilia_final/koala/png/01.png | Bin 7270 -> 5083 bytes assets/ys2/11_lilia_final/koala/png/02.png | Bin 7294 -> 5092 bytes assets/ys2/11_lilia_final/koala/png/03.png | Bin 7305 -> 5092 bytes assets/ys2/11_lilia_final/koala/png/04.png | Bin 7355 -> 5080 bytes assets/ys2/11_lilia_final/koala/png/05.png | Bin 7301 -> 4997 bytes assets/ys2/11_lilia_final/koala/png/06.png | Bin 7182 -> 4933 bytes assets/ys2/11_lilia_final/koala/png/07.png | Bin 7075 -> 4857 bytes assets/ys2/11_lilia_final/koala/png/08.png | Bin 7320 -> 5079 bytes assets/ys2/11_lilia_final/koala/png/09.png | Bin 7264 -> 4983 bytes assets/ys2/11_lilia_final/koala/png/10.png | Bin 7148 -> 4921 bytes assets/ys2/11_lilia_final/koala/png/11.png | Bin 7031 -> 4843 bytes assets/ys2/11_lilia_final/koala/png/12.png | Bin 7290 -> 5062 bytes assets/ys2/11_lilia_final/koala/png/13.png | Bin 7290 -> 5036 bytes assets/ys2/11_lilia_final/koala/png/14.png | Bin 7200 -> 4985 bytes assets/ys2/11_lilia_final/koala/png/15.png | Bin 7092 -> 4924 bytes assets/ys2/11_lilia_final/koala/png/16.png | Bin 6998 -> 4840 bytes loader/samples/minexample/Makefile | 6 +- loader/samples/minexample/font.bin | Bin 517 -> 529 bytes loader/samples/minexample/lilia_talk.bin | Bin 0 -> 15108 bytes loader/samples/minexample/loaderconfig.inc | 2 +- loader/samples/minexample/minexample.s | 169 +++++++++++---------- 21 files changed, 95 insertions(+), 82 deletions(-) create mode 100644 loader/samples/minexample/lilia_talk.bin diff --git a/assets/ys2/11_lilia_final/koala/png/01.png b/assets/ys2/11_lilia_final/koala/png/01.png index dab148d28600641accc0dca2ff848913bd6242d6..885dce51bbf155c12d5fed8702c881ffcf2d039d 100644 GIT binary patch literal 5083 zcmcJT`9IX%`^Voi22)Zq_OgvZ-9nVT>|4l|wTKZ#){))VrnwO#BwMH^m62^w84QMm zq)?W|Z7?^o@B1>A&wT!a?+>5vFXx;e&f}cxT#wgvo#%BWTU%b|K6&mW007*kCWbZu z0MccxJE0t`F%P0%#+pFEHrMq5Qjf?S0Ptp;8tU0ayjXha^2D`05}W?n`=Zh3Y%`gf z_$WPdiz>C$K`3tqSJ$u`LVC`K_fJ=s#i^QbcCs~}Onqv6sVcTnJ-J@OK~CyY=_huy z`yxcf9wZ&)mb%7quEb1g{!{k3n?`21R7vW`mD;N-u^Zhlf<32yXl!VzJw7~Y`mW79 z>i$7_^VcOo05}_DL=y*q*Rn7KaE}WN!TRZ8fv56N81R7|1lA=Zbb(F*2o(4S2Y?XH z|L0BL_enY}*3aq8I~hEJaq9^Vy>Z7i&GP##MGMP+9ZxQe-W)?ukBg_12#oEbwRx%SoDX%eY#w_R*RRvg@aH`o zbk8!eM(Sj)zD6N*g&>7UJ?E}6iHQY4D9o)-p@VcIyHa|hA88nI$N_4tTFp8c7vbsc z-X-hUrgjR3Xvy+?Oxlv5-hBjcc04{hZpOb@v*(JA@%9X9idZ*OAaM0TKses!`qe1j z88(aB9eMto&UC1P0t^u$aT|UWx4RAj>9adN@*e+2tLHW`Xx78BNo)h31n#3GbvlJ1 z(A1&B_J)fn1??brcd4OzA;}8ZqgWhJC_uE^Npv}rO7cn<9lv(62?WyrIc>}+kW}=8 z{j1vYF+DZa0)XRRE4xU%k!)Uya}BTz zTy9OrTs|{Pc~t5x|3NbjwKfG1PD3C=!DEdRBeRsf(E=R)yZt@l@XI60^0S7CVPs`z zCDhqBfd?|QG5r|5rZTm^gnmLozu4TsIAx_u>R@FMx+c#C3dH>gDlGpFOn6xx?#xo= zf@xA~FBeLk%fH@ICMp>sFS+0qYHlc1A0K=P%m z@3lK#-A*^Z@RV5JV065>cq2MB!@qh=eeb#LyYn)Q0+f}az+6@HV@;~J@Gtm@4iE?< z@Jidt;ki!an?a|WclWF#4~K75rjp`nJ$#E>mF|{q&E-%1y^~YZVSk>Bw1o)yx5)qe zcs>3p(Nqng+xt9LFG#!qwkFziOzm27dXRp+QNVwBEMy5KHONg)#`BR`y0kL+!u{x~=6C*udve0sfzoUIsb*coy?-3#izsD9H+<@#(WyzKAytxMs{{m7*AC z_$%ywayfKwE>HNpaWo}w{fPhb{MUNp*b+JajqFw%W(pU0^NFvN*S@&cAYZA!+R!Ej zXBds7hILGoPoZ?=Xy59w>=kW31?8znl6!zhFBzZNB+<`^6R$mMOmvJEgMMta8{|t>f(MQ zE!WddhTR5LZ15&R(uD@$? zW$5PVD+8c# zF8FB<&F@j;w4n;}uzy=@h!i+M;6-`M(*VE1Wt6{zAL&V+N$LDWs#kjM4NiiVHp3(u z({AE7kG~lki?OJ4Ra&Nmi5y^os16^<8jiMHnFhIk$|!*5A&Y#y(m1rdc(MdUGQBO2 zJm^U|lSWEOe_=vV^-9@=x%}6-ke3q_B%Hx5OAB`h5bvFo$v1ZG`%$-%^I_U+Vs-qB zCFjSlPHc-8jc+ehI6gyAl=ZN$)>L)`8$6}xjukx&eqKqP)OR1q`L9lRV_sYhEe)!X z$Y7A00_f;^M%=H7cro#b6H=C*J)$)C<=Cf z?9$4qq!NJ#DF+?CiQMVV$JKPF3J|%7bX8xfedz*Jk%womo@h-Z-FF?UQMyGxHP z?ImUSOXjjgb{1tCK9Ec@4Q#yiT*G5yV||niDT95VlDXjwMO|!$qKcAvZNm}n@GIx> zyC8F78Pq5m*?M8yLHvS#bnutZw+kL|Ovh9khq?V>q)wz(=BoMRRlr{tD_Yb-L`J>u z)TaS4gbO2l@K*u^c`#%Z1bz}aeyi&lKgGQ2dncjHHQ5MC{zz9F+dNS z5idk};94v2Kp&~=oe1q?7r4`Yp_Lcpa}VpJcGItyjdk^=;bOik-LCG^vo}6#-|C($ z^mLO=erA)@46t{xfL8y`8q_qQlA(RA+M(E%amd`U;vcRf)_qx-5t(1hg9$>^73Ybq zSC)|zW%L@YAj9~%-{vL4dl@GUOjt^PY8Np+G-~N_sjP-t3JsOFMu#CRxJ)0#6p_d3 zeX1L&7D|xcIDiws_`ycq7)OG?hFVf;!plRF+2P|EN`tf;mQMg^VBIV+Y0ml`v7|~D ze=;T!8u)Md@yBLy7puy5ZN(`z@wE(O`um>4ynG4300Q!C9T}S`^|-QPiFOz;x{jOl zuL+23w2>XyNB~@LfYNnU?QGl89VdEOL>{J|l1?DbfwWmDU=a59 z7ZXm_DkgjXIY04i)Omh+XNEhc?K1@C=4MX!5Ivf9$(~fApX`#-Mk)Izn#9*KQ7k+C5?;Tz+b_QI4RSQ zS2~2zclIie%YR6_4!0zhY5WbaUEWwtFCJ6KV9fXYa^#2hzigv5^hkYK{d+f1`+ysf#MQT9I%sD_|PXzKW5f`$d=Q4LGr4n8~2JO^$QHG>Xf6E>r^LKL7M&Y@z};7u?w}_=s(Z= zRU|3^ttvw|4tst}tVC(bKe3+pm~36#MH*P*NZI`a%M}zCb*UVSsSnbT@peVDq&>** z@`0;X7}eu@RoX|%wZrB=;V=EdUbj1{t@{?7Oo7$%J?^SZDMhR>ed>QL^gk~3&2)J< zdP1a+l?aOHvNcT;qjLN8Tx^`o@Uv-=Si8k*k{-?ccR{kFD$>ll*1a`_)W z)w{;ZhbB$N{63uC{h)>3Sby3qNCxyF3Pa4itYZ+}M!Z95)Hw``q>V zBR8A?y-5|TY}+H!nR)Tk7k}Cz_eXTGKcS;r7Aougxc;Glxb?-&Ny`QO3Ko#Ky$OzU zxhov?%PVwKWj)x4qp0BI&m1$}y-+T&xnZ=6LXKLpRlW#WLx-2z;X3^L;Lfj-s_2Rt zwguxL!&nxIN)}oPUW;hdw2%{6&iup8IEn*`jw zTllQc%?-8q z<>l2h&}bv!(8d}02;eO&fqE31hf01XeRYmj(YaGCde<%Lm1UuX95fJN@<)vi-a*<* zFy`vc;*q4*vCx0l?7l6d$4nBp|G7CA6*sX%KXF-QEwAIj{BQ6AetF_s(4-@j3w$cx zzg%K-=u3(16h5Iowb#f3RA8J~lB|&R(@*wq80yX#U91-K7g%{>ed@dAL<;c0PZBls7!w;VOr@r=nz%codBgS(kopCy0%@Zz8=3l|Nr2?9&5>ILh^g(B zrK6)Z+uq-P?BciMk*bl$R)Pf5h_;=dyJX)DHpp{msHC>M;q7WrUW3wQ91J0Ie&xMcz> z)H8v(xwoB*&l!FVRa9|T;WzI-*FTvg_m~~Lc!J7V9BTHWOQB8x^}hEl<9b_e*A8fc z#WBCO`f7+9F;{s`jf$R@rV`>W3F z5xRo(t?!czGh1|yrnYOPCEZWs;b38y`KTzifY?*0Y72XGNg>fR*RS{L|c;Lfh*U=q_R^eW8 z4F2cuMl{mJ+2_$A7=-DdjjNIEoKBhr=T9wzAAAZy_DX~{jV0wV?#(i__G&aK@7dD`W9*_jPQBjtA$AdlLdR` z^k6rOZoWfG(82V2;S?S#1wN(KTU^_K7d<LDemqGz3Jh2ucP~1c!2J+*jlf( z<#ZR@TX{d)ZtP-7sTWd{ZS$BeL=75z$o{W=__K3`?43!wY@6XoQ`Q>UGSAB&ub9g} zl=rfFS!Ai^`Nk#5wEeMnOUt6r4pU*<+`Wa5C2>JEh33J! z|0g<%Y1&RVx+BIka`4=h2QHjp^^D=GhLz#lC|dHD4d0wMT%x(~7AqTeCXFr0R8L?@ zM#RXnUEjScGcC@@P&74@EfYJu+N#fjDcwUU&ZM~%w~LB0-SO)!zY(D)yTtN zFwIJ2FT6OVT_#@8X_IEQvCxf4Gg{-h@a+iGMZ`C+bK|cub3)$te|{1M-U*zZUKPh4 z@Xd3)*_vy^Y1VCcSE5;Z^!c>LBmH%(;12Vs0j)=u-dpNjq`7DaJ}#|r5D827%9np? zmb-s*!n|Q=^sa#`97siBu;LCf1Yao2Qj|Ftv(y{yLGt(J+T~4gm{8kj(B`Z zsnXI2ma$E+a+~pp`8uTou^9$n4I2i(#<fkt1*;s7=CR5L3#h#S zEr}L+uX;#%Zm_WJx*+p zY!e(bzt~-r_+?3^TNKTX8DfO)%`DB*t7)nkaTVQssH8#E{REiWe29|jo0olBujVx5 zlU?teAW0rwUqM4I+5Y@M8r(UOCdlNo76_8w8Ct2R@7_%IGoN3&;2z5XRIjTM7z}J$ z4%9LB#-A5Fr#kqnK0}^2lCPMuGu}cKbEodh5}6$d!WxR3HI=Wf-K-Map~4&Fma#b) zxWQAnoz?X1TIHswuLRb_^bZ>vQ>Q-T^g8=2i2{EV5O_k2s6IIok3`-1nWNbO?g7Wh zz0(=!JAgId%B}m;?K0esUE@jFd%DfUzD_BFjaCl-?&x_0`HJ#`_epvP)?t~p0^oxi zBd3zTgeK77%MnkL*7HUJDDJu==o5@hsjm>Bgc zcD5S7zzU^$!uMNa*h;c2dO;{HA5;b3xmgiEoCBno99y)LsDlvsdxfd zTP&TCW8cM$)4@2UYS>xdp}RF_Yf{~vA>&R{8w?%?1+2^5vYPr*PMJ`6-ynEW$!|LLZ%vk1bB2#f_FXPYz$lq z^tB^@o1>s3Z#mr`HoLT2^8V|KM}A?tZu(6 zfQsun$p>`|{i#rE`S2z2l1iq>F_?NVP4kPrHyFs-l#~?Z zw#t!bGaEU^H4duK<)EHp)W1nX=c7D+Y^Dd+5#qs>mV>o%C)tm(ov1}GxXQ1qU$xcX zS(B5KxR8(#MzDVJ%idm+{iQ`ca>boHN$+{G>m~TOP?3OkxK3&5j-7(6VICLTm+^z* z0#F5fkm4p6G8s2sc)dlI9rZjsJUIDRd{YV__y%j@M7y?$Q8h8V7_W{KZ4a5@l#~y; zHbM&h513H4zP^_z%NsF=(Lws7P(Rc?gd98lP>Wk9c~GjWtILWArHQkgH&zhYe8`Z& z3RSU9{zQ^ndXMVj7EJECL^GnCuBort%y2DwVX^voEJto}6$#$JhKg~0vyN-K?46uk8=)yb&gWYxmWP4jomwWf1H95x zTDoS_{{xv-`|X!g%f7B|c}jrBL;4$>>*C)s^~xs&YyBK6O(Id{{Q2|j`UmZ5C!#}S z@hwlK=-?EKVWkF12;XDUg(kw_zC3vr|3EVIN}_FZGAZM{OyCKfg$*Qe0PjNJj4Nr+ zp0(V95>0Z&&6^}04PuolOv%n+|2!UaAfM4L7k2L$`{w`*BfvcxvKLB%~e5={IWXR}U z;w9^-w3lYkg%U69=~m_ykVm8>h-;X)R&dQSGJbAL*Cm=w0w4p1~kTE50G7UyJ?+3%jAGP`i`Vo^4RboB_Ta4C4HM42Fx0xQ;ei+x0S zE>=WS5)HBM5G@ARI1>}Pl&zt!Nq~?7>H}H!DO8d-Upi6)D{>2sB>pQ9zY z?xt(v0P7hk3(X1U_VWXMtLU@M1q?~kmsaq!>Z@0;aL0}vQ{NFPtRZdHM=0$XGqm}f zs->dk zPz6jLUX98ze?gIHq`7p53?#;pwKrb+T$3LjnOBN0PeuT2X=zbDMW>_BO8oBqWz!w) z6M=Qnvo3W1JjaZG9Ciavg?~7wc?(iyjp7xsZy&xyEFl1%QiI1087P>LS7(ibKrn|P z^oWOQ!+6#!X_21gKkRewucYn%RXFH78%nQT6A%0FoX9C0cSX|p zZ9O3sDti3Y7LkaAXeQWIkC2jMyS7HX+rT(Glnkv56q~I`Fc9hcmy~3ER$7yj#iW+m!_z-WXN7Fgumzf=ADiAvnw+ z@R&gj5G_2D10SE%yA%^MlpBfqIHTDW;s?cD$PLJIT;sb}1||Y&W>wsG{Dk39tKqk9 z#Rtt5QG7u_;W>#>JpghDwD^w2xi~c45?E&owg?}^|9#%cSm3ca@<}V*swBWSj|T;V zCjHS2Q{Nm3?oYK`btqz>F&VwF{XdC(=Z*#;GDdg+#I5SBcTWiVP@Q+|hdq5heF>Ie z7sSV=SBK`_MO$R<R;1 zSm?FQGvQo-K60?N-isoNh}halz6AP5DAn&j=$}{#7j&*Y`((n6vG4gZ7I12xgZ@jQ zdDI2&O)Ycjo+?2EZtG{n2HDCvi(37v4Kimmc!^=5Euuk7ltVj+xoredkDP*ko5ND z(EI%B>N*qo)YDK5lgvDje;NW>4+YM_%>pFY0q~$3n!>hcmGY?WV$9M+m~FB?eW1lQ zWc|a0xqG2bgiWox&eDQb0$R{a2jFDLLa#sAOcv0${sA&G_e1eV8=u4i6rUd8`rtjk zy6wxXI-w0cTYlrl4F=SL{6oHgVGnxeoypKHPX;QEv>XU0D54<9AJFA@2HS3E;Ua)! zv3o+j^3x#RlOcHiWTKAIizD&-jxRQvV-ZmY&V5p*ngkNf$V8a8D`JmH2Eytg0rzNq zb8EzTa#U5G3)G4+(i*G`yp0X(1U6DqGS%$#r)GM~1oWHUY%|ev_cw!q1PisNS4B|~ z#Gna%Vt5Q1HQ;hY(;08yD1xNPbEDIYr2jtu)El|V*FB)Tq>9ffQC7iRK)|Q;oODF0 z2E7*no^zBl6@c+x(uFqFyH8Xs#z-EG`|y#6?G#RdXoNOVIwK41+DU3H<3&wf%@8#L zQ3_vuhOK`Udp*nrRL)?Hj0RQG-K}>?#78IfNtKDJm<9yNk5&dqbYW~CL>YA+22(ws z=Ia)qXuvX~FimnXP^bd5|8|MblqyG85N=&j!aP!?13h313{xG^j%bpMA!)l};R5F$ zMi(#v!_TJ5R2q~H`QVcMCjlliAa5g@QoN6}5EJB_#` zzm1W=7mYLE1y#)C(@w~tMuh|24Z;|-ZE2yz!~6R7I2C(e)CidGESD@|c4J*}WKu_H{JapfPb57d9$;G}A{HAooxqkM z%?fl#Qaez_M{pEXJSArCH&nhH$%Jq6l*P|OUdl)g6ru}51LXF1+|z{~!tSU8K?%ij;r_Ru zGVDF$R%uWE;1BQ#o9=h=Do8V(dz^`~yx&^#((A(PExF|NFOD#_^ zDB>zq7?cc5L7d3qqznU*X>=J-{A>N9bp3w3?c^d~P%z&(t zjALVD!sbJ39sWQELyDg*$3ll>v??al`JqE%eb-h`3$$Eu^n7zzcI#CoRqN~XQuwqX zbw!g0cDwtDz=N#xUMx=bZ~}qDp`+;SKt-1~9$8&G^K~f))h$sV{vj0=m9QNFg^aL+ zlp@R1Ej7+`)z|1 ze&0rtfL}EILw6Di&;84_?^ir54~>p}u(>#m6`C*q7^W1aqOpa6;R<*pIcnN#`}PlIrpb3@G_d?Woi~X^)(r-3)n>CJV1sLAz5rBs6Ld{o_WvX zS-|52(8xH|b+shu&|jGl8@`VZjX6-vh7L8;Bc_&63hZ>)e!zMT0r)G(6YJgQD`Aa_ zdentBS4nT9v)hXd*Ze2C5afJEEr=(7&4ISbSie_;;PC6)<1G$tc#(~tTa$jra#G0k z$#b&+gH;{YRIK?pCVmG9^z5_`hDaA@XJgZKaIh8IKiEioR)I#$8Ejim$ST^1MUq@n zEypgxwuHQrE52gTZ*6pJuMh1%0VcmUUmNTg#NQl$#HyMOSqLr`$8d6S0Ahk)Q#9Ub zdDxgtJ$y(~fS-tOa_n7EwC1pti*=!fDc8?vqvKi0sBHyaej9U!4c$W-JeE+kAEI1q z<}Z(6#_~7#sr(BtEU`HxKm`~^2Ps%xXgjhRMfCa*V`WElDYReIiH!`!IxDdD5VlyGjo{=y_UgR z_5_%O@Q?u*A)OrF7RH~}Z<8!RZSf{_oGUT;TUihEkzt}9?BO#r_ihF2$y(Ipucp#Kw2*{#r_HAzXtp{#1NlWtO#cY;IL8D z1^7g5)c|XaRBqqG5-?zizzpL)3=B6NeTD0{Slb1L7%LlHoe+5ZvUg!OC+Eh48r|jQ zX5rUJNJ~7%*=SfzM=|nP=Zl)SK?LY)i!lW>_rY&?DR2Wi7KH6qGSD&5w$Sq_;d4?j zACUoaw~;@bNPu^$fGFJ?*ic{(`sexVfUU*tcSmGl&jmdQ?J>Onj#^QX)q^gI+g*v_ z+Q9>{o~$BG_x+Yg;lqt%UZK>8OgZz)VJ2eN?S#bv`e8g9Bd`Fc_%t%Ig3i8k5fP`a zkg0;;+{#1wscr&0Zs_8EBK|7TOrxv%dnF5*LFOx%E~Qp#&bB4e8R#D()FtpC<$w9Z c#kDyfZoiis`)~~Ye<);Q&1KuB=_m^|dbwKmGc>w?bzlAx{ z4gdfeve#W;ZuXc9(kW+8z%V;AV?gD1=|uoQxX1!&qwoVE*7Z z-(<(|3A?ud%inF1v-}!%&n!E9RWx4`21KOHu=BC4gVDSBg}U?KzU7Afi4GDtV8!Od z?XdE5!%eTbr~v@ye-kPV002WY+z`+u1_A>{5&=NCGXxIs=Hme20*r8gC#qlwpq2~B zVMzWz8)Y+G6L2N!^}8d8f2kcU^HmfbPx>FXE^y{lj=3Ivc8-17JoU}QK*rUeb;Zhl zEn#LEO`N1|XUGL^$Mbz&_1nH2!U;64YTPuSYE#@ss}%`MYo?f72M{QbHm5Bo;cDRE z{mC))8p0^$(7OFW{C$8YB#8hDRH}N2uX2YQ;(S}ho75bs*?5~&$TUL=1pe4=uY5S2 zTSiiDRa z&bm-gV`8%2;ReD0(cEl^`<3i%x&WT}%03r$;UXq0y3cFD`B~gRfuv#1A5PEW(huRm z5V*#zUf9|@YzuQeg_P+re=F_1F=+n;N0QTXy9ucXJsnDsUPRK`>1}Qh*eG8rF8Fa< zwGoa}es|9RcM5I@wxngcD^GZ|kT|TCegc3y1;Z2W6Njfml<0;Gf!z zXhj56h+493^5v+Vv}g4CR(%RJ{%0@U_nOw@L%8+|v8>@?4=jhwptr>?Dh|Z*`l0{U|?p)5(53rsq!8m`fQY@cOdXdB!Zn zyB=;RE>d!`or2=c7Y{G(ivD=d2&Y%2T9szAQ|1Dz3b#9};=f-^G*i%Sq6f$8GeE zP*FM9HxI+fv7NREQ`oIJ0iEhQSS5{DChrVKPQJl!5dDu4q@Ze)LuoaO0~lkBXno0a zcv5qsk+nFphu|iPirevxJAA9$I}D87&8XxNkPdn4NMItLm`GuXUouaDtG(W@zXyAn zi3Fmvy9iH;iyJ-tI$q~1t;z6RH~6l(X?5E-ze*%~)ZK**z~!WF|M3EeXdBq{fk+cp zm=WG+(F^l8eRCdHQB&6Zzwy?i|9Wx$_Ws_ruXGq#9TJ!TweH-WFNzJqOf-hQ&IzhU zVq2SRqi!QAYtEV$AgFOuQExY+QUIpdwVV6(n~zs$4%dqcVjIAOIwi-jUn7j@D%GAh zcDx+`AotbVfe4If+2TDa`o?oN8_=nqv=y80I;tu8OWw=nT9bJ$r}R@cf=_FDP;k;c=}VgkUv#Mk%ZLnICY1L;5l z4%Tz8W1suoeeHg_s<<)uPET|*>akUO_T-jXR@MBUKUZkU$;o};5fNme6Wy%*PZ?7! zucW=*(%y$-7o233f+gW?<{fTZBU+l|9{S+Q&-hKZnpd8k=n8$x`eyW z?1$^UyR0pvD7IhoWS<{QXTJaC&GiuD#TR~T`OmGe+ux9Oj_3`&ux6Kw%x@ceS7!QE zuH3Rmr)_Ta`?oXl?$PRIfAN5ZFI-39=UXBY!WB+?oepi1b%p}tc9SD~(B}Lhj@^FH z=}7k|4~#38iTqio>)i2Z;eQ@S7omx!FoVS1r(~z}b3fZ_q&Ju5-utY2yQjBf`s1TQ zfjb#>+{2D(wL{KT3Pu>;M1bC`|LWO@9&>V)Q*NsY@k+d;#qB^%J>j3*I^jzWbABd> z*1*^a@>HlPlHqi2)->sf7Fbrd3f4tcvZ)?@UwHh7j1yXnv;tU!AxwA9lzbE zx*6?iulhr54>k0clx+QxSACrmXMmM!c#=6`%m(72ps*Q+DzSF`_@hfrEyLi5xe#-7 zxVIVBd_$Ib$$&~|%YK}lir3a9woS#> zb>7wV^o%f6pIX1K1D%nQs+4k-V>Pw{3x&Q)dg7kI z4Q&=2$iW9qg?bU*7#7{E+$U~%>Kd_~C*zo&NAe$Yh`Rlb=%(7IaZJkz!<9I*ua$qO zmPf1L%6kH~&67{W+~-1Xq^u)xk`gb5P$FYn04xrm2W=wKv_vaYOW!zQ&#TQ+!v0Ye z!j#c_ARgjy!`|(<%f@!o^!nbb6@!Zdk;g|Yf8Ibl`|;`BFaZYB8qdceEgo*~DG>?X z7+e{Z)kU;p{D}kUhvv!h3g8eAbLHlcWwqDma>61n@uq{Y&Vsv6wtp<*`97^1e`H}(!00m$ZBIjfX0~(@Y=GRJk zAwYowM#7HZEBfL+ODyHIY1D!0CVpwWm?XiWj)Zue`nD2BzIbZu`)Ch=vS1!kTQQ`X z;pmqfLxsGsf_VJt`t&;V?bwJ{(1X6pu7aX>!wvBVg%uzbud^!7)7mk*I4D>>?0d6| z+Q^v3)#SNfVT}{owIw9|G0qo!5V*tlU4|>4NZ+22`-J`a4dK81?*mGNHon{e`&_oE zU_NFV7jy7L;{YF&gfN|2YlkilntNdIXyL&F#Q@6SR^=pgtSD zNyMwZ11MSVHQ87DMu(!+;%L#yaq;Yq4^VJ!w^Kkr?24376qdH861T*3r7yS_GTJIiSDGb|MUlYC)t z_5%H9L^VaVHlgHQl>V`uq8z6X5EyeM$(zuD#F~s44rZ~H|GMmy+Ie!ydWsEG$;i;a z2$$J8PlussVyHD0m%|Ogixpf$>CE48*zh>TM~dm4^GzTi3j~ZoWHTwB(8|l*{7v1B z?daBUc(-eho&FEENLc>%A%ND-9ujOj{KmQsG=!i_v#2q`6a0BqHpc1BrSGH9i>tJc z5Dkx8@!)^i_4f#%) zuB@{&?S=qGV2xv!~Er5A+To8WEtH9Z4n z)oakWyYjLvy&=cq(A!h$;hD)~0~nZ1Axd@yYZNJ$9JciOEv;PK>?Z{;CEUP(=IL?r zXTa*hrPr@Vn%zdfZ^L-|oV@_>8rs>j6=bKd*s^vMG;?C@v@tDjYJ9wa zCaMZpO9aTDfC|hBrdD;OpE8$*cpw&7ht{1KRs*HZ&{_G+Rz!YqrIzU^VSRzAtZAsH zCfu}xj+Cul%ha{z0Y;>W<*5%j~JX4l23UAheDG!Iqjz`()JZ7}xqb~GU`V6I;HI+~~>ah2< zu)bn19^?Cni(`37s)~HGcA5^e;XC<^8Gsld)vAOyeL(1|cFc8}U7?llx>SzaSmwdN z)hF|awN6PW|7(>qVW@lcD-~M87^Gsp%-xN_^utkNJEB9ivt*P0Qn@RZ>J+rSKTxtX z>Wy}ZvN^JCk+EwIEC=Z+w+*4bgSKAy?#WV)v_Dn;a8MmqU!r zCX*AoUdXVCvDEDqZ{36Uivx{5RI)$DHQv6gxk|($bE(&V0p3>hw`GMgW5PK=>FjTQ zj%ECS_JzBb027)jQvXnw2BaJJv+SOf@Z`9j#9UAOPq|Z&8#hlfs zDqcqxLzbTrmhYxL&C;2|#2P&P;lhenL2MzrcTe=k= z==s99J9_w&+xATvc6H*CX|zb>cwhDt8PEPKVW>MTbq+Q2^wguk@4ZP?H92HW12jhY zj5~d=jgl#y>7K{VpBDN%1!T|K2&Z=LXG~~?b0r7ZGe#09EujZIMbsab*c!;j-s3}S zc&+Ds0H;~}ke6r%tT5t19W!a_FmU9ug(Ef*g(c$EvUI;zo;)5m!pXeqoIilwTD&Xq zMfJ=X2RkRW!^|}2?Dml=_2nAq&mzx*SV8BIO0q z45#IiV?MI#?&emBjA_js52Lyzh5rdI$fhjL$F0sfr|Q3M4nO&sC^g7iI?OH~isn}o zW;RXx-SKf3=AvuEVv8BI9PN%t#(p#T0jYzV2XI%RXi!BSL2F(z1R&j24<5j)oOf$ z&0+yw{3V}duNEq!&wLBSYWeXFYn-=6VM~(kI7=ikXEs-N8U{_EFQ7SR-6JH?_a-z; zgFtt!?lVSUHBa!i>OCj+#fsNPix(M{tl6dS1C_?Y(9xv&kmbs}Vv!|7ka!Al{?jN( zsXig0SCCi~L-tc)b|FM+z8oY_n3%bpl3T)3nQrWC8Tm$P!&kl=!75C>r1DaDqvLAI zzi$0>?h`~|Vezct0e;64Ie1%FhrXsYH!d~wObDX%i`d3}q>itwj+&m8%#=Sto}Y~e zTPQh1ws_gw0RaxVN{wmad5m#@3!XwX&5c1nZb^)`^0c%4@3Us&c;i1#2Nz2GACSxv z!TiST&67j$_XFIfI1;p+k!2=;4 zW>K)4U$bOu>~BrYY^knVAkTz7Q#WUqRZFXYagA_+y4*xCCi=+mJd-}k!?!!Ig-B`I6i3i}| z^9c(|#?B0C3MP=mwZjKmkZ^xAHEidri?tBcdL&dbz>R9^0q?U+PMmdE$vF3%-DKc2 ziipjXS&RAQoaFTWX`b`vOmzRKT)tErTS_`=OcN0bx?F18WVCP%_2-KI15!r*6W(1; z&_XVGzAZ0LX+M09*)wPIRTO9e5|1ge362!KbpE}nD`yB0cnV=mQ>(qaI+LpSnusg+ zOU%rU$VHe)g(oW=7g=cQhNMFu^7|wL49PBi3?2Yrf%m`G82azEnEsz`5^3CwmX8DBTJTQEKQ{urkf%f6_J}Jp(L(s!&vTQCt+m0Euuvw zB1?p>(552dMs7m6cJFz<-|6;y|9^k)AC;KrdCvKq&pGFFj%cc#jqpm@l}nZ^5#DY~ zwqLSjsU>{5|QLfw-#z=Rh zoIjr5{V>Sz{Ih;)z-Vjore{hsCuag(VodD!mR;+cxUlY;?$?^M zs}A)g_O2%!cSu`5Gj69RuX7yFIb6=?Bqk}Ou&>+a<^j8V9j`d2+&4Z8s&-vn8f8zp zl_O1A+r@R$$fvVoa+B;gXhy;}i~i5PsYm5V-yK(Oz5I1H`_GlJd$sK+yOzWqjJrK2cnk{c%9YeK3SoqR5wTSNg1fxj=vN(%~jq*L+$0$5sZ~e10X~pLdd63hFCM zEnn^B>rDLBL_qrlO+7o*zR+@Lj4ynwc?qqoVK4Fa5LGaQE9G}mS|fi!(Rxvf;nE9F zDYs;Qw90bkr(~_sUQY!RY}$`Z3v{0%z)ve5T1~BbP?Y%8a_zT}ef@ugp9$TOX3@?z zF%#-69v^>^-O)@*P*jTD%Wo8O-bb0jW_Au8$?5d`TKm%xS7EB)u^@@}yT5YxM}^w2 zgr~a#g_2AncqgdC*LA6dwS#S{eMge)Z|PBo3GXtR3H|}6q6_fzIi0RCx%8h~);&tw z8%Y~hjYdIew#-_o9WrlBDGt-64vVid3;s>VMW)vXtm7Fy7wytHrb|_Sja@C{`yua?O){YMFHuU0!m=vHuTp4FK(} zu*U|VSu&&`$Z?%8PLh(;nDzS2x^!1mSSet-K-Pw9>kNWpAVz*%v*=%y+RR3+{LhWOpu1t@R&Ftr58w2e zG?(d0aIXv`(gNpxOZ@P9_Rfmc!=DNyc~FbsvC)LsykDlpxILs)`4I6Q0V3OIY1M2f zuXzIx!PSw$`=f*u*NGLGPOmJ5zWJ$uPpx&B?{v3Jk>L+IR8Hx&2V?_u3p14hynb1* z4FD4u&0v4=2@ZuHhCj9_$Q?gs-nU++MEAOo%K7PiUb=V6LMx^}o3iFIo_fMXwSvy{ z2_0%9yj_dk@ra2a%(E@HL+G9sA>V5xt*;(*Xlf1UQC|P{5c48HhYkUJauHG$MGd-C z&iGGKj7*W_mss2=km@q|XV;U1Th&(%DX>fDG7@b6ab$TsUq;q@5HU3prfn?L-^ETk zSD%ZY&_S7x-B>i}ku%J@JW{G6{8hoWR~wJKxbCXH@~=w)4x&w8CHwTV%Xl{)8|_(x zU{boYPm16%w_9UJH49OV9Gr9yuMPxv%t0?e8#o;lM3B^OtC0oY|2E5B4q7x&>^uZoWRv${ei?n3HjY z+js6n9X)nz+hIMKy1~IUZZmT}Mlr3eyT~51OKA8}n#PnQy6Ilof6#Zp2oH7Pg}IE~ zU?XXyT(pXO@xcsfIrEH;ok3Ps7CE>4Tx=d-pdkUyZ5E=d;#@TYU!g9O*CKl9fBNaj zF>}U?chzyy!=J3Bue*>h<{PFi?`NI8<4^qO_yP4R<>iU{TdsO5Mb6wa7IEo4NdV`P zB>Tf<=I_((_s8Z9L#fkP*5lSAMPB>%kTT+Z?BWU%e0l9bNM`BXWZ^m+2bp*`clXFr z%rg)5uAr|U&FbE^t8wWVFIGjI_o40b)QvYW=P$Wd`A}_T{(x0Dvno6AwEF?ewCBs} z^e3~%EOIa8Rvj1Ve>T0g?jP4Q&*f zc6wx<Z&~U$gzMm6`UR-vpXWdO5L8rD z1p0$4l7l9F7R~xb7H1UY>K;E9VCd`XclLe$D28CYL`xqVwrZ~GvxP3Hx%MFO7l?wL z0$&&5KuQ7+ih^DzxhU|i`0~w4Rz+1MOIk)|%haZ7%Zu`{4(!<{d2~HJz4P{Q?m6*R zHFx0PZk6wi0Afv;Y|r~g;J)d-a2=Niwl7;+gxn4v{#jRFKdfT&l)`ddGqX4#t%^5% zlQ}=*SNHYn#$-s6aL)t1MnDbJPK-u=^&m&)UcW)~W)TeR)SjK^rr`t~k zoLVvVoE}-a>?^37Yfl+6RbDl7*I*>C3wC(675zouAr z@Rw|2&x4t4$Rg5}o6?1s7QS5dQ9&JfIQM2HhV?B#A*SL~a12FDv;pYZqcQ@w_5tma zN~HKCqT42Q$(|fNpcHL?Y==PB--lSwMnh_8-hY`Api(ms27q7f@i!GURU7^_%LcU| zl;p*a^r(Jt)K_fTL^eoT9+-lZ1a#ZHTFDyL0KCpz)r)GLKA4 zUsOh-!|TG(hDl-67wi11_&7j*@N~s7sDp1Rn0()H+%*ufthq|ovbg$ij$QuFHQQdj z$aY{K3{Khq##O-zD2EB<`0p}&)6m8r|EY)q5YM4LpErrFRHg|To1X( zG*s%fY=svSTP=$%rlC(4 ztEOcGk}@JlaH6d58$Wo_S`*i&7#yA1s3$o&$Ux7vePEEhrP%#Y4*fBRz9t%glb?ZE z2->UX=Pt-xd4`|$;kY^nZ zWQRfWvnn=A+q}7diw*x4=DIlMjQp`QX-1!K&t9bZ^XrY=X0k(mgGL47{G>R157ptQ zgTa!VogP?^Lsh)Mk#paL?*`*)vGOeXt^L&ZWW;9B*GtT2?wkkGrtLA;-k z4zNij>~>qt@_l;WICeDXFVm4(9~NB9s2ta)e*y+G;;!4rNmW2exS`#~fV#i27W#W_ zi>L~)OXQGgPbg?9Baugs9OpPK=*6Iq!TA5!|eJ|ze-R~!=EaPv-(fvit+ zvM`*`Rq@FS-Bwuh!>-|`O1;?AdsDtTAI2Hm|PQ!Z$gZo_o~I5GS|pXxUN@XNNME}eFyM+e!ZfwBu2 z&vL6Hv)T`rk|($F(Xmq70s90K;#+ zYzt5t{3STFg4xf{P_*EVI4j!dnVPbt6%-026T^J$n?CervUGzZG&VF8Tcr+62umJ8 zD2{oY173CwI^mcy~^=E!l&E$7n03*R|;ilm#-B%W(MW5uuB!1j|1k{VEwI#t& zcX}}q5Z|}mn~(YV%qAL~K=&{w4pcFY9|k0He0jrI!oRr&s{}-0)6W%@*iYvcQad@6&04z;6)0Q6SHe(4Utn za;V3(d(^3f2x+$-q(tGM0~_=s89GE#OiZY~-|tWowvE8#(W^RviIy%9x8fjCo%;)m zW^}2$YCiT@fv|+BGhYnqKd&PKV>E*1SY^KFlAz?B5QnjcS>CwyyO@STBVY>pT$bVQ zFR8nE^G+2^doKq~*m*;5CV+?~;qv!!_aT>PyHW=nqNOV2qF`{Sg|bHQpLiQk^a1cb z=R_V7?U^x5o*NsIuS@R@If({)H1-QRBdHIARZe_DsL3y&Ce&a&+UyJ(07(n|)AI(+ z=E3A`&I++ARTkx_3l&`AB?!Q1XU^9JUgnBH*c7zX+d-5f37NdPTuTXZc^HJO5N+oG zp+3T}Hh4C3dHA`}I5zzdhHYn)M^1c1d-ano_)wGhG2L$|vtjY)v6g!e8L^<&VM#z` zyJ^}uddy0@`7*>f(l1qDY@~mJ=?kiru@JtX!2RHU9aHggbCFrIKK&gD>V7B)P$l@f zPYLzno@{I;^d;2OMcTJZ(o}6;n%))a^Y@Q_#G7RdV862P0k{S&W#p{g9vGig%-zFE zp`22{6<)hziYuB0CX_<)?c`Sc8EJddR}~vd(I|-xmJihcQyBGNOM<3fzY^Rz_oSUZ zG*O>jM~XhYv-qZB7_f#I9ctG6+*1=!L@Ni|+e3c}fxPl`|88NFeaH`urynTR-K*N& z7En6spt-i-WVqV%a`XfkuYphhUO&iInBn)g8hJt25A}KIdK(j?c8^lob%By77SZ3< zBNmQi7Xw+)WPA%K4n3kIU4vF9Tu8~1GcX$I z%mf&(0AB3bbo>nhnVY^jC@@N6esYs2%=sszF?JzVP#YU9yON<$Zs3i|Q&U6<*c7P1 zLML3U!>Q8^ul7ZSP_kyt2Q*@en>Go4Vm=tfAa10DtcI3FYwfC@*P^|KrlDZ| z;1L5UZuE(sg~6qLXMLP6OXAZp3We>y7cN_Y^c(QOT|78_elHnjF$kPp7+jeH(vj|f z7gH3zxUXPe^SBRc@jP&hV{wul4L|S0l*X^-_Bs{K=)+1-yL^$Nf&x-D*Nr5N#;>4} z0f6@#aXG(R4GzGDDh6L|8Lz}@!AUU)`tq?a)%KGCi-W&nVh)LGgq#eRMs_n}YZRPh zefQ{t&dMq)18Bvtprar7UyBVhG*w!^wjjeX+4t`|Op^wBP%>eRJw5eRM4bk6Qo&7W z8xUZ02N>jd3n`!s>|S9*1-mLD=H(9R&&!jX>}kj*S8bY>Dk zY%drMYvB(}N^I!LG)N!=xUv(v5p=mISpA@@=i0OhnVFe%d*`FuRQV^5UPfGq5&V@E z(yNHWv<^BtvQFLtN_6GJ0VUv+H|YJbhSfewCZ?uDIL^w?SF5v~jl$kWHne7KC%YXK zMO?B=)Lxj?M%7~Y159E^U|j_*%?vm}OUd>2^$$usdlnbM z+*JpO*s5{kQa%yxLH{A?mfEO+cign*Tsu)dKN22&4cr3cH~fTo5k6fDu6_I6@u^sf z^vi9kSfrv%<}uATU?j2lXw)c{_W(B$9cs6Q!wfJ#%=U_haV$9Ob%4J_8L``@u(ZY-8Qf6 zR`UwxFl4{l6);*n(=?Gqj6V2b_kB5tQ)D2(E1ANCnR5C47WD6x3ZOqUdQdd2_ z3<4CTp>hR0=1gi^7asP#9?HRBZ zR&!8g<*e~#2~1!%j!+T3-8Z4ePL349!%CBampHaGbPWb9Pzn7Wz*cA^x03;DC7#2u z$|*wY99T-h0#TZ4D*|F?8vw>5B5gM&7uK!=1lYJwd6Ez@QoG$gjvPh)m;aaFR{b}A g1NL9Ob5YnS?tVPm)$kttUUA8GD?9SFtq0Hl54Dq_e*gdg diff --git a/assets/ys2/11_lilia_final/koala/png/03.png b/assets/ys2/11_lilia_final/koala/png/03.png index 77f2902a6558bf5308ca236f28a5d06db97ccb61..25d220601a2decd2efc21c97c7105390195604f7 100644 GIT binary patch literal 5092 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 X{L-FPi5(TT?Etn`j+Qh8CgJ}8)d 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 SjRZ!k4scHog(T`aM*a`*H*g&Q literal 7355 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 A761SM diff --git a/assets/ys2/11_lilia_final/koala/png/05.png b/assets/ys2/11_lilia_final/koala/png/05.png index 873521d593e6da12d4688f4d71433a1c49023743..12e0bf1024a5de7c0b04a02b2338695e833a5abf 100644 GIT binary patch literal 4997 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 literal 7301 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 LQ7_x={Ox}Lw+Mf@ diff --git a/assets/ys2/11_lilia_final/koala/png/07.png b/assets/ys2/11_lilia_final/koala/png/07.png index 201bed504e810f236bcb912abf1cd0ae4b36dc91..340a4b3f8db5775535eac0987c1087f4ce4054d8 100644 GIT binary patch literal 4857 zcmds*=Rcd@|HrRHL{PP=RH{;)gjNTw9Xcpt6Dy)>)JRH+y+^Csq93hYv@}+Y+JYFR zYP43A(x6(6@v$mI#Q5g(FZ^!)?wsp9&W&@Ob6v0VdOhFgiHVV}0G}iu0007a^lq8~ z00_nDe}+LhZ3g6eDdz$5HPh7r%D*08005EdJ2$m00<)KCcF!zFrMlP4hWiZO2o}6M zJ;4(f-7zjAFfq?XgmxNGHLoh27RBAktCr=;GbInSnntZhOmJkBAtc*Zv(Y?3xb1U_wsqF(zEwxrfdfeCjL2a z#e4th5MXI(PD}jWd*n|UZJKJ_p+qIEYHYQ&u?xdlG5V|5KCFJyABd3x3zhk|<8brX z0r?4u)7yUbJklKqK+Sb0<#EWEK~<-G_8~J~{kcMZ^%{OqywRE^Z)Rq*oE*jfBoL+D zDzP+hgkaEB2t64!Mt~s5U8d&S!*7bC&<>3vp)?c#-ZWgjmJf+2C)yNhkCC^CEU+mY1XB)*FZ5JYyoGE6}@)LjNJb%Z;5 z%=9c%&+6sVU~P#o4UnxsZ=F@R9vl>}ue`tesAIW@NAU1_2wd--FLrjd^7z0)4oX;7*Ja7~gp#&@$k&A;6~u!X z7^&UQX1U&2pKBT6LMzUApA;Ah!YesBW=R*TQ&{UI>Hdiq z_Eg!~&Bw38P=S`jxOiJu87rKk(!QP&;n5X}niQ}gdcK%rWmU5^LRDel$~jH-gTPht zzkPkp&@_DV!p;hH(k1POi$PV5TxlPCmKxS|srt;n2x=`~ z^h+;^3U(dZ&F!uwi%Gq5lz`;@YBL{55&QM{@Hbne94X-UShqt&eZby#%Th@Jbtx<^ z*WzVXZXh{;=5H`HcHb;SriT6wPj0Ig(1D^ewE&7qto!bQj%{pj_oGnku7 zl3sjrnU%{rfU3+ZTq^BfmxayQ{2l?F-u_bDf@1ePhmj0w}G03WX%C-kBL;n&za&ZyM z>;3qV`<2P4tclk00FBy*ElnJ$s`h4OW?Sz4NXkAiTt<%Dm?LffZ#>ur=9l-y6k45dQImRqq*(O=D+58F` zgAvP8C^p2W4L4dTOU%&=%Xu+l&nC;I9>Y0;?za-E2t2m;$}woa79Yp^1(&h&v5mA^ zCLmz-nVuE8=12|mB_$-~c^(DL+sLEs?Z~~x*MgCt1@eMNh+;^QQd?d7`6gx&@(zrA zT{tqaF_S4?GN8A-k?i^Cr=$K}}s8Sn=RBC&2xD$U4tSD5x>y>3fHvMQ) z@L-jMCd8~Z?pavG^MJ;a2azCZudxQ2Q1>K6W^~s?CCa() zDAyVz$Z>#I5%2pYXQri1QCK8#K-7x8R^VRBf8iB`w4+K!aEBrQuA$9^QGw=?n3H|q zJ`Fu~D>)9zg`sq*B(KS>fRt*r3l3M*AFQF%C(0!~%*VxOyRCKET+dvEBcs4W0fj-| zDJUtT%VYf7LMBBd&;>~@8Q|(g08+fPLQK7^SE)xAy-CC?_zJ|23p8&%S*TltzMGNw zmS1ONKg`V371Owvjn0*POyDFF$;;e2AiQFtrp0|^#?+1$+8(|p+iMkmHSQ)2+!P_c9Pd|BSHF_!X~VlHhY}?w>kw8oZ9`k; zqlFPblY!KcOZaF<55A?ro42w|LH<9YSNGlqXj~pSt@+QKb|7u^uh_>|f4IR|6mZtb zi-GdV>`&Vew0il@Dtb8Je9YO)wm%qW`P&Xo0ix&BH2aDP-CHh3_04HP!BtMbW|g`W zmiwUZ4MQ?$e67QMAPtD)taG=U%1kKwi*E$l`G)zXmtY<*1i?pVlUMj(=J|?+x)`_L zLo5Ed0lYO?r|syS@Y9tVu=T;NvoyI6yCZ}zc8~jmK9dv1+vf13P+yzrZEdo z*gI^Zd|AOzjTsTnN2!88CrjU@`FboRLQ4yq@PW!}!z!trcLDI=721|{Yxv@$j`a*8 zm%eytc|(pw*g#pIfl`!PVap(sCxGKlr;}Ig!*Jo%6>Ou)zMwV(mwiR(Y@w%Iq5-{=r4a_8X{I#|vQ0Zv(-XYc|S)q|l5fi7?k&5iw!E^4XI`996JU zXbM=pa40%mZ)RcTB0Sbtj`@ag@aCBmXF)q!-W~@x9?;0OCXGFHw$d(R*2}tq|1OKu zX@w^BaKjPN{4=m_L8F+fC1;?m6Lz4Rx=vO%Po9 zuE3YFFf>!8thLT)V~_S4<99yoKfYBqW8ZRdR|XJ08Rp^=U{UuDnr{0&BerDMPxLKz zf#+@)P|6N{c?0l&R!Z`=6mbr)gTBG%PLGeLkBBL>sX!2KVIAeWcYQ1yFTq5hAPHWg zmKN5HyhC(hgVCHr|DfIr?_*Lx5L(G-)R)dv#h&$>#(if+;w$qp+iq=DTiZ82*qGeikYX36AgcGmOL4jgWe(Y-UufIW zPS==mrebKOjVpPdi5PL@CzDBctd_7VCC}ZLA1X_Z0-nXLh#LuX)IC3J;8JK6z4*&= zOem|a7x%$0WOXO0PrA1vg)Vj?V!_+TWKQ?g(w{J`+wM&q3tfa)cvU;kE{Yoq9KyA` z@#)kSdzJoszY>xw89$OD$Si+)Ek{A!DCMdG#PLRnvdbvq{e-v+JhTq|V>G|39a8%? z<;!8}4APD@isv&xlz;aBU0>~ln%Xy^3@weQC3vRbzpp?NIh1<-*_Qsa!`9sHw1kaZ zz-cvt*!_nQv|mc28*y>VDj$a-4$U>+CgBG{859TV-i=4W9AZD|7(|8BbS+w*`Y-#(8uGQb5 zg^<}QeB4+4WJS(&@QG~cQhx?otKwpeG$pgnvPJdE(D$3s#$Zzd6Emys!VD*)ss#qE z<#wn-kwrJ9HlNr2HRm#NAxEr!U?r(3Jf%?vdf}6} zs+nFQ7slkXvZdDEC^3%R%Ifd2Z5K~~ezAnkb&d9W z**KQ+V`Y=5?aoIj8OefmxC%v<%V*2~X!g^SD{2?Zd$KGdJMwE}WF$_1wR->5YFcS! z;{Lctan??=T6lw;r*BHV*PJym-&R{xO&&bB9;#N{U|+n${~_qSma)GVBQixys80L5 z6F+6Y&RVHe@UooOgmS5Z=#;rG5X{$6CF+RXn~QMmMz$=ityQLIR#?ZDY$qQDD~edg zDEg%odz~3)Fpgqkr0WcICDL;WmEZgn2aOAxv5042H<+6&5;U{?j^SF|EkJd)L>A8W zx02&6!W^VeQ?`~i!I$c0M$q}Plj7FO^G4FW*TUm)9JD353s4F*nzx-OPItW)qVmvf zC9m#!wbPMQ zHOa>ecqKbt#F#|^x8Hhks?E3Z!_pbYWg)L2#`9-CSQsu^F|hoUlw3_!?;DmiTp$VS zdGn9XVDD68{(pJQBAx~sYmZB-SK0?3RU7k65at07ied^MjY^$19q3F3%HI5Gk$P^7S;wPAIyM!?qyr)PZEb70a z>d)dD+}zyuFwX3pGMi6l0Zv_3K1F3R#R4fi`{~e>qu|O@&h=?OGq8g8JZ~gx_B87s zAuCG4BD@HZzOc5>8FJdZr&YMWGV3sVj$wu0!=U$a2|DHtQZQ8aVh&d++|U${{Wd)AASG; literal 7075 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 NaKrp20&j{+`VT}*XsiGL literal 7320 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 diff --git a/assets/ys2/11_lilia_final/koala/png/09.png b/assets/ys2/11_lilia_final/koala/png/09.png index 780e8296853082b8848f902d78957a18436235b9..fd11b6bf850598396576143c4441f079812bf80f 100644 GIT binary patch literal 4983 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 W@ziUY48J*CVsGnAx^Dg3ss90>PK_M^ diff --git a/assets/ys2/11_lilia_final/koala/png/10.png b/assets/ys2/11_lilia_final/koala/png/10.png index f1d786480161fe486c591ff1350aeb814ae039ac..41f94c2c7649fd287c5b26c1c44b8be52b5213a4 100644 GIT binary patch literal 4921 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 literal 7290 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 H`~3d^yWjo1&-3gz+Vr0Oh4TXE0RX@SgFC1P z005H~j0_-g#G{kJkJeK+UEY*e{*c#+CGGZnG}3fh=@kj zveCmF5`D+?nECy+io1cQ8Xx~tyxk2aW`HkTl{kEPLyu*oz%XD~Pq*XsnWCw+_%Ik{ z=4j{$GI%Rt85e!-Y2nC&PW8_lOBGE=8`y#ApgiorXEz?Q{Ll zMkYyft0!>IxvABFg>yiho%ddz$R%5oyax3c`dvC)q>G7(^DUWgli!x~$mx4i?0tlG z^zq$}*CF8mM+hzk@*2RZvwrR$WM7+JNP;pLB2at6 zu59kE5JLMFo#?RgQ7CI| z9c^sY8~n(C;5Mo9RR|ww%DeZZDALW#=kKJ-5}EuJ0L10rn7dpk){fkiiQ>t=bwISE zG7~sWmHwhrS2ktZco#;)!vH}8yUscMwh95{o%~;3uncLx5|7C_FAE#fCD;MX(Yw+# z0uW?(yoGElwrL?Z4bz%BL+ngqKY1>(DzbpU21$Y2ueYrj>D57=Qghnls`#*n#sAz>CO9I?&-;cJ8s z%Cg~(BhQC-yeb~IdDr4mSO7`T+nHW%9KCCxKzKKXn#Lg@eUC;8ydR( z50rV7lj8@Ao%z4_u&2v8L3)#|LHnv?8FVnBw?Ik5Y>5H7sjJrh*0@@+n0hrMC;eXb z9{C*p?H5-%)Eb)w{xs=@l)Ad@e!+?F^YMXJFHYVWpo*xEi<=W))`$*Hc5{7`xEts8 zBj~V$(y!TKexrkWat(XdOQx}d`0@3c;9{pkvH0892<~%)aU&&5MB7=eTni#`A&;YN ztnht~_@_}6Ng-r;mu*-nKID!Wi}M ze?f+mgBOQB>}QSK_~NLG(899=g~0VH!NtNN#X>W~J$)2OUyD#h49L0s9J|p7Ew*>Nm9N5ak%ni^T4(FMm%cu$`Z8YgTo~>PPcxO z2a+h&uJ!Mq1_T87%r!a&B|W*aLxF?%)9ckhI%0n%M*JFP;w{{ChsW)q`4s<(EZ^kE zOx@lHjp!{@*yqomQ;0|Vc`tS+WpBDSR*vstLqj2U)}mj-kr``x!GuLiUx$|4-n7-g z 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 diff --git a/assets/ys2/11_lilia_final/koala/png/14.png b/assets/ys2/11_lilia_final/koala/png/14.png index 29957484fe5b49774524d5c469aee53c5920d04e..4a820d760efbd12b83387c96837e64ff87e73656 100644 GIT binary patch literal 4985 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 ZG(Fwnb9()A_@BQeJM3J@H*5}^`yXRzW>f$G diff --git a/assets/ys2/11_lilia_final/koala/png/15.png b/assets/ys2/11_lilia_final/koala/png/15.png index 802e95c82c44d38ce180aa3fa997fa4d2d69ee6c..17fd1905966be46f842ae284cbab37990fc58790 100644 GIT binary patch literal 4924 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 literal 6998 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 H9Vh<>9k>Y* diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index bedc2a7..d3d2422 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -142,7 +142,8 @@ ZX0PRGS = \ lilia.zx0.prg \ lilia_hero.zx0.prg \ island.zx0.prg \ - clouds.zx0.prg + clouds.zx0.prg \ + lilia_talk.zx0.prg LZPRGS = \ island_map.lz.prg @@ -158,7 +159,7 @@ tellarch: loader: $(LOADER) $(LOADER): $(LOADERCFG) - make -C $(LOADER_SRC) EXTCONFIGPATH=../samples/$(NAME) PLATFORM=$(_PLATFORM_) INSTALL=0b00 RESIDENT=0900 ZP=02 prg + make -C $(LOADER_SRC) EXTCONFIGPATH=../samples/$(NAME) PLATFORM=$(_PLATFORM_) INSTALL=0a00 RESIDENT=0900 ZP=02 prg assemble: $(ASSEMBLE) @@ -195,6 +196,7 @@ $(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.bin -f "island" -w island.zx0.prg \ -f "islandmap" -w island_map.lz.prg \ -f "clouds" -w clouds.zx0.prg \ + -f "liltalk" -w lilia_talk.zx0.prg \ $@ diff --git a/loader/samples/minexample/font.bin b/loader/samples/minexample/font.bin index 05d4f39f805ad7436a42c1e1c701d71ebd05fd9e..60320e77e37014caa8e8ff567f7cc5d05c05b0f3 100644 GIT binary patch delta 24 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 + lda #>code_start sta $fd - lda #code_start + lda #>code_load sta $fb ldy #0 - ldx #>(code_end-CODE_START_ADDR) + ldx #>(code_end-code_start) beq :+++ : lda ($fa), y @@ -73,17 +73,30 @@ copy_start: sta ($fc), y iny : - cpy #<(code_end-CODE_START_ADDR) + cpy #<(code_end-code_start) bne :-- - lda #$36 - sta $01 + inc $01 cli jsr install sei - lda #$35 + dec $01 + jmp code_start + +check_return: + ; for some reason GETIN enable interrupts back + lda #0 + sta $d01a + asl $d019 + lda #$36 sta $01 - jmp CODE_START_ADDR +: + jsr $ff9f ; SCNKEY + jsr $ffe4 ; GETIN + cmp #$0d + bne :- + dec $01 + jmp code_start .res loadraw - * .incbin "../../build/loader-c64.prg", 2 @@ -91,17 +104,18 @@ copy_start: .res install - * .incbin "../../build/install-c64.prg", 2 -code_start: +code_load: .org CODE_START_ADDR - - sei - lda #$0b - sta $d011 +code_start: lda #0 sta $d020 sta ZX0_dst+0 - sta enable_music + lda #$0b + sta $d011 jsr load_font + .assert * = CODE_START_ADDR + 15, error + lda #0 + sta enable_music jsr init_2x jsr clr_txt ldx #irq_badguy sta $ffff - lda #$1b - sta $d011 lda #$d2 sta $d012 + lda #1 + sta $d01a + asl $d019 rts badguy: .byte "badguy",0 @@ -1247,6 +1257,7 @@ liliaheroname: .byte "lilhero", 0 islandname: .byte "island", 0 islandmapname: .byte "islandmap", 0 cloudsname: .byte "clouds", 0 +liliatalkname: .byte "liltalk", 0 darmtower_txt: @@ -1307,7 +1318,6 @@ run_nufli_bmp: sta $d01a asl $d019 jsr $a000 - cli jsr $3000 @loop: bit $d011 @@ -1376,16 +1386,14 @@ load_8000_zx02: jmp zx02 load_font: - beq :+ + bcc :+ pha : ldx #fontname - jsr fileexists + jsr loadraw bcs :- - ldx #fontname - jmp loadraw + rts part_10: ; the sprite data is embedded into first few bitmap pixels @@ -1550,9 +1558,9 @@ part_11: lda #1 sta timer_mode - ; ldx #liliatalkname - ; jsr load_8000_zx02_2000 + ldx #liliatalkname + jsr load_8000_zx02_2000 : lda timer_reached beq :- @@ -1572,27 +1580,37 @@ part_11: lda timer_reached beq :- - jmp * ; TEMP - ; load new music - lda #0 - sta enable_music + sei ldx #song1name lda #$a0 jsr load_8000_zx02 - - sei + jsr $a000 + jsr init_bmp jsr set_irq_badguy inc enable_music cli + lda #61 + sta frame_until + jsr wait_frame_until_2x + + sei + lda #$0b + sta $d011 + ldx #64 +: + jsr wait_frame + dex + bpl :- jsr clr_txt ldx #turn_disk - jsr write_txt1 - - jmp end + jsr write_txt2 + lda #1 + sta $d021 + jmp check_return clear_2bufs: ldy #$44 @@ -1746,7 +1764,8 @@ presented: .byte " presented by falcom " turn_disk: -.byte " insert datadisk in drive 8 " +.byte " insert datadisk in " +.byte " drive 8 then return " clr_txt: lda #$80 @@ -1874,12 +1893,4 @@ txt_fade_out_offset: beq :- rts - .res ((*+$ff)&$ff00|2)-* -end: - ldx #fontname - jsr fileexists - bcc end - jmp code_start - code_end: From 5f54c645ab3d8b8370082cd3904d0e118368544d Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Fri, 28 Nov 2025 22:54:44 +0700 Subject: [PATCH 12/26] Always build the loader before the source assembly --- loader/samples/minexample/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index d3d2422..ab890a6 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -164,7 +164,9 @@ $(LOADER): $(LOADERCFG) assemble: $(ASSEMBLE) -$(ASSEMBLE): $(SOURCE) $(LOADER) $(LOADERCFG) +$(SOURCE): $(LOADER) ; + +$(ASSEMBLE): $(SOURCE) $(MKDIR) $(BUILDDIR) $(MKDIR) $(INTERMDIR) ifeq ($(_PLATFORM_),c64) From 2f18a3b9b57590f65d765fe6a75492b91b9e830b Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Sat, 29 Nov 2025 02:54:09 +0700 Subject: [PATCH 13/26] Fix makefile for older shells --- loader/samples/minexample/Makefile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index ab890a6..faf8311 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -116,7 +116,7 @@ CAT = cat BUILDDIR = ../../build INTERMDIR = ../../build/intermediate -LOADER_SRC = ../../src +LOADER_SRC = ../.. LOADER = $(BUILDDIR)/loader-$(_PLATFORM_).prg RESOURCESDIR = ../resources @@ -213,9 +213,6 @@ run71: $(DISKIMAGE) $(EMU71) $(realpath $^) endif -$(INTERMDIR)/%.prg: $(RESOURCESDIR)/%.bin - $(PRINTF) '\000\140' | $(CAT) - $? > $@ # octal 140 = hex 60 - $(CC1541): make -C $(LOADER_SRC) cc1541 @@ -224,12 +221,12 @@ $(ZX02): %.zx0.prg: %.bin $(ZX02) $(ZX02) $< $@.tmp - $(PRINTF) "\x00\x80" | cat - $@.tmp > $@ + $(PRINTF) "\000\200" | $(CAT) - $@.tmp > $@ $(RM) $@.tmp %.lz.prg: %.bin $(PYTHON) aart_lz.py $< $@.tmp - $(PRINTF) "\x00\x90" | cat - $@.tmp > $@ + $(PRINTF) "\000\220" | $(CAT) - $@.tmp > $@ $(RM) $@.tmp song0.bin: ys2_fixed_drums.fur From 1855439e8517dcf15001a3f170568dc02eb295c0 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Sat, 29 Nov 2025 08:07:45 +0700 Subject: [PATCH 14/26] Fix lilia talk animation --- assets/11_lilia_final.csv | 339 ++++++++++++++++++++--- assets/build_macos.sh | 3 +- loader/samples/minexample/badguy.bin | Bin 27948 -> 27948 bytes loader/samples/minexample/lilia_talk.bin | Bin 15108 -> 22353 bytes loader/samples/minexample/minexample.s | 7 +- 5 files changed, 302 insertions(+), 47 deletions(-) diff --git a/assets/11_lilia_final.csv b/assets/11_lilia_final.csv index fb9202a..ff741d4 100644 --- a/assets/11_lilia_final.csv +++ b/assets/11_lilia_final.csv @@ -1,22 +1,21 @@ -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -50,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png -20,ys2/11_lilia_final/koala/png/04.png +6,ys2/11_lilia_final/koala/png/13.png + + +70,ys2/11_lilia_final/koala/png/13.png + +10,ys2/11_lilia_final/koala/png/04.png 3,ys2/11_lilia_final/koala/png/05.png 3,ys2/11_lilia_final/koala/png/06.png 3,ys2/11_lilia_final/koala/png/07.png @@ -24,18 +23,58 @@ 3,ys2/11_lilia_final/koala/png/05.png 3,ys2/11_lilia_final/koala/png/04.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +10,ys2/11_lilia_final/koala/png/01.png + +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png 3,ys2/11_lilia_final/koala/png/08.png 3,ys2/11_lilia_final/koala/png/09.png @@ -45,19 +84,233 @@ 3,ys2/11_lilia_final/koala/png/09.png 3,ys2/11_lilia_final/koala/png/08.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/01.png -7,ys2/11_lilia_final/koala/png/02.png -7,ys2/11_lilia_final/koala/png/03.png -7,ys2/11_lilia_final/koala/png/02.png -50,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +10,ys2/11_lilia_final/koala/png/01.png + +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +10,ys2/11_lilia_final/koala/png/01.png + +70,ys2/11_lilia_final/koala/png/01.png + +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +10,ys2/11_lilia_final/koala/png/01.png + +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +10,ys2/11_lilia_final/koala/png/01.png + +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png + +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +10,ys2/11_lilia_final/koala/png/01.png + +150,ys2/11_lilia_final/koala/png/01.png + + +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/03.png +5,ys2/11_lilia_final/koala/png/02.png +5,ys2/11_lilia_final/koala/png/01.png 3,ys2/11_lilia_final/koala/png/12.png 3,ys2/11_lilia_final/koala/png/13.png diff --git a/assets/build_macos.sh b/assets/build_macos.sh index 49c17cb..38c47bc 100644 --- a/assets/build_macos.sh +++ b/assets/build_macos.sh @@ -4,4 +4,5 @@ ../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/lilia_hero.bin ys2/08_lilia_hero/koala/png/01.png ../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/lilia.bin lilia.csv ../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/field.bin 05_field_will_loop.csv -../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/falling_star.bin 06_falling_star.csv \ No newline at end of file +../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/falling_star.bin 06_falling_star.csv +../png2prg/png2prg_darwin_arm64 -m koala -bpc 0,-1,-1,-1 -o ../loader/samples/minexample/lilia_talk.bin 11_lilia_final.csv \ No newline at end of file diff --git a/loader/samples/minexample/badguy.bin b/loader/samples/minexample/badguy.bin index 6d504ca7e39b64c77bc004a95fd42c2ec98a3068..8ade6eb71aed0e9c729aebb848d9703dc3892006 100644 GIT binary patch delta 18 acmZ2;i*d~@#tjbg8wEBoZT_TaU^&Xypw6S=IV!+kc!sLc=9)EO0*r>AFUM@J{l{PykZ-@pI=|6kOq8Wovx<3eblXVz>z zcCO7D9FmOeVUxns>f_@!dvJQN32-tnFleZ$s{WtP3S>0|ZC=1{!N?ODI(6Br-~a#T z=kMRY`H4URKWA50Q_sVPjEsg88AaI{4H+&sF?CJOR5;1KXwjlW4ULS94<9}RN^w7U zY-q^X)Wq~@{rb(Zip!YT7#O%1_!uS|s>rc1aI&+r^H0`QQD)?y9H?@ViGhE!jOtfL ze#QrEcNjv$LP3DDiD5FYnSvt3#a;ZVOP4Nv`t|GAE_OBtP7THosO!7U#iTxVR0={s~| znUF!@fBGDO|U4h(4qH?j-Uf%5f6eR*cCA?Iph zLyLN8pI93yOZAZ0n1(&)2(U7GaB4D!*M9x%;LL2XkZH1(MFeWyD~7XR4%)oU(vJ}U D0!XqC delta 1276 zcmcb(jxXXT2eKMIZC=1{!N{{}RaWHH@BjbL zpI=|U`H4URKWBeeQ_sVPjEsg88AaI{4H+&sG4)T*R5;1a^l8zdhDJulhYueDrMMqF zHZ){xYGV5I>(}O3#br!vTntHfRpi(hIN90RxhCtXC^K?R4pceG#KpB)M)fPB z2Gb3;+YBp#VCKxoxF)X9uuu@-Y+_(y;9y|9d-vY0TdS5WZQ`6fTTfaM;+1}`)TK+8 zKK=UjYZp741E&UK2-I8sT$2;k7nm?j;Qz!3^BfZw%zK}>m~IG2Gr|1#iyh=cU`YM{ z#m>M!SuaF>@HC z-@hN^sr8c&>U3@P)hQ(*h$Xd*QQT@Y*+nmaoZw`hte~zyRBRbd=G0f3JUv8=!oWri z=B1|Ipa|4t9xB0XNrzyTWTHHo3m7qaaB4FCy&fNU;2@)fBG=@-Ara6t6A4V;a-p>` RB&Sq%2BPC>^TyBxi~x4<*Np%G diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 690342b..8572c53 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -1592,9 +1592,10 @@ part_11: inc enable_music cli - lda #61 - sta frame_until - jsr wait_frame_until_2x + lda #<256 + jsr wait_frame_until + lda #301-256 + jsr wait_frame_until sei lda #$0b From 1744e672862660370173f4fdae738fa70c6f26ae Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Sat, 29 Nov 2025 10:27:57 +0700 Subject: [PATCH 15/26] Compress the main $e000 code too --- .gitignore | 14 +- loader/samples/minexample/Makefile | 17 +- loader/samples/minexample/bin.cfg | 11 + loader/samples/minexample/font.bin | Bin 529 -> 512 bytes loader/samples/minexample/main.asm | 1794 +++++++++++++++++++++- loader/samples/minexample/minexample.s | 1864 +---------------------- loader/samples/minexample/song1.bin | Bin 4464 -> 0 bytes loader/samples/minexample/test/bin.cfg | 11 + loader/samples/minexample/test/main.asm | 10 + 9 files changed, 1844 insertions(+), 1877 deletions(-) create mode 100644 loader/samples/minexample/bin.cfg delete mode 100644 loader/samples/minexample/song1.bin create mode 100644 loader/samples/minexample/test/bin.cfg create mode 100644 loader/samples/minexample/test/main.asm diff --git a/.gitignore b/.gitignore index 07aa64f..576f741 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,13 @@ loader/build loader/tools/cc1541/cc1541 -loader/samples/minexample/*.bak -loader/samples/minexample/*.o -loader/samples/minexample/*.zx0.prg -loader/samples/minexample/*.lz.prg -loader/samples/minexample/*.tmp +loader/samples/minexample/**/*.bak +loader/samples/minexample/**/*.o +loader/samples/minexample/**/*.zx0.prg +loader/samples/minexample/**/*.lz.prg +loader/samples/minexample/**/*.tmp +loader/samples/minexample/main.zx0 loader/samples/minexample/song0.bin +loader/samples/minexample/song1.bin +loader/samples/minexample/font.prg +loader/samples/minexample/test/*.prg diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index faf8311..725b102 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -164,9 +164,7 @@ $(LOADER): $(LOADERCFG) assemble: $(ASSEMBLE) -$(SOURCE): $(LOADER) ; - -$(ASSEMBLE): $(SOURCE) +$(ASSEMBLE): $(SOURCE) $(LOADER) main.zx0 $(MKDIR) $(BUILDDIR) $(MKDIR) $(INTERMDIR) ifeq ($(_PLATFORM_),c64) @@ -180,14 +178,14 @@ endif diskimage: $(DISKIMAGE) -$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.bin +$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.prg $(RM) $@ $(CC1541) -n "otomata labs" -i " 2025" \ -f "ys2intro" -w $< \ -f "song0" -w song0.zx0.prg \ -f "song1" -w song1.zx0.prg \ -f "badguy" -w badguy.zx0.prg \ - -f "font" -w font.bin \ + -f "font" -w font.prg \ -f "intrbmp" -w title_320-prepared.zx0.prg \ -f "tower" -w tower.zx0.prg \ -f "towerbm" -w tower_beam.zx0.prg \ @@ -229,6 +227,12 @@ $(ZX02): $(PRINTF) "\000\220" | $(CAT) - $@.tmp > $@ $(RM) $@.tmp +main.zx0: main.asm + $(RM) $@ + $(AS) -t c64 -C bin.cfg -o $@.tmp $< + $(ZX02) $@.tmp $@ + $(RM) $@.tmp + song0.bin: ys2_fixed_drums.fur cd $(FURC64) && ./convert.sh $(abspath $<) cp $(FURC64)/asm/song.bin $@ @@ -237,6 +241,9 @@ song1.bin: ys2_lilia_sid.fur cd $(FURC64) && ./convert.sh $(abspath $<) cp $(FURC64)/asm/song.bin $@ +font.prg: test/main.asm font.bin #test/logo.bin test/txtbg.bin + $(AS) -t c64 -C test/bin.cfg -o $@ $< + clean: -$(RM) $(ZX0PRGS) $(LZPRGS) -$(RM) *.o $(ASSEMBLE) $(DISKIMAGE) diff --git a/loader/samples/minexample/bin.cfg b/loader/samples/minexample/bin.cfg new file mode 100644 index 0000000..88a98b7 --- /dev/null +++ b/loader/samples/minexample/bin.cfg @@ -0,0 +1,11 @@ +MEMORY { + ZP: file = "", start = $0002, size = $00FE, define = yes; + MAIN: file = %O, start = $E000, size = $1FFA; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; +} diff --git a/loader/samples/minexample/font.bin b/loader/samples/minexample/font.bin index 60320e77e37014caa8e8ff567f7cc5d05c05b0f3..13078277a37661ec46e40c360db565fa87d49c7b 100644 GIT binary patch delta 7 OcmbQp(!jEii3tD*j{&~` delta 25 XcmZo*naIM#z_Wmfp8*N@@bCcuD8d3i diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index 3718b33..8497f4c 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -1,15 +1,691 @@ .feature c_comments +.include "../../build/loadersymbols-c64.inc" -.zeropage +.ZEROPAGE +.org $10 +bmp_delay: .res 1 +bmp_addr: .res 2 +bmp_ptr: .res 2 +scr_ptr_lo: .res 1 +scr_ptr: .res 2 +cram_ptr: .res 2 +chr_count: .res 1 +vbl: .res 1 +frame: .res 1 +cur_frame: .res 1 +frame_delay: .res 1 +frame_until: .res 1 +text_ptr: .res 2 +timer: .res 2 +timer_limit: .res 2 +timer_reached: .res 2 +timer_mode: .res 1 +enable_music: .res 1 +temp: .res 3 + +.include "lz_zp.asm" + +zx02 = $082f +check_return = $08b5 +CODE_START_ADDR = $e000 +aart_lz_buffer = $fd00 .segment "CODE" -.org $080D -main: - sei - lda #$35 - sta $01 +ZP=$e0 +offset = ZP+0 +ZX0_src = ZP+2 +ZX0_dst = ZP+4 +bitr = ZP+6 +pntr = ZP+7 + + .org CODE_START_ADDR +code_start: + lda #0 + sta $d020 + sta ZX0_dst+0 + lda #$0b + sta $d011 + jsr load_font + .assert * = CODE_START_ADDR + 15, error + lda #0 + sta enable_music + jsr init_2x + jsr clr_txt + ldx #copyright + jsr write_txt3 + ldx #$00 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #badguy + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$90 + ldy #$01 + jsr txt_fade_out + + sei + jsr init_bmp + jsr set_irq_badguy + lda #0 + sta vbl + cli + + jsr intro + + lda #$0b + sta $d011 + + sei + ldx #introname + lda #$10 + jsr load_8000_zx02 + + ldx #song0name + lda #$a0 + jsr load_8000_zx02 + + lda #fake_kernal_irq + sta $ffff + inc enable_music + + jsr run_nufli_bmp + sei + jsr init_2x + lda #$0b + sta $d011 + + jsr clr_txt + ldx #story_writ + jsr write_txt3 + ldx #$30 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #towername + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$b8 + ldy #$01 + jsr txt_fade_out + + jsr init_bmp + + lda #0 + sta vbl + + lda #$11 + jsr wait_frame_until_2x + + ldx #$6c +: + jsr wait_frame + jsr wait_frame + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #scenario_writ + jsr write_txt2 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #towerbeamname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$90 + ldy #$01 + jsr txt_fade_out + + jsr init_bmp + + lda #0 + sta vbl + + lda #$0d + jsr wait_frame_until_2x + lda bmp_addr + sta temp + lda bmp_addr+1 + sta temp+1 + lda cur_frame + sta temp+2 + + ldx #17 +: + txa + pha + lda temp+2 + sta cur_frame + lda temp + sta bmp_addr + lda temp+1 + sta bmp_addr+1 + lda #$0d+3 + jsr wait_frame_until_2x + pla + tax + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #prog_writ + jsr write_txt2 + ldx #$a8 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #fieldname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + jsr txt_fade_out + + jsr init_bmp + + lda #0 + sta vbl + + lda #$08 + jsr wait_frame_until_2x + lda bmp_addr + sta temp + lda bmp_addr+1 + sta temp+1 + lda cur_frame + sta temp+2 + + ldx #2 +: + txa + pha + lda temp+2 + sta cur_frame + lda temp + sta bmp_addr + lda temp+1 + sta bmp_addr+1 + lda #$08+8 + jsr wait_frame_until_2x + pla + tax + dex + bpl :- + + + lda #0 + sta vbl + lda #$27 + jsr wait_frame_until_2x + + ldx #25 +: + jsr wait_frame + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #gart_writ + jsr write_txt5 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #fallingstarname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + jsr txt_fade_out + + jsr init_bmp + + lda #$1d + jsr wait_frame_until_2x + + ldx #5 +: + jsr wait_frame + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #music_writ + jsr write_txt4 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #lilianame + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$10 + ldy #$01 + lda #8*11 + jsr txt_fade_out_offset + + ldx #$c4 + ldy #$01 + jsr init_timer + + jsr init_bmp + + lda #$08 + jsr wait_frame_until_2x + +: + lda timer_reached + beq :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #scene_writ + jsr write_txt3 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #liliaheroname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$20 + ldy #$01 + jsr txt_fade_out + + jsr init_bmp + + ldx #4 +: + lda #0 + sta vbl + lda #60 +: + cmp vbl + bne :- + dex + bpl :-- + +part_9: + ; $0400-$07ff buffer 0 tilemap + ; $2000-$3fff buffer 0 bitmap + ; $4000-$5fff buffer 1 bitmap + ; $6000-$63ff buffer 1 tilemap + ; $6400-$6417 next buffer CRAM + ; $7000-$77ff tileset bitmap + ; $7800-$78ff tileset tile colors + ; $7900-$79ff tileset CRAM colors + ; $9000- compressed tilemap + + jsr clr_txt + ldx #art_direct + jsr write_txt2 + ldx #$c0 + ldy #$01 + jsr init_timer + + lda #1 + sta timer_mode + + ldx #islandname + lda #$70 + jsr load_8000_zx02 + ldx #islandmapname + jsr loadraw + ldx #0 + ldy #$90 + jsr LZ_init_decomp + +: + lda timer_reached + beq :- + + ldx #$90 + ldy #$01 + lda #8 + jsr txt_fade_out_offset + + lda #0 + sta $d011 + jsr clear_2bufs + + ; set up sprites to cover scrolling + lda #$ff + ldx #0 +: sta $2000,x + sta $4000,x + inx + bne :- + .repeat 4, I + ldx #I*48+$58 + stx $d000+I*2 + stx $d008+I*2 + .endrepeat + ldx #6 +: + lda #$42 + sta $d001,x + lda #$d7 + sta $d009,x + dex + dex + bpl :- + ldx #7 +: + lda #$80 + sta $07f8,x + lda #0 + sta $63f8,x + sta $d027,x + dex + bpl :- + stx $d01d + stx $d015 + inx + stx $d010 + stx $d017 + stx $d01b + stx $d01c + stx frame + + lda #$18 + sta $d018 + lda #<((17+4)*40+$408) + sta text_ptr + lda #>((17+4)*40+$408) + sta text_ptr+1 + ldx #16 +: + lda #0 + lda text_ptr + sec + sbc #40 + sta text_ptr + sta scr_ptr + sta cram_ptr + sta bmp_ptr + lda text_ptr+1 + sbc #0 + sta text_ptr+1 + sta scr_ptr+1 + ; carry is always set here + adc #$d8-$04-1 + sta cram_ptr+1 + adc #<(($20>>3)-$d8) + asl bmp_ptr + rol a + asl bmp_ptr + rol a + asl bmp_ptr + rol a + sta bmp_ptr+1 + stx temp+1 + jsr drawrow + ldx temp+1 + dex + bpl :- + lda #0 + sta cram_ptr + lda #$64 + sta cram_ptr+1 +: + lda $d011 + bpl :- + lda #$38 + sta $d011 + lda #$18 + sta $d016 + lda #3 + sta timer_mode +@loop: + lda #0 + sta vbl + lda frame + cmp #$e1 + bcc :+ + jmp @finish +: + and #1 + tax + jsr copybuf + jsr drawrow +: + lda vbl + cmp #32 + bcc :- + ; B U M R U S H C R A M C O P Y F U N K + ldy #23 +: .repeat 16, I + lda $d808+(19-I)*40,y + sta $d808+(20-I)*40,y + .endrepeat + lda $6400,y + sta $d808+4*40,y + dey + bpl :- + inc frame + lda frame + lsr a + lda #$18 + ldx #3 + bcc :+ + lda #$80 + ldx #2 +: + sta $d018 + stx $dd00 + jmp @loop + +@finish: + ldx #$a8 + ldy #$01 + jsr init_timer +: + lda timer_reached + beq :- + lda #$0b + sta $d011 + lda #0 + sta $d015 + lda #3 + sta $dd00 + + ; we run out of space before the fixed location vector return now + jmp part_10 + +drawrow: + ldy #0 +charloop: + sty temp + lda #$70>>3 + sta bmp_addr+1 + jsr LZ_get_byte + tax + asl a + rol bmp_addr+1 + asl a + rol bmp_addr+1 + asl a + rol bmp_addr+1 + sta bmp_addr + ldy #0 + .repeat 8, I + lda (bmp_addr),y + sta (bmp_ptr),y + iny + .endrepeat + clc + lda bmp_ptr + adc #8 + sta bmp_ptr + bne :+ + inc bmp_ptr+1 +: + ldy temp + lda $7800,x + sta (scr_ptr),y + lda $7900,x + sta (cram_ptr),y + iny + cpy #24 + bne charloop + rts + +intro: + lda #0 + jsr sfx_init + + lda #7 + jsr wait_frame_until + + lda #64 + sta frame_delay + jsr wait_loop + + lda #1 + jsr sfx_init + + ldx #darmtower_txt + jsr upload_text + ldx #<(darmtower_txt+40) + ldy #>(darmtower_txt+40) + jsr upload_text_bottom + + lda #50*5 + sta frame_delay + jsr wait_loop + + jsr clear_text + + lda #$0d + jsr wait_frame_until + + ldx #adol_win + jsr upload_text + ldx #<(adol_win+40) + ldy #>(adol_win+40) + jsr upload_text_bottom + + lda #50*5 + sta frame_delay + jsr wait_loop + + jsr clear_text + ldx #too_bad_txt + jsr upload_text + + lda #50*5 + sta frame_delay + jsr wait_loop + + jsr clear_text + + lda #$13 + jsr wait_frame_until + + lda #0 + jsr sfx_init + + lda #$1a + jsr wait_frame_until + + lda #120 + sta frame_delay + jmp wait_loop + +wait_frame: +@loop: + bit $d011 + bpl @loop +@loop2: + bit $d011 + bmi @loop2 + rts + +init_2x: lda #127 sta $dc0d @@ -19,9 +695,9 @@ main: lda $dc0d lda $dd0d - lda #irq + lda #>irq_music sta $ffff lda #$0b @@ -29,13 +705,29 @@ main: lda #$00 sta $d012 +position_2x_to_display: + lda #50 +position_2x: +: + bit $d011 + bpl :- +: + bit $d011 + bmi :- +: + cmp $d012 + bne :- + lda #0 sta $d01a + sta $dc0e lda #$63; <(985248/100) sta $dc04 - lda #$26;>(985248/100) + lda #$26; >(985248/100) sta $dc05 + lda #$11 + sta $dc0e lda $dc0d and #$81 @@ -47,10 +739,43 @@ main: lda #$81 sta $dc0d - lda #0 - jsr $1000 +@loop: + bit $d011 + bpl @loop +@loop2: + bit $d011 + bmi @loop2 cli - jmp * + rts + +init_timer: + lda #0 + sta timer_reached + sta timer_mode + sta timer + sta timer+1 + stx timer_limit + sty timer_limit+1 + rts + +fade_cols: + .byte 0, 0 + .byte $0, $0, $0, $0, $b, $c, $f, $1 + .res 32-10, $1 + +fake_kernal_irq: + pha + txa + pha + tya + pha + tsx + lda $0104, x + and #$10 + beq :+ + jmp ($0314) +: + jmp ($0314) ; fuck you irq_music: pha @@ -59,18 +784,1049 @@ irq_music: tya pha - inc $d020 - jsr $1003 - dec $d020 + lda $dd00 + and #3 + sta @dd00_arc+1 + and #3 + sta $dd00 + + inc vbl + + ;inc $d020 + lda enable_music + beq :+ + jsr $a003 +: + ;dec $d020 + + lda timer_mode + cmp #1 + bne :+ + lda timer+1 + bne :+ + lda timer + lsr + lsr + lsr + tax + lda fade_cols, x + sta $d021 +: + lda timer_mode + cmp #2 + bne :+ + lda timer+1 + bne :+ + lda timer + lsr + lsr + lsr + eor #31 + tax + lda fade_cols, x + sta $d021 +: + + inc timer + bne :+ + inc timer+1 +: + lda timer + sec + sbc timer_limit + lda timer+1 + sbc timer_limit+1 + bcc :+ + lda #1 + sta timer_reached +: + lda timer_mode + cmp #3 + bne @timer_done + lda vbl + lsr a + bcs @timer_done + lsr a + and #7 + ora #$38 + sta $d011 + +@timer_done: + +@dd00_arc: + lda #0 + sta $dd00 pla tay pla tax pla - ;rti jmp $dc0c - -.res $1000-* -.incbin "ys2_sid.sid", $7e+($1000-$ff6) \ No newline at end of file +wait_loop: +@loop2: + lda vbl + beq @loop2 + + lda #0 + sta vbl + + lda enable_music + bne :+ + jsr sfx_play +: + + dec frame_delay + lda frame_delay + beq :+ + jmp @loop2 +: + rts + +wait_frame_until: + sta frame_until +@loop: + lda vbl + beq @loop + + lda #0 + sta vbl + + lda cur_frame + cmp #2 + bcc :+ + jsr sfx_play +: + + dec bmp_delay + bpl :+ + jsr update_bmp +: + + lda cur_frame + cmp frame_until + beq :+ + + jmp @loop +: + rts + +wait_frame_until_2x: + sta frame_until +@loop: + lda vbl + cmp #2 + bcc @loop + + lda #0 + sta vbl + + dec bmp_delay + bpl :+ + jsr update_bmp +: + + lda cur_frame + cmp frame_until + beq :+ + jmp @loop +: + rts + +init_bmp: + lda #$0b + sta $d011 + lda #$19 + sta $d018 + lda #$d8 + sta $d016 + + lda $4710 + lsr + lsr + lsr + lsr + sta $d020 + + lda $4710 + and #$0f + sta $d021 + + lda #0 + sta cur_frame + sta bmp_delay + + lda #$11 + sta bmp_addr + lda #$47 + sta bmp_addr+1 + + ldx #0 +: + .repeat 4, I + lda $3f40+(I*250), x + sta $400+(I*250), x + lda $4328+(I*250), x + sta $d800+(I*250), x + .endrepeat + inx + cpx #250 + bne :- + + lda #$3b + sta $d011 + rts + +inc_bmp_addr: + inc bmp_addr + bne :+ + inc bmp_addr+1 +: + rts + +update_bmp: + ldy #0 + sty scr_ptr + sty cram_ptr + lda (bmp_addr), y + jsr inc_bmp_addr + sta chr_count + cmp #0 ; tfw flags update in inc_bmp_addr + bne @skip_frame_end + lda (bmp_addr), y + jsr inc_bmp_addr + sta bmp_delay + inc cur_frame + rts +@skip_frame_end: + + lda (bmp_addr), y + sta bmp_ptr + iny + lda (bmp_addr), y + clc + adc #$20 + sta bmp_ptr+1 + + iny + lda (bmp_addr), y + sta scr_ptr_lo + iny + lda (bmp_addr), y + clc + adc #$04 + sta scr_ptr+1 + clc + adc #$d8-$04 + sta cram_ptr+1 + + ldy #0 + lda bmp_addr + clc + adc #4 + sta bmp_addr + bcc :+ + inc bmp_addr+1 +: + + ldx #0 +@loop: + ldy #0 + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + + lda bmp_ptr + clc + adc #8 + sta bmp_ptr + bcc :+ + inc bmp_ptr+1 +: + + ldy #8 + lda (bmp_addr), y + ldy scr_ptr_lo + sta (scr_ptr), y + + ldy #9 + lda (bmp_addr), y + ldy scr_ptr_lo + sta (cram_ptr), y + + inc scr_ptr_lo + bne :+ + inc scr_ptr+1 + inc cram_ptr+1 +: + + lda bmp_addr + clc + adc #10 + sta bmp_addr + bcc :+ + inc bmp_addr+1 +: + + dec chr_count + ldx chr_count + bne @loop + jmp update_bmp + +irq_badguy: + pha + + pha + pla + pha + pla + pha + pla + lda #$1b + sta $d011 + lda #$c8 + sta $d016 + lda #$13 + sta $d018 + lda #1 + sta $d021 + + lda #irq_badguy2 + sta $ffff + lda #$fb + sta $d012 + + asl $d019 + pla + rti + +irq_badguy2: + pha + + inc vbl + lda #$3b + sta $d011 + lda #$d8 + sta $d016 + lda #$19 + sta $d018 + lda #0 + sta $d021 + + lda #irq_badguy + sta $ffff + lda #$d2 + sta $d012 + + lda enable_music + beq :+ + txa + pha + tya + pha + jsr $a003 + pla + tay + pla + tax +: + asl $d019 + pla + rti + +set_irq_badguy: + lda #127 + sta $dc0d + + and $d011 + sta $d011 + + lda $dc0d + lda $dd0d + + lda #irq_badguy + sta $ffff + + lda #$d2 + sta $d012 + lda #1 + sta $d01a + asl $d019 + rts + +badguy: .byte "badguy",0 +fontname: .byte "font",0 +song0name: .byte "song0", 0 +song1name: .byte "song1", 0 +introname: .byte "intrbmp", 0 +towername: .byte "tower", 0 +towerbeamname: .byte "towerbm", 0 +fieldname: .byte "field", 0 +fallingstarname: .byte "fallstar", 0 +lilianame: .byte "lilia", 0 +liliaheroname: .byte "lilhero", 0 +islandname: .byte "island", 0 +islandmapname: .byte "islandmap", 0 +cloudsname: .byte "clouds", 0 +liliatalkname: .byte "liltalk", 0 + + +darmtower_txt: + .byte " darm's tower has fallen silent. " + .byte " what should we do? " + +adol_win: + .byte " ", 34, "it must be adol, let's see " + .byte " how far he'll get!", 34, " " + +too_bad_txt: + .byte " as you command. " + +upload_text: + stx text_ptr + sty text_ptr+1 + + ldy #39 +: + lda (text_ptr), y + clc + adc #$60 + sta $748, y + dey + bpl :- + rts + +upload_text_bottom: + stx text_ptr + sty text_ptr+1 + + ldy #39 +: + lda (text_ptr), y + clc + adc #$60 + sta $748+40+40, y + dey + bpl :- + rts + +clear_text: + lda #$80 + ldy #39 +: + sta $748, y + sta $748+40+40, y + dey + bpl :- + rts + +run_nufli_bmp: + lda #$01 + sta $81 + lda #$29 + sta $80 + lda #0 + sta $d01a + asl $d019 + jsr $a000 + jsr $3000 +@loop: + bit $d011 + bpl @loop + jsr $a003 +@loop2: + bit $d011 + bmi @loop2 + lda #0 + sta $d020 + sta $d021 + jsr $a003 + lda $80 + bne :+ + dec $81 +: + dec $80 + lda $81 + cmp #$ff + beq :+ + jmp @loop +: + lda #0 + sta $d015 + rts + + +.res $ea31-*, $ff + ;asl $d019 + pla + tay + pla + tax + pla + rti + +.res $ea81-*, $ff + ;asl $d019 + pla + tay + pla + tax + pla + rti + +.include "sfx.asm" +.include "thcmod_lz.asm" + +zx02_8000: + pha + jmp :+ + +load_8000_zx02_2000: + lda #$20 +load_8000_zx02: + pha + jsr loadraw +: + lda #0 + sta ZX0_src + sta ZX0_dst + lda #$80 + sta ZX0_src+1 + pla + jmp zx02 + +load_font: + bcc :+ + pha +: + ldx #fontname + jsr loadraw + bcs :- + rts + +part_10: + ; the sprite data is embedded into first few bitmap pixels + ; which are hidden by black border attributes +@y = 93 + jsr clr_txt + ldx #total_direct + jsr write_txt2 + ldx #$c0 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #cloudsname + jsr load_8000_zx02_2000 +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + lda #$40 + jsr txt_fade_out_offset + + jsr init_bmp + ldx #0 + stx $d010 + stx $d017 + stx $d01d + stx $d025 + stx frame + dex + stx $d01b + stx $d01c + lda #11 + sta $d026 + lda #@y+48 + jsr position_2x + lda #0 + sta vbl + ; draw top half +@loop: + bit $d011 + bpl @loop + ldx #0 + ldy #0 + lda frame + bpl :+ + jmp @finish +: + cmp #$74 + bcc :+ + lda #$74 +: + pha +: + clc + adc @sprxs,x + sta $d000,y + sta temp + lda @sprys,x + sta $d001,y + txa + ora #$80 + sta $7f8,x + lda @sprcols,x + sta $d027,x + lda temp + iny + iny + inx + cpx #8 + bcc :- + lda #$ff + sta $d015 + + ; draw bottom half +: + bit $d011 + bmi :- + lda #@y+37 +: + cmp $d012 + bcs :- + + ldx #0 + ldy #0 + pla + clc +: + adc @sprxs+8,x + sta $d000,y + sta temp + lda @sprys+8,x + sta $d001,y + txa + ora #$88 + sta $7f8,x + lda @sprcols+8,x + sta $d027,x + lda temp + iny + iny + inx + cpx #6 + bcc :- + + lda vbl + and #15 + bne :+ + inc frame +: + jmp @loop + +@sprxs: + .byte 48, <-24, 24, 24, <-64, 24, 24, 24 + .byte 48-40, 24, 24, 24, <-44, 24 + +@sprys: + .byte @y-8, @y, @y, @y, @y+21, @y+21, @y+21, @y+21 + .byte @y+42, @y+42, @y+42, @y+42, @y+63, @y+63 + +@sprcols: + .byte 2, 5, 5, 5, 14, 14, 14, 6 + .byte 2, 2, 2, 9, 2, 2 + +@finish: + lda #$0b + sta $d011 + lda #0 + sta $d015 + + jsr clr_txt + ldx #produced + jsr write_txt2 + ldx #$c0 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + lda #8*11 + jsr txt_fade_out_offset + +part_11: + jsr clr_txt + ldx #presented + jsr write_txt1 + ldx #$c0 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #liliatalkname + jsr load_8000_zx02_2000 +: + lda timer_reached + beq :- + + ; tell the music to end and wait +: + lda #1 + jsr $a006 + cmp #17 + bne :- + + ldx #$00 + ldy #$01 + lda #8*11 + jsr txt_fade_out_offset +: + lda timer_reached + beq :- + + ; load new music + sei + ldx #song1name + lda #$a0 + jsr load_8000_zx02 + jsr $a000 + jsr init_bmp + jsr set_irq_badguy + inc enable_music + cli + + lda #<256 + jsr wait_frame_until + lda #301-256 + jsr wait_frame_until + + sei + lda #$0b + sta $d011 + ldx #64 +: + jsr wait_frame + dex + bpl :- + jsr clr_txt + ldx #turn_disk + jsr write_txt2 + lda #1 + sta $d021 + jmp check_return + +clear_2bufs: + ldy #$44 + .byte $2c ; skip next instruction +clear_buf: + ldy #$20 + lda #$20 + sta @dst+2 + lda #0 + tax +: + sta $400,x + sta $500,x + sta $600,x + sta $700,x + inx + bne :- +@dst: + sta $2000,x + inx + bne @dst + inc @dst+2 + dey + bne @dst + rts + +copybuf: + lda @bsrclo,x + sta bmp_addr + lda @bsrchi,x + sta bmp_addr+1 + lda @bdstlo,x + sta bmp_ptr + lda @bdsthi,x + sta bmp_ptr+1 + lda @tsrclo,x + sta text_ptr + lda @tsrchi,x + sta text_ptr+1 + lda @tdstlo,x + sta scr_ptr + lda @tdsthi,x + sta scr_ptr+1 + ldx #16 +@loop: + ldy #23 +: lda (text_ptr),y + sta (scr_ptr),y + dey + bpl :- + ldy #191 +: lda (bmp_addr),y + sta (bmp_ptr),y + dey + bne :- + lda (bmp_addr),y + sta (bmp_ptr),y + ; math dumb cpu be struggling a lot here + lda text_ptr + sec + sbc #40 + sta text_ptr + bcs :+ + dec text_ptr+1 +: + lda scr_ptr + sec + sbc #40 + sta scr_ptr + bcs :+ + dec scr_ptr+1 +: + lda bmp_addr + sec + sbc #<320 + sta bmp_addr + bcs :+ + dec bmp_addr+1 +: + dec bmp_addr+1 + lda bmp_ptr + sec + sbc #<320 + sta bmp_ptr + bcs :+ + dec bmp_ptr+1 +: + dec bmp_ptr+1 + dex + bne @loop + rts + +@bsrclo: .lobytes (15+4)*320+$2040, (15+4)*320+$4040 +@bsrchi: .hibytes (15+4)*320+$2040, (15+4)*320+$4040 +@bdstlo: .lobytes (16+4)*320+$4040, (16+4)*320+$2040 +@bdsthi: .hibytes (16+4)*320+$4040, (16+4)*320+$2040 +@tsrclo: .lobytes (15+4)*40+$0408, (15+4)*40+$6008 +@tsrchi: .hibytes (15+4)*40+$0408, (15+4)*40+$6008 +@tdstlo: .lobytes (16+4)*40+$6008, (16+4)*40+$0408 +@tdsthi: .hibytes (16+4)*40+$6008, (16+4)*40+$0408 + +copyright: +.byte " ys ^ " +.byte " copyright 1988 falcom " +.byte " all right reserved " + +story_writ: +.byte " story written by " +.byte " takahiro ohura " +.byte " tomoo yamane " + +scenario_writ: +.byte " scenario written by " +.byte " tomoyoshi miyazaki " + +prog_writ: +.byte " programmed by " +.byte " masaya hashimoto " + +gart_writ: +.byte " graphic arts designed by " +.byte " takahiro ohura " +.byte " ayano koshiro " +.byte " kazuhiko tsuzuki " +.byte " tomoo yamane " + +music_writ: +.byte " music composed by " +.byte " mieko ishikawa " +.byte " yuzo koshiro " +.byte " hideya nagata " + +scene_writ: +.byte " scene set by " +.byte " seigo oketani " +.byte " yoshihiko kurata " + +art_direct: +.byte " art directed by " +.byte " seigo oketani " + +total_direct: +.byte " total directed by " +.byte " masaya hashimoto " + +produced: +.byte " produced by " +.byte " masayuki katoh " + +presented: +.byte " presented by falcom " + +turn_disk: +.byte " insert datadisk in " +.byte " drive 8 then return " + +clr_txt: + lda #$80 + ldx #0 +: + .repeat 4, I + sta $400+(I*250), x + .endrepeat + inx + cpx #250 + bne :- + lda #0 + ldx #0 +: + .repeat 4, I + sta $d800+(I*250), x + .endrepeat + inx + cpx #250 + bne :- + lda #$13 + sta $d018 + lda #$1b + sta $d011 + rts + +write_txt5: + stx text_ptr + sty text_ptr+1 + ldy #0 + lda #<($400+8*40) + ldx #>($400+8*40) + jsr write_txt_to + lda #<($400+10*40) + ldx #>($400+10*40) + jsr write_txt_to + lda #<($400+12*40) + ldx #>($400+12*40) + jsr write_txt_to + lda #<($400+14*40) + ldx #>($400+14*40) + jsr write_txt_to + lda #<($400+16*40) + ldx #>($400+16*40) + jmp write_txt_to + +write_txt4: + stx text_ptr + sty text_ptr+1 + ldy #0 + lda #<($400+9*40) + ldx #>($400+9*40) + jsr write_txt_to + lda #<($400+11*40) + ldx #>($400+11*40) + jsr write_txt_to + lda #<($400+13*40) + ldx #>($400+13*40) + jsr write_txt_to + lda #<($400+15*40) + ldx #>($400+15*40) + jmp write_txt_to + +write_txt3: + stx text_ptr + sty text_ptr+1 + ldy #0 + lda #<($400+10*40) + ldx #>($400+10*40) + jsr write_txt_to + lda #<($400+12*40) + ldx #>($400+12*40) + jsr write_txt_to + lda #<($400+14*40) + ldx #>($400+14*40) + jmp write_txt_to + +write_txt2: + stx text_ptr + sty text_ptr+1 + ldy #0 + lda #<($400+11*40) + ldx #>($400+11*40) + jsr write_txt_to + lda #<($400+13*40) + ldx #>($400+13*40) + jmp write_txt_to + +write_txt1: + stx text_ptr + sty text_ptr+1 + ldy #0 + lda #<($400+12*40) + ldx #>($400+12*40) + ; fall through + +write_txt_to: + sta @dst+1 + stx @dst+2 + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 +@dst: + sta $400, x + iny + inx + cpx #40 + bne :- + rts + +txt_fade_out: + lda #0 +txt_fade_out_offset: + pha + jsr init_timer + pla + sta timer + lda #2 + sta timer_mode +: + lda timer_reached + beq :- + rts diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 8572c53..76eca09 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -1,31 +1,6 @@ .feature c_comments .include "../../build/loadersymbols-c64.inc" -.ZEROPAGE -.org $10 -bmp_delay: .res 1 -bmp_addr: .res 2 -bmp_ptr: .res 2 -scr_ptr_lo: .res 1 -scr_ptr: .res 2 -cram_ptr: .res 2 -chr_count: .res 1 -vbl: .res 1 -frame: .res 1 -cur_frame: .res 1 -frame_delay: .res 1 -frame_until: .res 1 -text_ptr: .res 2 -timer: .res 2 -timer_limit: .res 2 -timer_reached: .res 2 -timer_mode: .res 1 -enable_music: .res 1 -temp: .res 3 - -aart_lz_buffer := $fd00 -.include "lz_zp.asm" - CODE_START_ADDR = $e000 .segment "CODE" @@ -45,43 +20,23 @@ copy_start: lda #$35 sta $01 - lda #code_start - sta $fd - - lda #code_load - sta $fb - - ldy #0 - ldx #>(code_end-code_start) - beq :+++ -: - lda ($fa), y - sta ($fc), y - iny - bne :- - inc $fb - inc $fd - dex - bne :- - beq :+ -: - lda ($fa), y - sta ($fc), y - iny -: - cpy #<(code_end-code_start) - bne :-- + lda #code + sta ZX0_src+1 + lda #CODE_START_ADDR + jsr zx02 inc $01 cli jsr install sei dec $01 - jmp code_start + jmp CODE_START_ADDR + +.include "zx02.asm" check_return: ; for some reason GETIN enable interrupts back @@ -96,7 +51,10 @@ check_return: cmp #$0d bne :- dec $01 - jmp code_start + jmp CODE_START_ADDR + + .assert zx02 = $082f, error, .sprintf("change zx02 address to $%04x", zx02) + .assert check_return = $08b5, error, .sprintf("change check_return address to $%04x", check_return) .res loadraw - * .incbin "../../build/loader-c64.prg", 2 @@ -104,1794 +62,4 @@ check_return: .res install - * .incbin "../../build/install-c64.prg", 2 -code_load: - .org CODE_START_ADDR -code_start: - lda #0 - sta $d020 - sta ZX0_dst+0 - lda #$0b - sta $d011 - jsr load_font - .assert * = CODE_START_ADDR + 15, error - lda #0 - sta enable_music - jsr init_2x - jsr clr_txt - ldx #copyright - jsr write_txt3 - ldx #$00 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #badguy - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$90 - ldy #$01 - jsr txt_fade_out - - sei - jsr init_bmp - jsr set_irq_badguy - lda #0 - sta vbl - cli - - jsr intro - - lda #$0b - sta $d011 - - sei - ldx #introname - lda #$10 - jsr load_8000_zx02 - - ldx #song0name - lda #$a0 - jsr load_8000_zx02 - - lda #fake_kernal_irq - sta $ffff - inc enable_music - - jsr run_nufli_bmp - sei - jsr init_2x - lda #$0b - sta $d011 - - jsr clr_txt - ldx #story_writ - jsr write_txt3 - ldx #$30 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #towername - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$b8 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #0 - sta vbl - - lda #$11 - jsr wait_frame_until_2x - - ldx #$6c -: - jsr wait_frame - jsr wait_frame - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #scenario_writ - jsr write_txt2 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #towerbeamname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$90 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #0 - sta vbl - - lda #$0d - jsr wait_frame_until_2x - lda bmp_addr - sta temp - lda bmp_addr+1 - sta temp+1 - lda cur_frame - sta temp+2 - - ldx #17 -: - txa - pha - lda temp+2 - sta cur_frame - lda temp - sta bmp_addr - lda temp+1 - sta bmp_addr+1 - lda #$0d+3 - jsr wait_frame_until_2x - pla - tax - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #prog_writ - jsr write_txt2 - ldx #$a8 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #fieldname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #0 - sta vbl - - lda #$08 - jsr wait_frame_until_2x - lda bmp_addr - sta temp - lda bmp_addr+1 - sta temp+1 - lda cur_frame - sta temp+2 - - ldx #2 -: - txa - pha - lda temp+2 - sta cur_frame - lda temp - sta bmp_addr - lda temp+1 - sta bmp_addr+1 - lda #$08+8 - jsr wait_frame_until_2x - pla - tax - dex - bpl :- - - - lda #0 - sta vbl - lda #$27 - jsr wait_frame_until_2x - - ldx #25 -: - jsr wait_frame - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #gart_writ - jsr write_txt5 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #fallingstarname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #$1d - jsr wait_frame_until_2x - - ldx #5 -: - jsr wait_frame - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #music_writ - jsr write_txt4 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #lilianame - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$10 - ldy #$01 - lda #8*11 - jsr txt_fade_out_offset - - ldx #$c4 - ldy #$01 - jsr init_timer - - jsr init_bmp - - lda #$08 - jsr wait_frame_until_2x - -: - lda timer_reached - beq :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #scene_writ - jsr write_txt3 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #liliaheroname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$20 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - ldx #4 -: - lda #0 - sta vbl - lda #60 -: - cmp vbl - bne :- - dex - bpl :-- - -part_9: - ; $0400-$07ff buffer 0 tilemap - ; $2000-$3fff buffer 0 bitmap - ; $4000-$5fff buffer 1 bitmap - ; $6000-$63ff buffer 1 tilemap - ; $6400-$6417 next buffer CRAM - ; $7000-$77ff tileset bitmap - ; $7800-$78ff tileset tile colors - ; $7900-$79ff tileset CRAM colors - ; $9000- compressed tilemap - - jsr clr_txt - ldx #art_direct - jsr write_txt2 - ldx #$c0 - ldy #$01 - jsr init_timer - - lda #1 - sta timer_mode - - ldx #islandname - lda #$70 - jsr load_8000_zx02 - ldx #islandmapname - jsr loadraw - ldx #0 - ldy #$90 - jsr LZ_init_decomp - -: - lda timer_reached - beq :- - - ldx #$90 - ldy #$01 - lda #8 - jsr txt_fade_out_offset - - lda #0 - sta $d011 - jsr clear_2bufs - - ; set up sprites to cover scrolling - lda #$ff - ldx #0 -: sta $2000,x - sta $4000,x - inx - bne :- - .repeat 4, I - ldx #I*48+$58 - stx $d000+I*2 - stx $d008+I*2 - .endrepeat - ldx #6 -: - lda #$42 - sta $d001,x - lda #$d7 - sta $d009,x - dex - dex - bpl :- - ldx #7 -: - lda #$80 - sta $07f8,x - lda #0 - sta $63f8,x - sta $d027,x - dex - bpl :- - stx $d01d - stx $d015 - inx - stx $d010 - stx $d017 - stx $d01b - stx $d01c - stx frame - - lda #$18 - sta $d018 - lda #<((17+4)*40+$408) - sta text_ptr - lda #>((17+4)*40+$408) - sta text_ptr+1 - ldx #16 -: - lda #0 - lda text_ptr - sec - sbc #40 - sta text_ptr - sta scr_ptr - sta cram_ptr - sta bmp_ptr - lda text_ptr+1 - sbc #0 - sta text_ptr+1 - sta scr_ptr+1 - ; carry is always set here - adc #$d8-$04-1 - sta cram_ptr+1 - adc #<(($20>>3)-$d8) - asl bmp_ptr - rol a - asl bmp_ptr - rol a - asl bmp_ptr - rol a - sta bmp_ptr+1 - stx temp+1 - jsr drawrow - ldx temp+1 - dex - bpl :- - lda #0 - sta cram_ptr - lda #$64 - sta cram_ptr+1 -: - lda $d011 - bpl :- - lda #$38 - sta $d011 - lda #$18 - sta $d016 - lda #3 - sta timer_mode -@loop: - lda #0 - sta vbl - lda frame - cmp #$e1 - bcc :+ - jmp @finish -: - and #1 - tax - jsr copybuf - jsr drawrow -: - lda vbl - cmp #32 - bcc :- - ; B U M R U S H C R A M C O P Y F U N K - ldy #23 -: .repeat 16, I - lda $d808+(19-I)*40,y - sta $d808+(20-I)*40,y - .endrepeat - lda $6400,y - sta $d808+4*40,y - dey - bpl :- - inc frame - lda frame - lsr a - lda #$18 - ldx #3 - bcc :+ - lda #$80 - ldx #2 -: - sta $d018 - stx $dd00 - jmp @loop - -@finish: - ldx #$a8 - ldy #$01 - jsr init_timer -: - lda timer_reached - beq :- - lda #$0b - sta $d011 - lda #0 - sta $d015 - lda #3 - sta $dd00 - - ; we run out of space before the fixed location vector return now - jmp part_10 - -drawrow: - ldy #0 -charloop: - sty temp - lda #$70>>3 - sta bmp_addr+1 - jsr LZ_get_byte - tax - asl a - rol bmp_addr+1 - asl a - rol bmp_addr+1 - asl a - rol bmp_addr+1 - sta bmp_addr - ldy #0 - .repeat 8, I - lda (bmp_addr),y - sta (bmp_ptr),y - iny - .endrepeat - clc - lda bmp_ptr - adc #8 - sta bmp_ptr - bne :+ - inc bmp_ptr+1 -: - ldy temp - lda $7800,x - sta (scr_ptr),y - lda $7900,x - sta (cram_ptr),y - iny - cpy #24 - bne charloop - rts - -intro: - lda #0 - jsr sfx_init - - lda #7 - jsr wait_frame_until - - lda #64 - sta frame_delay - jsr wait_loop - - lda #1 - jsr sfx_init - - ldx #darmtower_txt - jsr upload_text - ldx #<(darmtower_txt+40) - ldy #>(darmtower_txt+40) - jsr upload_text_bottom - - lda #50*5 - sta frame_delay - jsr wait_loop - - jsr clear_text - - lda #$0d - jsr wait_frame_until - - ldx #adol_win - jsr upload_text - ldx #<(adol_win+40) - ldy #>(adol_win+40) - jsr upload_text_bottom - - lda #50*5 - sta frame_delay - jsr wait_loop - - jsr clear_text - ldx #too_bad_txt - jsr upload_text - - lda #50*5 - sta frame_delay - jsr wait_loop - - jsr clear_text - - lda #$13 - jsr wait_frame_until - - lda #0 - jsr sfx_init - - lda #$1a - jsr wait_frame_until - - lda #120 - sta frame_delay - jmp wait_loop - -wait_frame: -@loop: - bit $d011 - bpl @loop -@loop2: - bit $d011 - bmi @loop2 - rts - -init_2x: - lda #127 - sta $dc0d - - and $d011 - sta $d011 - - lda $dc0d - lda $dd0d - - lda #irq_music - sta $ffff - - lda #$0b - sta $d011 - lda #$00 - sta $d012 - -position_2x_to_display: - lda #50 -position_2x: -: - bit $d011 - bpl :- -: - bit $d011 - bmi :- -: - cmp $d012 - bne :- - - lda #0 - sta $d01a - sta $dc0e - - lda #$63; <(985248/100) - sta $dc04 - lda #$26; >(985248/100) - sta $dc05 - lda #$11 - sta $dc0e - - lda $dc0d - and #$81 - sta $dc0d - - lda #$40 - sta $dc0c - - lda #$81 - sta $dc0d - -@loop: - bit $d011 - bpl @loop -@loop2: - bit $d011 - bmi @loop2 - cli - rts - -init_timer: - lda #0 - sta timer_reached - sta timer_mode - sta timer - sta timer+1 - stx timer_limit - sty timer_limit+1 - rts - -fade_cols: - .byte 0, 0 - .byte $0, $0, $0, $0, $b, $c, $f, $1 - .res 32-10, $1 - -fake_kernal_irq: - pha - txa - pha - tya - pha - tsx - lda $0104, x - and #$10 - beq :+ - jmp ($0314) -: - jmp ($0314) ; fuck you - -irq_music: - pha - txa - pha - tya - pha - - lda $dd00 - and #3 - sta @dd00_arc+1 - and #3 - sta $dd00 - - inc vbl - - ;inc $d020 - lda enable_music - beq :+ - jsr $a003 -: - ;dec $d020 - - lda timer_mode - cmp #1 - bne :+ - lda timer+1 - bne :+ - lda timer - lsr - lsr - lsr - tax - lda fade_cols, x - sta $d021 -: - lda timer_mode - cmp #2 - bne :+ - lda timer+1 - bne :+ - lda timer - lsr - lsr - lsr - eor #31 - tax - lda fade_cols, x - sta $d021 -: - - inc timer - bne :+ - inc timer+1 -: - lda timer - sec - sbc timer_limit - lda timer+1 - sbc timer_limit+1 - bcc :+ - lda #1 - sta timer_reached -: - lda timer_mode - cmp #3 - bne @timer_done - lda vbl - lsr a - bcs @timer_done - lsr a - and #7 - ora #$38 - sta $d011 - -@timer_done: - -@dd00_arc: - lda #0 - sta $dd00 - - pla - tay - pla - tax - pla - jmp $dc0c - -wait_loop: -@loop2: - lda vbl - beq @loop2 - - lda #0 - sta vbl - - jsr sfx_play - - dec frame_delay - lda frame_delay - beq :+ - jmp @loop2 -: - rts - -wait_frame_until: - sta frame_until -@loop: - lda vbl - beq @loop - - lda #0 - sta vbl - - lda cur_frame - cmp #2 - bcc :+ - jsr sfx_play -: - - dec bmp_delay - bpl :+ - jsr update_bmp -: - - lda cur_frame - cmp frame_until - beq :+ - - jmp @loop -: - rts - -wait_frame_until_2x: - sta frame_until -@loop: - lda vbl - cmp #2 - bcc @loop - - lda #0 - sta vbl - - dec bmp_delay - bpl :+ - jsr update_bmp -: - - lda cur_frame - cmp frame_until - beq :+ - jmp @loop -: - rts - -init_bmp: - lda #$0b - sta $d011 - lda #$19 - sta $d018 - lda #$d8 - sta $d016 - - lda $4710 - lsr - lsr - lsr - lsr - sta $d020 - - lda $4710 - and #$0f - sta $d021 - - lda #0 - sta cur_frame - sta bmp_delay - - lda #$11 - sta bmp_addr - lda #$47 - sta bmp_addr+1 - - ldx #0 -: - .repeat 4, I - lda $3f40+(I*250), x - sta $400+(I*250), x - lda $4328+(I*250), x - sta $d800+(I*250), x - .endrepeat - inx - cpx #250 - bne :- - - lda #$3b - sta $d011 - rts - -inc_bmp_addr: - inc bmp_addr - bne :+ - inc bmp_addr+1 -: - rts - -update_bmp: - ldy #0 - sty scr_ptr - sty cram_ptr - lda (bmp_addr), y - jsr inc_bmp_addr - sta chr_count - cmp #0 ; tfw flags update in inc_bmp_addr - bne @skip_frame_end - lda (bmp_addr), y - jsr inc_bmp_addr - sta bmp_delay - inc cur_frame - rts -@skip_frame_end: - - lda (bmp_addr), y - sta bmp_ptr - iny - lda (bmp_addr), y - clc - adc #$20 - sta bmp_ptr+1 - - iny - lda (bmp_addr), y - sta scr_ptr_lo - iny - lda (bmp_addr), y - clc - adc #$04 - sta scr_ptr+1 - clc - adc #$d8-$04 - sta cram_ptr+1 - - ldy #0 - lda bmp_addr - clc - adc #4 - sta bmp_addr - bcc :+ - inc bmp_addr+1 -: - - ldx #0 -@loop: - ldy #0 - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - - lda bmp_ptr - clc - adc #8 - sta bmp_ptr - bcc :+ - inc bmp_ptr+1 -: - - ldy #8 - lda (bmp_addr), y - ldy scr_ptr_lo - sta (scr_ptr), y - - ldy #9 - lda (bmp_addr), y - ldy scr_ptr_lo - sta (cram_ptr), y - - inc scr_ptr_lo - bne :+ - inc scr_ptr+1 - inc cram_ptr+1 -: - - lda bmp_addr - clc - adc #10 - sta bmp_addr - bcc :+ - inc bmp_addr+1 -: - - dec chr_count - ldx chr_count - bne @loop - jmp update_bmp - -irq_badguy: - pha - - pha - pla - pha - pla - pha - pla - lda #$1b - sta $d011 - lda #$c8 - sta $d016 - lda #$13 - sta $d018 - lda #1 - sta $d021 - - lda #irq_badguy2 - sta $ffff - lda #$fb - sta $d012 - - asl $d019 - pla - rti - -irq_badguy2: - pha - - inc vbl - lda #$3b - sta $d011 - lda #$d8 - sta $d016 - lda #$19 - sta $d018 - lda #0 - sta $d021 - - lda #irq_badguy - sta $ffff - lda #$d2 - sta $d012 - - lda enable_music - beq :+ - txa - pha - tya - pha - jsr $a003 - pla - tay - pla - tax -: - asl $d019 - pla - rti - -set_irq_badguy: - lda #127 - sta $dc0d - - and $d011 - sta $d011 - - lda $dc0d - lda $dd0d - - lda #irq_badguy - sta $ffff - - lda #$d2 - sta $d012 - lda #1 - sta $d01a - asl $d019 - rts - -badguy: .byte "badguy",0 -fontname: .byte "font",0 -song0name: .byte "song0", 0 -song1name: .byte "song1", 0 -introname: .byte "intrbmp", 0 -towername: .byte "tower", 0 -towerbeamname: .byte "towerbm", 0 -fieldname: .byte "field", 0 -fallingstarname: .byte "fallstar", 0 -lilianame: .byte "lilia", 0 -liliaheroname: .byte "lilhero", 0 -islandname: .byte "island", 0 -islandmapname: .byte "islandmap", 0 -cloudsname: .byte "clouds", 0 -liliatalkname: .byte "liltalk", 0 - - -darmtower_txt: - .byte " darm's tower has fallen silent. " - .byte " what should we do? " - -adol_win: - .byte " ", 34, "it must be adol, let's see " - .byte " how far he'll get!", 34, " " - -too_bad_txt: - .byte " as you command. " - -upload_text: - stx text_ptr - sty text_ptr+1 - - ldy #39 -: - lda (text_ptr), y - clc - adc #$60 - sta $748, y - dey - bpl :- - rts - -upload_text_bottom: - stx text_ptr - sty text_ptr+1 - - ldy #39 -: - lda (text_ptr), y - clc - adc #$60 - sta $748+40+40, y - dey - bpl :- - rts - -clear_text: - lda #$80 - ldy #39 -: - sta $748, y - sta $748+40+40, y - dey - bpl :- - rts - -run_nufli_bmp: - lda #$01 - sta $81 - lda #$29 - sta $80 - lda #0 - sta $d01a - asl $d019 - jsr $a000 - jsr $3000 -@loop: - bit $d011 - bpl @loop - jsr $a003 -@loop2: - bit $d011 - bmi @loop2 - lda #0 - sta $d020 - sta $d021 - jsr $a003 - lda $80 - bne :+ - dec $81 -: - dec $80 - lda $81 - cmp #$ff - beq :+ - jmp @loop -: - lda #0 - sta $d015 - rts - - -.res $ea31-*, $ff - ;asl $d019 - pla - tay - pla - tax - pla - rti - -.res $ea81-*, $ff - ;asl $d019 - pla - tay - pla - tax - pla - rti - -.include "sfx.asm" -.include "zx02.asm" -.include "thcmod_lz.asm" - -zx02_8000: - pha - jmp :+ - -load_8000_zx02_2000: - lda #$20 -load_8000_zx02: - pha - jsr loadraw -: - lda #0 - sta ZX0_src - sta ZX0_dst - lda #$80 - sta ZX0_src+1 - pla - jmp zx02 - -load_font: - bcc :+ - pha -: - ldx #fontname - jsr loadraw - bcs :- - rts - -part_10: - ; the sprite data is embedded into first few bitmap pixels - ; which are hidden by black border attributes -@y = 93 - jsr clr_txt - ldx #total_direct - jsr write_txt2 - ldx #$c0 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #cloudsname - jsr load_8000_zx02_2000 -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - lda #$40 - jsr txt_fade_out_offset - - jsr init_bmp - ldx #0 - stx $d010 - stx $d017 - stx $d01d - stx $d025 - stx frame - dex - stx $d01b - stx $d01c - lda #11 - sta $d026 - lda #@y+48 - jsr position_2x - lda #0 - sta vbl - ; draw top half -@loop: - bit $d011 - bpl @loop - ldx #0 - ldy #0 - lda frame - bpl :+ - jmp @finish -: - cmp #$74 - bcc :+ - lda #$74 -: - pha -: - clc - adc @sprxs,x - sta $d000,y - sta temp - lda @sprys,x - sta $d001,y - txa - ora #$80 - sta $7f8,x - lda @sprcols,x - sta $d027,x - lda temp - iny - iny - inx - cpx #8 - bcc :- - lda #$ff - sta $d015 - - ; draw bottom half -: - bit $d011 - bmi :- - lda #@y+37 -: - cmp $d012 - bcs :- - - ldx #0 - ldy #0 - pla - clc -: - adc @sprxs+8,x - sta $d000,y - sta temp - lda @sprys+8,x - sta $d001,y - txa - ora #$88 - sta $7f8,x - lda @sprcols+8,x - sta $d027,x - lda temp - iny - iny - inx - cpx #6 - bcc :- - - lda vbl - and #15 - bne :+ - inc frame -: - jmp @loop - -@sprxs: - .byte 48, <-24, 24, 24, <-64, 24, 24, 24 - .byte 48-40, 24, 24, 24, <-44, 24 - -@sprys: - .byte @y-8, @y, @y, @y, @y+21, @y+21, @y+21, @y+21 - .byte @y+42, @y+42, @y+42, @y+42, @y+63, @y+63 - -@sprcols: - .byte 2, 5, 5, 5, 14, 14, 14, 6 - .byte 2, 2, 2, 9, 2, 2 - -@finish: - lda #$0b - sta $d011 - lda #0 - sta $d015 - - jsr clr_txt - ldx #produced - jsr write_txt2 - ldx #$c0 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - lda #8*11 - jsr txt_fade_out_offset - -part_11: - jsr clr_txt - ldx #presented - jsr write_txt1 - ldx #$c0 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #liliatalkname - jsr load_8000_zx02_2000 -: - lda timer_reached - beq :- - - ; tell the music to end and wait -: - lda #1 - jsr $a006 - cmp #17 - bne :- - - ldx #$00 - ldy #$01 - lda #8*11 - jsr txt_fade_out_offset -: - lda timer_reached - beq :- - - ; load new music - sei - ldx #song1name - lda #$a0 - jsr load_8000_zx02 - jsr $a000 - jsr init_bmp - jsr set_irq_badguy - inc enable_music - cli - - lda #<256 - jsr wait_frame_until - lda #301-256 - jsr wait_frame_until - - sei - lda #$0b - sta $d011 - ldx #64 -: - jsr wait_frame - dex - bpl :- - jsr clr_txt - ldx #turn_disk - jsr write_txt2 - lda #1 - sta $d021 - jmp check_return - -clear_2bufs: - ldy #$44 - .byte $2c ; skip next instruction -clear_buf: - ldy #$20 - lda #$20 - sta @dst+2 - lda #0 - tax -: - sta $400,x - sta $500,x - sta $600,x - sta $700,x - inx - bne :- -@dst: - sta $2000,x - inx - bne @dst - inc @dst+2 - dey - bne @dst - rts - -copybuf: - lda @bsrclo,x - sta bmp_addr - lda @bsrchi,x - sta bmp_addr+1 - lda @bdstlo,x - sta bmp_ptr - lda @bdsthi,x - sta bmp_ptr+1 - lda @tsrclo,x - sta text_ptr - lda @tsrchi,x - sta text_ptr+1 - lda @tdstlo,x - sta scr_ptr - lda @tdsthi,x - sta scr_ptr+1 - ldx #16 -@loop: - ldy #23 -: lda (text_ptr),y - sta (scr_ptr),y - dey - bpl :- - ldy #191 -: lda (bmp_addr),y - sta (bmp_ptr),y - dey - bne :- - lda (bmp_addr),y - sta (bmp_ptr),y - ; math dumb cpu be struggling a lot here - lda text_ptr - sec - sbc #40 - sta text_ptr - bcs :+ - dec text_ptr+1 -: - lda scr_ptr - sec - sbc #40 - sta scr_ptr - bcs :+ - dec scr_ptr+1 -: - lda bmp_addr - sec - sbc #<320 - sta bmp_addr - bcs :+ - dec bmp_addr+1 -: - dec bmp_addr+1 - lda bmp_ptr - sec - sbc #<320 - sta bmp_ptr - bcs :+ - dec bmp_ptr+1 -: - dec bmp_ptr+1 - dex - bne @loop - rts - -@bsrclo: .lobytes (15+4)*320+$2040, (15+4)*320+$4040 -@bsrchi: .hibytes (15+4)*320+$2040, (15+4)*320+$4040 -@bdstlo: .lobytes (16+4)*320+$4040, (16+4)*320+$2040 -@bdsthi: .hibytes (16+4)*320+$4040, (16+4)*320+$2040 -@tsrclo: .lobytes (15+4)*40+$0408, (15+4)*40+$6008 -@tsrchi: .hibytes (15+4)*40+$0408, (15+4)*40+$6008 -@tdstlo: .lobytes (16+4)*40+$6008, (16+4)*40+$0408 -@tdsthi: .hibytes (16+4)*40+$6008, (16+4)*40+$0408 - -copyright: -.byte " ys ^ " -.byte " copyright 1988 falcom " -.byte " all right reserved " - -story_writ: -.byte " story written by " -.byte " takahiro ohura " -.byte " tomoo yamane " - -scenario_writ: -.byte " scenario written by " -.byte " tomoyoshi miyazaki " - -prog_writ: -.byte " programmed by " -.byte " masaya hashimoto " - -gart_writ: -.byte " graphic arts designed by " -.byte " takahiro ohura " -.byte " ayano koshiro " -.byte " kazuhiko tsuzuki " -.byte " tomoo yamane " - -music_writ: -.byte " music composed by " -.byte " mieko ishikawa " -.byte " yuzo koshiro " -.byte " hideya nagata " - -scene_writ: -.byte " scene set by " -.byte " seigo oketani " -.byte " yoshihiko kurata " - -art_direct: -.byte " art directed by " -.byte " seigo oketani " - -total_direct: -.byte " total directed by " -.byte " masaya hashimoto " - -produced: -.byte " produced by " -.byte " masayuki katoh " - -presented: -.byte " presented by falcom " - -turn_disk: -.byte " insert datadisk in " -.byte " drive 8 then return " - -clr_txt: - lda #$80 - ldx #0 -: - .repeat 4, I - sta $400+(I*250), x - .endrepeat - inx - cpx #250 - bne :- - lda #0 - ldx #0 -: - .repeat 4, I - sta $d800+(I*250), x - .endrepeat - inx - cpx #250 - bne :- - lda #$13 - sta $d018 - lda #$1b - sta $d011 - rts - -write_txt5: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+8*40) - ldx #>($400+8*40) - jsr write_txt_to - lda #<($400+10*40) - ldx #>($400+10*40) - jsr write_txt_to - lda #<($400+12*40) - ldx #>($400+12*40) - jsr write_txt_to - lda #<($400+14*40) - ldx #>($400+14*40) - jsr write_txt_to - lda #<($400+16*40) - ldx #>($400+16*40) - jmp write_txt_to - -write_txt4: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+9*40) - ldx #>($400+9*40) - jsr write_txt_to - lda #<($400+11*40) - ldx #>($400+11*40) - jsr write_txt_to - lda #<($400+13*40) - ldx #>($400+13*40) - jsr write_txt_to - lda #<($400+15*40) - ldx #>($400+15*40) - jmp write_txt_to - -write_txt3: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+10*40) - ldx #>($400+10*40) - jsr write_txt_to - lda #<($400+12*40) - ldx #>($400+12*40) - jsr write_txt_to - lda #<($400+14*40) - ldx #>($400+14*40) - jmp write_txt_to - -write_txt2: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+11*40) - ldx #>($400+11*40) - jsr write_txt_to - lda #<($400+13*40) - ldx #>($400+13*40) - jmp write_txt_to - -write_txt1: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+12*40) - ldx #>($400+12*40) - ; fall through - -write_txt_to: - sta @dst+1 - stx @dst+2 - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 -@dst: - sta $400, x - iny - inx - cpx #40 - bne :- - rts - -txt_fade_out: - lda #0 -txt_fade_out_offset: - pha - jsr init_timer - pla - sta timer - lda #2 - sta timer_mode -: - lda timer_reached - beq :- - rts - -code_end: +code: .incbin "main.zx0" diff --git a/loader/samples/minexample/song1.bin b/loader/samples/minexample/song1.bin deleted file mode 100644 index 98396cd3e31b4825764e60d6f075140ba51b16df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4464 zcmdT{eNa#XSXBcoGNr~qpVilYMZry(4}gzT8bi1 zB@|eqsZ|T=#Umz2B8dUCLd}Dq!V-4IO*>3yhuK#5i`Lz#^ZwdxgWT*nFF}I#WB=Vd z;l6wBJ@kV81FD{Yt?0~&b|E1Q@V`YWiMyu>YiVx>+Q{5wQ$kX&j|k~ zB{aD-362WZ4Gw|z0P6sD4jduo19k}B0?Pu{4}+S1hhQ;- zOLSZIfoqT3Qi-aTJZMroM0OJJ=TNaF1ZN|R)4-g-vVnPkxquY`D+aa`SQW4uV0FL_ z080m!3ak;>7GQIMl>plgEE!lSq3FSpz@7$2EL#rDfcEQ~1l|3uXtNM3`CuC10rg0z zjiWcl%eLE6!gpQ%n8byCC`V@s385JUgats{g?qq-1#8AT?l%R;=I z(jYl5&v5sFbO~@lrOSZJiG2~iibfwT`S;Bw@03N0o`GCE(K8Tm>eTU2P2!v=-W8Ux zCUO2TP24=_7J{P>i^iLwa5E~d+M*cTT%_4Ynz&6@IqcYD{p=)`CMu_}P}OwGg^S^o)_|EyYr!1C*-5Ps1^6EDgud9z+q-0@)74;eLJ{6u0f1tpR(8tpyWdZ3p>R_@#hW zxy`(*+O6>MZh`U$%qEa6`nLg6-YFw}1&XNDPHV>LKh> zkheszYYDp!vArb-Y$l&>!^ld_2FUd0;jYWBPCUaBLynl9V>zM$SS4YpwuR+&0~5M-ct54y;{DV z2T_V`p@iB4?oIIAb1t7C$IM>r!Y;f#aWp|Tjwd42(I-JX=7$~_kT6vwVY6E?a7n2z z(*#{$mUIr}IH?2V>FDdZJCn6k1fLg!tR<_H(>RXc1xgt5d=}Bpq%qBl zEnS1q+6N68B&Oj#hq`!)N*>I3sH$vHX)eeQg3!kGNw|<0Z#hvF7sP;vgGwWbDilp_ zGu$i$S0Q}94?Ho(!w%){b(vwA3LgUak`OTU4r+qfO_|%$2fAjPLlrHkqXgIMATLBU z%mDd{J9M}0bll7XS04D|Fgwt5LU-c~z9{G=fyl;(9i$u18%@G~#mpwMbtPhO-DzZq z{PobJqG6Q zBs@>}RO-dIkYoc)Qulvh18fDRp=a2lJ&ge!)cge%8Yve)zM+xQb`8i$_)^g3b6s&O z-JkC{Q8fG`A`WUk!3n!DSkg|=R~Q+MYIVPCMeP=CS6OR$9k7GYHQZW`uc^am;8WDE z0(lc62j&^1IvB%zUWcpq#R2d(0!}fEDHFyHgEifF%c(`3az)1)!w-OQ<{5M_e5eo` zQE?34EKi=n*?9O3-XthXr1Nge z8jwDATh`)XcU#thbj5A?HAsH9wx-ILW`IhMpO%kJ&NsQ7rW%G;Ry$D_Tt@!wC zDfFr2IG#qIm~x;0HLKe3n#tm)V_ePGgoi^>hB+c|0Gk}3 z-O|!`c8KDhy?ggnR+_7--m9*zsTKEDR#n&5?YAC0bfo_1@kVi9RjtK(=)hFux{rDxF zSYGy;qh^Z&Im*ppogoyT;0jlVG+@1g@mtTRf@JR z;%v7s%w{sDi;De=ybHa!$S)|m5hLNyc)NR)Ky)iX>50@78tV5(>Tdk@q8#RUfp>I7 z9Bk(u{5;}f7r)@9PUQG~;~r&PF@JsnqJwuTfg*w(+=D=!2p1-~6gj5X^Ap_0W2rj9 z|3?9*HF3s|@L0yf4f_75fYXkl-f8^1`+J%n<;@WX#vO_N+R$7RM~FlG5Lb`?CJ7(# JM?wOT`Y(svn1lcT diff --git a/loader/samples/minexample/test/bin.cfg b/loader/samples/minexample/test/bin.cfg new file mode 100644 index 0000000..ba97093 --- /dev/null +++ b/loader/samples/minexample/test/bin.cfg @@ -0,0 +1,11 @@ +MEMORY { + ZP: file = "", start = $0002, size = $00FE, define = yes; + MAIN: file = %O, start = $0BFE, size = $C402; +} +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, optional = yes; + CODE: load = MAIN, type = rw; + RODATA: load = MAIN, type = ro, optional = yes; + DATA: load = MAIN, type = rw, optional = yes; + BSS: load = MAIN, type = bss, optional = yes, define = yes; +} diff --git a/loader/samples/minexample/test/main.asm b/loader/samples/minexample/test/main.asm new file mode 100644 index 0000000..f831ad0 --- /dev/null +++ b/loader/samples/minexample/test/main.asm @@ -0,0 +1,10 @@ +.zeropage + +.segment "CODE" + + .word $0c00 + .incbin "font.bin" + .res 12 + +entry: + jmp * From da758df0194ba3258fa2ab3990c92510b40cde96 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Sat, 29 Nov 2025 14:32:14 +0700 Subject: [PATCH 16/26] Add dialog text --- loader/samples/minexample/main.asm | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index 8497f4c..97b6e3a 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -893,10 +893,14 @@ wait_frame_until: lda #0 sta vbl + lda enable_music + bne :+ lda cur_frame cmp #2 - bcc :+ + bcc :++ jsr sfx_play + jmp :++ +: jsr update_dialog : dec bmp_delay @@ -1830,3 +1834,25 @@ txt_fade_out_offset: lda timer_reached beq :- rts + +update_dialog: + ldy #0 + lda (text_ptr),y + bne :+ + rts +: + ; TODO + rts + +dialog:.byte8 + .byte 0, "are you ok?", 0 + .byte 1, "... who are you?", 0 + .byte 2, "thank goodness.\ni'm lilia from lance village.", 0 + .byte 3, "having some kind of premonition,\ni came here to have a look.", 0 + .byte 4, "suddenly,the area was enveloped\nby a light and you collapsed.", 0 + .byte 5, "where am i?", 0 + .byte 6, "this is the restaurant called y's.", 0 + .byte 7, "there're monsters near.\nwe should go.", 0 + .byte 8, "how about it,\ncan you stand up?", 0 + .byte 9, "yeah,i'm alright.should we\ngo before the monsters come?", 0 + .byte 10, "sure.", 0 From e47d81701b7c03ac8c78f1935f7e6714c900c2d0 Mon Sep 17 00:00:00 2001 From: AArt1256 Date: Sat, 29 Nov 2025 10:36:15 +0300 Subject: [PATCH 17/26] removed extra .byte8 --- loader/samples/minexample/main.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index 97b6e3a..548cb61 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -1844,7 +1844,7 @@ update_dialog: ; TODO rts -dialog:.byte8 +dialog: .byte 0, "are you ok?", 0 .byte 1, "... who are you?", 0 .byte 2, "thank goodness.\ni'm lilia from lance village.", 0 From 943185eb6223db7834f558f4b28091c6da5a4e8b Mon Sep 17 00:00:00 2001 From: AArt1256 Date: Sat, 29 Nov 2025 13:50:08 +0300 Subject: [PATCH 18/26] actually implemented the dialog text (better sync needed though) --- loader/samples/minexample/conv_liltalk.py | 29 ++ loader/samples/minexample/liltalk.bin | Bin 0 -> 988 bytes loader/samples/minexample/liltalk_speak.txt | 307 ++++++++++++++++++++ loader/samples/minexample/main.asm | 105 ++++++- loader/samples/minexample/sfx.asm | 4 +- 5 files changed, 440 insertions(+), 5 deletions(-) create mode 100644 loader/samples/minexample/conv_liltalk.py create mode 100644 loader/samples/minexample/liltalk.bin create mode 100644 loader/samples/minexample/liltalk_speak.txt diff --git a/loader/samples/minexample/conv_liltalk.py b/loader/samples/minexample/conv_liltalk.py new file mode 100644 index 0000000..516c9a0 --- /dev/null +++ b/loader/samples/minexample/conv_liltalk.py @@ -0,0 +1,29 @@ +f = open("liltalk_speak.txt","r").readlines() +f = [x[:-1] for x in f] + +line_addrs = [11,16,16,29,33,27,32,29,11,32,24,13,14,17,27,4] +out = [0xFE, (40-line_addrs[0])//2] +cnt = 1 +for line in f: + if line == '': + out.append(0xFE) # set line addr to beginning + out.append((40-line_addrs[cnt])//2) + cnt += 1 + else: + num = 0 + i = 0 + while i < len(line) and line[i] in "0123456789": + num = num*10+int(line[i]) + i += 1 + str = line[i+1:] + str = str.upper() + str = str.replace("\\N","\n") + if num == 3: num += 1 # botches yay + out.append(num) + out.append(len(str)) + for x in str: out.append(ord(x)) +out.append(0xFF) + +f = open("liltalk.bin","wb") +f.write(bytearray(out)) +f.close() \ No newline at end of file diff --git a/loader/samples/minexample/liltalk.bin b/loader/samples/minexample/liltalk.bin new file mode 100644 index 0000000000000000000000000000000000000000..ed6f00aac7a146f2748b09af19d41da621f9f37e GIT binary patch literal 988 zcmYk5QEtL85JcIqMHRHD>IwYE56Tfr0~mrzFbbiFi}heV5bd*ry4XSug%Xp)-iaaTVGl;s zjm{=yBpk4dJ$BhblEtx40bz;&fH58K_*oS5=zo+7!104RSYssv7CA=xXaZ*0;K*P$ zBhK07!Ao?m$t0m;i3cd^fH;hKpK$Is4I{cF6AXxwb(xY0FcHOdA@|^yi4kaa!E9uN zNBmkn=kjo9cbhXV>XzKPwdlGS|+b5BuJG`K;(cAjsf{3 zOgKe|q5y3ZxaCBahPC9FvAf@pNq;vG1pAnynZiO&`K-k;{=r5+A6H-1^WCg*)xOu%vrbvWRM_$*n@;7q|B`0_H80@^|p}59Wh;8~^|S literal 0 HcmV?d00001 diff --git a/loader/samples/minexample/liltalk_speak.txt b/loader/samples/minexample/liltalk_speak.txt new file mode 100644 index 0000000..3866852 --- /dev/null +++ b/loader/samples/minexample/liltalk_speak.txt @@ -0,0 +1,307 @@ +3 A +3 r +3 e +3 +3 y +3 o +3 u +3 +3 O +3 K +3 ? +6 + +70 ... Who are you? +6 +3 + +3 T +3 h +3 a +3 n +3 k +3 +3 g +3 o +3 o +3 d +3 n +3 e +3 s +3 s +2 .\n +1 + +3 I +3 ' +3 m +3 +3 L +3 i +3 l +3 i +3 a +3 +3 f +3 r +3 o +3 m +3 +3 L +3 a +3 n +3 c +3 e +3 +3 v +3 i +3 l +3 l +3 a +3 g +3 e +3 . +6 + +3 H +3 a +3 v +3 i +3 n +3 g +3 +3 s +3 o +3 m +3 e +3 +3 k +3 i +3 n +3 d +3 +3 o +3 f +3 +3 p +3 r +3 e +3 m +3 o +3 n +3 i +3 t +3 i +3 o +3 n +2 ,\n +1 + +3 I +3 +3 c +3 a +3 m +3 e +3 +3 h +3 e +3 r +3 e +3 +3 t +3 o +3 +3 h +3 a +3 v +3 e +3 +3 a +3 +3 l +3 o +3 o +3 k +3 . +6 + +3 S +3 u +3 d +3 d +3 e +3 n +3 l +3 y +3 , +3 t +3 h +3 e +3 +3 a +3 r +3 e +3 a +3 +3 w +3 a +3 s +3 +3 e +3 n +3 v +3 e +3 l +3 o +3 p +3 e +3 d +2 \n +1 + +3 b +3 y +3 +3 a +3 +3 l +3 i +3 g +3 h +3 t +3 +3 a +3 n +3 d +3 +3 y +3 o +3 u +3 +3 c +3 o +3 l +3 l +3 a +3 p +3 s +3 e +3 d. +6 + +64 Where am I? + +3 T +3 h +3 i +3 s +3 +3 i +3 s +3 +3 t +3 h +3 e +3 +3 k +3 i +3 n +3 g +3 d +3 o +3 m +3 +3 c +3 a +3 l +3 l +3 e +3 d +3 +3 Yee +3 s +3 . +6 + +3 T +3 h +3 e +3 r +3 e +3 ' +3 r +3 e +3 +3 m +3 o +3 n +3 s +3 t +3 e +3 r +3 s +3 +3 n +3 e +3 a +3 r +3 . +2 \n +1 + +3 W +3 e +3 +3 s +3 h +3 o +3 u +3 l +3 d +3 +3 g +3 o. +6 + +3 H +3 o +3 w +3 +3 a +3 b +3 o +3 u +3 t +3 +3 i +3 t +2 ,\n +1 + +3 c +3 a +3 n +3 +3 y +3 o +3 u +3 +3 s +3 t +3 a +3 n +3 d +3 +3 u +3 p? +6 + +150 Yeah,I'm alright? Should we\n Go before the monsters come? + +3 S +3 u +3 r +3 e +3 . +210 \ No newline at end of file diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index 548cb61..e451a47 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -22,6 +22,8 @@ timer_reached: .res 2 timer_mode: .res 1 enable_music: .res 1 temp: .res 3 +dialog_col: .res 1 +dialog_tick: .res 1 .include "lz_zp.asm" @@ -81,11 +83,11 @@ code_start: sta vbl cli - jsr intro + ;jsr intro lda #$0b sta $d011 - + sei ldx #introname @@ -1531,6 +1533,12 @@ part_11: jsr init_bmp jsr set_irq_badguy inc enable_music + lda #0 + sta dialog_tick + lda #dialog + sta text_ptr+1 cli lda #<256 @@ -1836,15 +1844,104 @@ txt_fade_out_offset: rts update_dialog: + lda dialog_tick + beq @skip_tick + dec dialog_tick + rts +@skip_tick: + ldy #0 lda (text_ptr),y + cmp #$fe + bne @skip_reset_col + cmp #$ff bne :+ rts : - ; TODO + ldx dialog_col + cpx #40*2 + beq @skip_reset + + ldy #1 + lda (text_ptr), y + sta dialog_col + ldx #0 + lda #$20+$60 +: + sta $748, x + inx + cpx #40*3 + bcc :- + jmp @skip_reset2 +@skip_reset: + ldy #1 + lda (text_ptr), y + clc + adc #40*2 + sta dialog_col +@skip_reset2: + + lda text_ptr + clc + adc #2 + sta text_ptr + bcc :+ + inc text_ptr+1 +: + jmp @skip_tick +@skip_reset_col: + clc + adc #1 + sta dialog_tick + ldy #1 + lda (text_ptr), y + sta temp+2 + lda text_ptr + clc + adc #2 + sta text_ptr + bcc :+ + inc text_ptr+1 +: + + lda temp+2 + beq @skip_text_upload + + ldy #0 +: + lda (text_ptr), y + jsr write_char_dialog + iny + cpy temp+2 + bne :- +@skip_text_upload: + + lda text_ptr + clc + adc temp+2 + sta text_ptr + bcc :+ + inc text_ptr+1 +: + + rts + +write_char_dialog: + cmp #$0a ; newline + bne :+ + lda #40*2 + sta dialog_col + rts +: + ldx dialog_col + clc + adc #$60 + sta $748, x + inc dialog_col rts dialog: +/* .byte 0, "are you ok?", 0 .byte 1, "... who are you?", 0 .byte 2, "thank goodness.\ni'm lilia from lance village.", 0 @@ -1856,3 +1953,5 @@ dialog: .byte 8, "how about it,\ncan you stand up?", 0 .byte 9, "yeah,i'm alright.should we\ngo before the monsters come?", 0 .byte 10, "sure.", 0 +*/ +.incbin "liltalk.bin" diff --git a/loader/samples/minexample/sfx.asm b/loader/samples/minexample/sfx.asm index 164103b..4ca6ada 100644 --- a/loader/samples/minexample/sfx.asm +++ b/loader/samples/minexample/sfx.asm @@ -77,7 +77,7 @@ sfx_num: .res 1 sfx_list: .word sfx0, sfx1, sfx1+$29 sfx0: - .incbin "sfx_badguy.bin" + .incbin "sfx_badguy.bin", 256 sfx1: - .incbin "sfx_badguy_amb.bin" + .incbin "sfx_badguy_amb.bin", 256 .endproc \ No newline at end of file From 0275f85b536f36ca996c38c27974a67594c6b25d Mon Sep 17 00:00:00 2001 From: spaztron64 Date: Sat, 29 Nov 2025 12:32:36 +0100 Subject: [PATCH 19/26] Dialogue resync attempt #1 --- assets/11_lilia_final.csv | 643 ++++++++++---------- loader/samples/minexample/build_liltalk.sh | 6 + loader/samples/minexample/lilia_talk.bin | Bin 22353 -> 25800 bytes loader/samples/minexample/liltalk.bin | Bin 988 -> 1017 bytes loader/samples/minexample/liltalk_speak.txt | 29 +- loader/samples/minexample/main.asm | 15 +- 6 files changed, 367 insertions(+), 326 deletions(-) create mode 100644 loader/samples/minexample/build_liltalk.sh diff --git a/assets/11_lilia_final.csv b/assets/11_lilia_final.csv index ff741d4..9f0fa7e 100644 --- a/assets/11_lilia_final.csv +++ b/assets/11_lilia_final.csv @@ -1,319 +1,332 @@ -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +6,../../../assets/ys2/11_lilia_final/koala/png/14.png -6,ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png + +10,../../../assets/ys2/11_lilia_final/koala/png/04.png +3,../../../assets/ys2/11_lilia_final/koala/png/05.png +3,../../../assets/ys2/11_lilia_final/koala/png/06.png +3,../../../assets/ys2/11_lilia_final/koala/png/07.png +3,../../../assets/ys2/11_lilia_final/koala/png/06.png +3,../../../assets/ys2/11_lilia_final/koala/png/05.png +3,../../../assets/ys2/11_lilia_final/koala/png/04.png + +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +10,../../../assets/ys2/11_lilia_final/koala/png/01.png + +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png + +3,../../../assets/ys2/11_lilia_final/koala/png/08.png +3,../../../assets/ys2/11_lilia_final/koala/png/09.png +3,../../../assets/ys2/11_lilia_final/koala/png/10.png +3,../../../assets/ys2/11_lilia_final/koala/png/11.png +3,../../../assets/ys2/11_lilia_final/koala/png/10.png +3,../../../assets/ys2/11_lilia_final/koala/png/09.png +3,../../../assets/ys2/11_lilia_final/koala/png/08.png + +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +10,../../../assets/ys2/11_lilia_final/koala/png/01.png + +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +10,../../../assets/ys2/11_lilia_final/koala/png/01.png + +70,../../../assets/ys2/11_lilia_final/koala/png/01.png + +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +10,../../../assets/ys2/11_lilia_final/koala/png/01.png + +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +10,../../../assets/ys2/11_lilia_final/koala/png/01.png + +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png + +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +10,../../../assets/ys2/11_lilia_final/koala/png/01.png + +150,../../../assets/ys2/11_lilia_final/koala/png/01.png -70,ys2/11_lilia_final/koala/png/13.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/03.png +5,../../../assets/ys2/11_lilia_final/koala/png/02.png +5,../../../assets/ys2/11_lilia_final/koala/png/01.png -10,ys2/11_lilia_final/koala/png/04.png -3,ys2/11_lilia_final/koala/png/05.png -3,ys2/11_lilia_final/koala/png/06.png -3,ys2/11_lilia_final/koala/png/07.png -3,ys2/11_lilia_final/koala/png/06.png -3,ys2/11_lilia_final/koala/png/05.png -3,ys2/11_lilia_final/koala/png/04.png - -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -10,ys2/11_lilia_final/koala/png/01.png - -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png - -3,ys2/11_lilia_final/koala/png/08.png -3,ys2/11_lilia_final/koala/png/09.png -3,ys2/11_lilia_final/koala/png/10.png -3,ys2/11_lilia_final/koala/png/11.png -3,ys2/11_lilia_final/koala/png/10.png -3,ys2/11_lilia_final/koala/png/09.png -3,ys2/11_lilia_final/koala/png/08.png - -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -10,ys2/11_lilia_final/koala/png/01.png - -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -10,ys2/11_lilia_final/koala/png/01.png - -70,ys2/11_lilia_final/koala/png/01.png - -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -10,ys2/11_lilia_final/koala/png/01.png - -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -10,ys2/11_lilia_final/koala/png/01.png - -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png - -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -10,ys2/11_lilia_final/koala/png/01.png - -150,ys2/11_lilia_final/koala/png/01.png - - -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/03.png -5,ys2/11_lilia_final/koala/png/02.png -5,ys2/11_lilia_final/koala/png/01.png - -3,ys2/11_lilia_final/koala/png/12.png -3,ys2/11_lilia_final/koala/png/13.png -3,ys2/11_lilia_final/koala/png/14.png -3,ys2/11_lilia_final/koala/png/15.png -200,ys2/11_lilia_final/koala/png/16.png \ No newline at end of file +3,../../../assets/ys2/11_lilia_final/koala/png/12.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/15.png +200,../../../assets/ys2/11_lilia_final/koala/png/16.png \ No newline at end of file diff --git a/loader/samples/minexample/build_liltalk.sh b/loader/samples/minexample/build_liltalk.sh new file mode 100644 index 0000000..79c5207 --- /dev/null +++ b/loader/samples/minexample/build_liltalk.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +rm lilia_talk*.* +../../../assets/png2prg_linux_amd64 -m koala -o lilia_talk.bin ../../../assets/11_lilia_final.csv + + diff --git a/loader/samples/minexample/lilia_talk.bin b/loader/samples/minexample/lilia_talk.bin index e8b8d210998e9a7ad6edab3213b815a28417f049..c387dd3ff85519b37a3b818e7f9cae26d46d2585 100644 GIT binary patch literal 25800 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 evgZ_jw3FqaYMb&HM)tS8v<^ literal 22353 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 IjrMby0fn&&+W-In delta 38 scmey#eusU6iZsJN9yb9!Jw1hR4}S&6AXkM*|4@521{R?B#+bRx0NYOrzyJUM diff --git a/loader/samples/minexample/liltalk_speak.txt b/loader/samples/minexample/liltalk_speak.txt index 3866852..5f5875f 100644 --- a/loader/samples/minexample/liltalk_speak.txt +++ b/loader/samples/minexample/liltalk_speak.txt @@ -9,11 +9,32 @@ 3 O 3 K 3 ? -6 +6 -70 ... Who are you? -6 -3 +3 . +3 . +3 . +3 +3 W +3 h +3 o +3 +3 a +3 r +3 e +3 +3 y +3 o +3 u +3 ? + +10 +3 +3 +3 +3 +3 +3 3 T 3 h diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index e451a47..69d9b54 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -54,6 +54,7 @@ code_start: lda #0 sta enable_music jsr init_2x + jsr part_11 jsr clr_txt ldx #copyright @@ -1509,11 +1510,11 @@ part_11: beq :- ; tell the music to end and wait -: - lda #1 - jsr $a006 - cmp #17 - bne :- +;: + ; lda #1 +; jsr $a006 +; cmp #17 +; bne :- ldx #$00 ldy #$01 @@ -1890,8 +1891,8 @@ update_dialog: : jmp @skip_tick @skip_reset_col: - clc - adc #1 + sec + sbc #1 sta dialog_tick ldy #1 lda (text_ptr), y From 19139b69367add4f2e723cbd906de5eec5ade4cd Mon Sep 17 00:00:00 2001 From: AArt1256 Date: Sat, 29 Nov 2025 14:55:26 +0300 Subject: [PATCH 20/26] Dialogue resync attempt #2 --- assets/11_lilia_final.csv | 16 +++++++-------- loader/samples/minexample/conv_liltalk.py | 21 ++++++++++++++++++-- loader/samples/minexample/lilia_talk.bin | Bin 25800 -> 22630 bytes loader/samples/minexample/liltalk.bin | Bin 1017 -> 1031 bytes loader/samples/minexample/liltalk_speak.txt | 14 ++++++------- loader/samples/minexample/main.asm | 5 +---- 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/assets/11_lilia_final.csv b/assets/11_lilia_final.csv index 9f0fa7e..c007f7e 100644 --- a/assets/11_lilia_final.csv +++ b/assets/11_lilia_final.csv @@ -12,21 +12,21 @@ 6,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png 3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png 10,../../../assets/ys2/11_lilia_final/koala/png/04.png 3,../../../assets/ys2/11_lilia_final/koala/png/05.png diff --git a/loader/samples/minexample/conv_liltalk.py b/loader/samples/minexample/conv_liltalk.py index 516c9a0..ff21186 100644 --- a/loader/samples/minexample/conv_liltalk.py +++ b/loader/samples/minexample/conv_liltalk.py @@ -1,7 +1,25 @@ f = open("liltalk_speak.txt","r").readlines() f = [x[:-1] for x in f] -line_addrs = [11,16,16,29,33,27,32,29,11,32,24,13,14,17,27,4] +line_addrs = [] +char_cnt = 0 +for line in f: + if line == '': + if char_cnt >= 40: char_cnt = 0 + line_addrs.append(char_cnt) + char_cnt = 0 + else: + num = 0 + i = 0 + while i < len(line) and line[i] in "0123456789": + num = num*10+int(line[i]) + i += 1 + str = line[i+1:] + str = str.upper() + str = str.replace("\\N","") + char_cnt += len(str) +line_addrs.append(char_cnt) + out = [0xFE, (40-line_addrs[0])//2] cnt = 1 for line in f: @@ -18,7 +36,6 @@ for line in f: str = line[i+1:] str = str.upper() str = str.replace("\\N","\n") - if num == 3: num += 1 # botches yay out.append(num) out.append(len(str)) for x in str: out.append(ord(x)) diff --git a/loader/samples/minexample/lilia_talk.bin b/loader/samples/minexample/lilia_talk.bin index c387dd3ff85519b37a3b818e7f9cae26d46d2585..db61f988382f69f15aa8fa0b64d98a3dea9c0af6 100644 GIT binary patch delta 131 zcmX?clJVIF#tkeQjLef4hROrUgJ2TEW()&~;1>s~nJk=qd9t|H7dZxId~ot@r;f=N WtXWu@W^e^FPQGWYyV=vCUIzf!$seBp delta 152 zcmaF1f$_vi#tkeQn;U$!7$+wfNKEF?N!`3!Gl6mPrm!oMuj@%o)>Y@39ILgCPW(%o JpKI6a008i3K}`Sv diff --git a/loader/samples/minexample/liltalk.bin b/loader/samples/minexample/liltalk.bin index 330020d1c15b3757d8e1828586d79386014d227a..b0aedc543262999dd0b93b880de911694a2dbeb4 100644 GIT binary patch literal 1031 zcmZvaU2eiK5QO7wiz;Z5D)j(<;|1jiP5Ch-Dj_HdMO>^0>w(gK_F{{Nwieo~XLn|2 zJT4VF*>=kD)QO z`_KfQZAc=a=j3@YHQD$mrWUgh(*!k#@TtG_pn4Z{Q=I_XdlQHGiX~KW1se>-BpV;1 z5=EegJ37Ly?bHmWM*+9U4h)Dtf#&rDp&pcmx{gaRYjvm;-YFC^iNRCrS z5is(=P^2(ok|^hvgO;0eM6w?wae%@Oh`lYN!>L|5v=J*Kpq8durA$h|L?pMlxf#C> z9f2kl%!Ws3M6c$PFZXX|6U5S#LoI!wbdqnq`1!}|Qn}9ARb%VYZ$X~~y;WEWG_QlC zEx^ync%l1-3I?U};=L}pIzpOxx~JHmlv=Tf0TZO%frd^oDuc=Rq&ZcEdh!w;Jy|LN z;R8BY1N4CybMn@c0@O z>qTQ%hpygNLuvb}Js-CA;-)tI?OVHcyB4d5%Gstp_JiwsyJ;I&j;~<^#H%UAPxku< DbE0`n literal 1017 zcmZvaO>V+K425xUQ3aGmPcS<+C`V|@&p=QKK@f_#SP#|%rTu2ijJhZqA;+^;4BH9Z)xwIs%FRt*-j%c%afn9Ef9V1$r0D=)8$Z zNH3hCD91ABpH%iLbCo9YAL6I|(}U`5R7!OQSnqX`|Cvgt;tDnx%F&=7CMAYI4|jBg z-P+ms%!>kUk;g4pP!gPyMG%t&0F3GQ51&P`2>M4c0USNBgSD=BMUXwFjv`>>fuYD? z#3WJ9Ee9<@xkiy}1W6pAumfUKi{x;wHx6sWk_Z@(rdDN4M!-ZQH-$WmU&W3vzX>QBn7n5TdV^6o%GXBd;gWPBo@s?t1piO-xYm4NU89jpQR zNQ^l}8%P1#C5D?%cxhO3jv2eh3z?+10U_AGKAI>bWS6g6oGJ)LUvGE6tQY%v yeph#uyVULVuyHp(cJa4s-O6uUtnO;>n)Z0<{Q2V6ZR4x{HI9IIGo}0<{QLqJ(0Mli diff --git a/loader/samples/minexample/liltalk_speak.txt b/loader/samples/minexample/liltalk_speak.txt index 5f5875f..750d4ca 100644 --- a/loader/samples/minexample/liltalk_speak.txt +++ b/loader/samples/minexample/liltalk_speak.txt @@ -28,13 +28,13 @@ 3 u 3 ? -10 -3 -3 -3 -3 -3 -3 +10 +3 +3 +3 +3 +3 +3 3 T 3 h diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index 69d9b54..f5f43ab 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -1845,9 +1845,8 @@ txt_fade_out_offset: rts update_dialog: - lda dialog_tick - beq @skip_tick dec dialog_tick + bmi @skip_tick rts @skip_tick: @@ -1891,8 +1890,6 @@ update_dialog: : jmp @skip_tick @skip_reset_col: - sec - sbc #1 sta dialog_tick ldy #1 lda (text_ptr), y From 0de9f70a71d0d3a41850b997279859bb29f023bb Mon Sep 17 00:00:00 2001 From: spaztron64 Date: Sat, 29 Nov 2025 14:11:26 +0100 Subject: [PATCH 21/26] Lipsync finalized, TODO fix the text rendering --- assets/11_lilia_final.csv | 773 +++++++++++------- assets/ys2/11_lilia_final/koala/png/02b.png | Bin 0 -> 5853 bytes assets/ys2/11_lilia_final/koala/png/03b.png | Bin 0 -> 5899 bytes loader/samples/minexample/lilia_talk.bin | Bin 22630 -> 22741 bytes loader/samples/minexample/liltalk.bin | Bin 1031 -> 1278 bytes .../minexample/liltalk_full_rebuild.sh | 4 + loader/samples/minexample/liltalk_speak.txt | 715 +++++++++------- loader/samples/minexample/main.asm | 12 +- 8 files changed, 891 insertions(+), 613 deletions(-) create mode 100644 assets/ys2/11_lilia_final/koala/png/02b.png create mode 100644 assets/ys2/11_lilia_final/koala/png/03b.png create mode 100644 loader/samples/minexample/liltalk_full_rebuild.sh diff --git a/assets/11_lilia_final.csv b/assets/11_lilia_final.csv index c007f7e..e0727d1 100644 --- a/assets/11_lilia_final.csv +++ b/assets/11_lilia_final.csv @@ -1,332 +1,471 @@ -3,../../../assets/ys2/11_lilia_final/koala/png/01.png -3,../../../assets/ys2/11_lilia_final/koala/png/02.png -3,../../../assets/ys2/11_lilia_final/koala/png/03.png -3,../../../assets/ys2/11_lilia_final/koala/png/02.png -3,../../../assets/ys2/11_lilia_final/koala/png/01.png -3,../../../assets/ys2/11_lilia_final/koala/png/02.png -3,../../../assets/ys2/11_lilia_final/koala/png/03.png -3,../../../assets/ys2/11_lilia_final/koala/png/02.png -3,../../../assets/ys2/11_lilia_final/koala/png/01.png -3,../../../assets/ys2/11_lilia_final/koala/png/02.png -3,../../../assets/ys2/11_lilia_final/koala/png/01.png -6,../../../assets/ys2/11_lilia_final/koala/png/14.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +6,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +10,../../../assets/ys2/11_lilia_final/koala/png/13.png -10,../../../assets/ys2/11_lilia_final/koala/png/04.png -3,../../../assets/ys2/11_lilia_final/koala/png/05.png -3,../../../assets/ys2/11_lilia_final/koala/png/06.png -3,../../../assets/ys2/11_lilia_final/koala/png/07.png -3,../../../assets/ys2/11_lilia_final/koala/png/06.png -3,../../../assets/ys2/11_lilia_final/koala/png/05.png -3,../../../assets/ys2/11_lilia_final/koala/png/04.png +6,../../../assets/ys2/11_lilia_final/koala/png/04.png +1,../../../assets/ys2/11_lilia_final/koala/png/05.png +1,../../../assets/ys2/11_lilia_final/koala/png/06.png +1,../../../assets/ys2/11_lilia_final/koala/png/07.png +1,../../../assets/ys2/11_lilia_final/koala/png/06.png +1,../../../assets/ys2/11_lilia_final/koala/png/05.png +1,../../../assets/ys2/11_lilia_final/koala/png/04.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +2,../../../assets/ys2/11_lilia_final/koala/png/02.png +1,../../../assets/ys2/11_lilia_final/koala/png/03.png + +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +6,../../../assets/ys2/11_lilia_final/koala/png/01.png + +1,../../../assets/ys2/11_lilia_final/koala/png/08.png +1,../../../assets/ys2/11_lilia_final/koala/png/09.png +1,../../../assets/ys2/11_lilia_final/koala/png/10.png +1,../../../assets/ys2/11_lilia_final/koala/png/11.png +1,../../../assets/ys2/11_lilia_final/koala/png/10.png +1,../../../assets/ys2/11_lilia_final/koala/png/09.png +1,../../../assets/ys2/11_lilia_final/koala/png/08.png + +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +2,../../../assets/ys2/11_lilia_final/koala/png/03.png +1,../../../assets/ys2/11_lilia_final/koala/png/01.png + +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +6,../../../assets/ys2/11_lilia_final/koala/png/01.png + +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +2,../../../assets/ys2/11_lilia_final/koala/png/02.png +1,../../../assets/ys2/11_lilia_final/koala/png/03.png + +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +6,../../../assets/ys2/11_lilia_final/koala/png/01.png + +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png 10,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +6,../../../assets/ys2/11_lilia_final/koala/png/01.png + +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +2,../../../assets/ys2/11_lilia_final/koala/png/02.png +1,../../../assets/ys2/11_lilia_final/koala/png/01.png + +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +6,../../../assets/ys2/11_lilia_final/koala/png/01.png + +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/01.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +4,../../../assets/ys2/11_lilia_final/koala/png/03.png +4,../../../assets/ys2/11_lilia_final/koala/png/02.png +2,../../../assets/ys2/11_lilia_final/koala/png/01.png +1,../../../assets/ys2/11_lilia_final/koala/png/02.png + +4,../../../assets/ys2/11_lilia_final/koala/png/03b.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/03b.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/03b.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/03b.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +6,../../../assets/ys2/11_lilia_final/koala/png/13.png + +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/13.png + +4,../../../assets/ys2/11_lilia_final/koala/png/13.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +4,../../../assets/ys2/11_lilia_final/koala/png/03b.png +4,../../../assets/ys2/11_lilia_final/koala/png/02b.png +15,../../../assets/ys2/11_lilia_final/koala/png/13.png + +2,../../../assets/ys2/11_lilia_final/koala/png/13.png +2,../../../assets/ys2/11_lilia_final/koala/png/14.png +2,../../../assets/ys2/11_lilia_final/koala/png/15.png +2,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png +10,../../../assets/ys2/11_lilia_final/koala/png/16.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -3,../../../assets/ys2/11_lilia_final/koala/png/08.png -3,../../../assets/ys2/11_lilia_final/koala/png/09.png -3,../../../assets/ys2/11_lilia_final/koala/png/10.png -3,../../../assets/ys2/11_lilia_final/koala/png/11.png -3,../../../assets/ys2/11_lilia_final/koala/png/10.png -3,../../../assets/ys2/11_lilia_final/koala/png/09.png -3,../../../assets/ys2/11_lilia_final/koala/png/08.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -10,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -10,../../../assets/ys2/11_lilia_final/koala/png/01.png -70,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -10,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -10,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png - -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -10,../../../assets/ys2/11_lilia_final/koala/png/01.png - -150,../../../assets/ys2/11_lilia_final/koala/png/01.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/03.png -5,../../../assets/ys2/11_lilia_final/koala/png/02.png -5,../../../assets/ys2/11_lilia_final/koala/png/01.png -3,../../../assets/ys2/11_lilia_final/koala/png/12.png -3,../../../assets/ys2/11_lilia_final/koala/png/13.png -3,../../../assets/ys2/11_lilia_final/koala/png/14.png -3,../../../assets/ys2/11_lilia_final/koala/png/15.png -200,../../../assets/ys2/11_lilia_final/koala/png/16.png \ No newline at end of file diff --git a/assets/ys2/11_lilia_final/koala/png/02b.png b/assets/ys2/11_lilia_final/koala/png/02b.png new file mode 100644 index 0000000000000000000000000000000000000000..c7af2ad0ab1a5a549dc3cc17b75a94dfe1aa24bc GIT binary patch literal 5853 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 literal 0 HcmV?d00001 diff --git a/assets/ys2/11_lilia_final/koala/png/03b.png b/assets/ys2/11_lilia_final/koala/png/03b.png new file mode 100644 index 0000000000000000000000000000000000000000..c6e40fa678d5425bd26c50e1aeeade2ecb6e7c07 GIT binary patch literal 5899 zcmds*_g7O}u*XkACj{5)A+~4iRz|-8K!E=cqc^+8;ibeXwzFw&BD6M&(fs zHS6sir@2 zhw5PnL8?HG3Q#mPUM2ZAb;B*_Zc7tMh#lv=1Qt{bpwN2b*=v-PL@R{YkrmJ9vNP*n zy0pH7XW2&nSmZ;$Cp+@-=;!n5j1p0L?9{L+RegDz^X#J`yO8olRsEAXLP=})!hO%) z?0q>d^44QYl}y5dtRGA1{Wd3h56`^%xWxTx!!TZ+q8`k!ir~=?RQ-mu=&ba6Axx-C z#YfnX+BlmB=lJ}Jxd!UK3ln?|W{=!>Ct>(COEu2qXKsLX`oU^Tm?MjA!i`sVvV;t2 z$sm)f<+yv_Xnctm>dcr{j)D1{$Hyxx;h9D@WWY%sE*FLsyr#Gb~D*jB!J&eTZy!>!4 zBh!}i-6*(pSls9(mo);V|NZr_YSZ9O2H^>YHYd!jpxu%gBebVE)CD-**4|cEba8g9 z+9CcDCfM3}%O#q@Tz-$eAi~8$b#b>mi&!3JOsNPHP%Ft^+Co|C5>6%PgvkLAd&w%x zyI!dj`>t8K?$ZQNV}8Kmn4DhAxw@K`tqfPL&yW~C^zP`BBe-a~JUi0zu^svn8>*g8 z1`1A78#hb(Ub~kook{DziY~T){My?cs66@LF!Co=3i26}b}GysXHzwA_KO#T6c%~( zmAR?jx=H5K@@_Yn@8KN#soyx@lEn(|_7^JiK*J-EPI%MN z#l7b%VL_w1`_$SfL@6bus_EoSHCi@~yl!S&Q9?|~HM|^;J~Vvli&|Eu)Q-;{s z%XU95gL_Kp)o+&U0oP;c&+loDzeBjH zHLY(Qe*23b49mTIE8uD_iY35-xd{&#+`MS=!)j|27FTHQCJi8h?lhUPz_zX)4{eEb zw6xc^L0Z z{VSZNg*V`U9}z}A0hO<%)wWSQL% z7ne3_>xKpoIU1Mv_(Ogj={=D}(f+39econp? zV67SwnUK>>8%Fm#bn-5f2T~Njy@TWw)eCO7q6yVIGFJE()5Wxb|;=RCC z0o0|jIe>21C2Qo`=MG>*!}C~RX%bpOZ$riH#9r?KU>G{pBjK3?C=-%P{q{twL#TYS zb6wj-s8%UB+Wx`H8Pmxi$CA-gUh^B0jCmd6lyDx;t$F?lPyBQH7``d_KF=R5_d;$6 zi70j_)yN+ljoB|9$j%F?iL#^g{aNNRqatS^ji#mN3 z^v4ASAo?cIcI;Yo2rw<~dir|6OsaZhavH0kI=r$50ZwbDX#hQEW zK*P$C>ER}9CoMU|S7<#p%aK!`iG>C*2a0^pVZlEl$boIAo#(`^6DQ^#dn63NLI>c_ z5_*yo$V%0M57J_E-#!nssIpzbB^fK@!>A*b+0-n`ygxH9x5Sv=bYnRPw+xB)Fq;Ei zVrwG*p@4Z{(1%T`KoatxKUSKPT+5fkdssodVz!$YKhN=BZJsNnr_-5yTJI+Z|B#xa$;E zWB(dDcd~UgWa;N*eeO%DsQoQ_VP}_?r3_u6q~wnzZtckMZB3o1D~XZ@XBr?p#iIRe z30V6~XPiR7dFZ|WXUAD1c!CRRW*fD?lg0GdxG@Y4ULwe7v`Wiu0fDzl3W}P4O z`uDiRbFBHix+u=V4OGQpl8+luc}nM`j91KjEt-U9%e+syQ1$@SIIG0?+{Oj9ziT+6 zA(T`Cm+n{a0RA#y_b!;?fo1bgtC^Ld(BfiGhprXejgXSL%tP+}XJBUlhIOD$K28xb zebU9f6~lHOR()m>1s#!@(Ap^u-DoH-f7!e?9-?A zW;6{ReDR-<6784a(dWLx^`R>@u!{a7-+#?JP*t907GPAugcr*t857ko6{9Ec*M&7G z3mdY{RJO%0+s4cR&)Th$+a>t-MDEU+5<53)wbPKzbf|*UAKBV)>C@UL8eROn0r$sS z`RUW1FsF;U?-)TJOS>v3m=Iz9^DIDfM>L+{D!3K<2Yu>3heWB?wXPk8Ekr0!2)_C? zePI`T@#9v@7v+ALKO%)A+n0AgP9WYsGhCgwpXzModse5pmzxV26V8?!Xh};txy;Ri z$uM=^mdv2Oy8LWCUEvMMIb&7q1j-s{lFDj|v26f9bDLN|my+AZ0yyU0XUVa_nf0K`B_) ziQwp*NfH@@I7UpQB((-;^Y`qPuR>Ny;l2A9(I0Hx-(wmdJ9*m+6NSVqC_%}pBUSzg z;c`l5Ya-Ie4biBCVdl(2j$(!^qq*JRqR@G2;Qp=R%2GQn_W-WcVF)vh76XbCQ$-=e zLaggjJG+)F26v&qoqD~XC&W(eZ0eiKx(f6g{0 zQ_{v^$~#o=^q87ZnM|kMh8fDBxpIsCGXSFQ(t$~koJhv!{)7Cl>k zrcObRJoBawBQ<|%M#j=1gkaXGKpVdwU{%ab+ll)xARFd#ov8;{ZT+y;H2D`*T#hN_ z#wV*~5v_bmca!5qe(t*w%i71;_?uZ^)*M#XHuhvlwA9`m^6Xy6vqc;t(~0OCKKW`V zEzt;gK?&{cAzREl6L* z641r3?SPZjLw~=7w?44A8+oWU2b#dF*+EAPA%)FNp-S&Yoj6N1e?0MnLic?XLtM?HWP8&c8ytV9c6%Aim*u5-k#*dwavp%kCrNf(Mqs|H`6>4LU? zHZ%{RM*iX+@3@#>st#z|2k6n+fuXD3ja{Y95?a>~g?|9cjOB{`z2UTYqyK9NW1M5~ zU!1K<6#F-M1~*Ige<(MfKgXpV=Q7f!z4p#ev3ocBhMFpHF~;L=NprBagm4Y8o*#RK zdO1T&G<>!}_n0UW)|)-bpVdw9g*1^b1vZguD*bs#?z=&xl-EsURT5-e$NZIfNHl$# zjg(c3xqqr;*N90oT2(Efk-klH5ev_%mlHfjbQ(ShU8~1ByV34^iqNfwI57(sZk6vS zN1xkXN`X1(3-Uymmj6P~wLU3Gnqb2^qbJo7UJ z)Og)pYkG8-J=a*Ny0zG}P##M0l7NVdfge)TPqRyvY_tAUr&Cpi_2>l`w$i&B*(`_Yae;;gqHYjL_;61MY0CK9WT+A{2gYTCbK z0jZ_Eds#@AmHmc`a}C#J2je8S`X0{cVj-CZr)4X8?b^PCNpheU-PufxWf@xqbEo<; zq!cur*U?M2SIzqN4vMANC-qfUl|v4xeFf9Bzbs!j;ftCFMF&sP0ce z$banNWG@t;Rzn2$Wx-M>_iEdk&fJ_DS;^69JIBZiX8H!l1PDtCjfn?oFkwPaf`D1` z*5pj&C9fVVR5B}r$Rqm+fwzSqj21x0CCaIDCYAz}-EonB%k!t~dG*KXP=jXWnAOo5 z54RMhWwy4nW!Jv!?;gcf$f*HAeN(!j9Jun0uL0W^siu83+|~FY$-Z2zf6+xSBIa;5 z`l=@!@&+qMbgjyj+S_eu2-m&2x59XrfmEoaMfzVJ4f_YGdlIVe%=J1rdXHUtjr1=Q zjJMLGtBt#U!3nAuz`Y0UnRSon(?El{Q|UPdZr&q0?D0Ks*cpH}eNNa*AbdbJ(|t zd6a_(ov)AUZEQ2CZHU4hV41fe#;tIM>tx(h`Q}xUZKS}BAJ>y3a>8rC_`t*cr8a)J z6ZMwgEx8-<)IM{)yOuB3xm%dzTY!minF`we`K4MXctot78Ti<+$*iMqU?~wTRev!4 zgqBk9g!EHPLYd2Ymx4Oixw!9VN_vk=F%w-Lm{sCdF=s{JSGdP5jc!t#p?wVDKJ1Ff zV!#%!PSpp#@|`jI{)^cLq1twyO(PGt9`1kH5X-D=*kvW7Xo=T9w)Z@{Cxzl%zvF!8 zvznV@(+4pvprurU*->HU<_H#*3mkc#)Yb^Mlsv;VlMrlZFQg8saw&>7TrHs)n#iqB z9%)f!re{FY6snJU?;d?sl%SaeeC!zEZLbOCKw?)v0#24pQ;52V&rH z9zn@>ezA+PJhBcr*2w>+Ly4Q^+il-R|hYWZibDhG&O4_FnPDQA-kR+|M05iQ2( zR<9K*U~32MSuRyXKk+2v&?orGZfJk5Q{(!YjVmJx>O$Wi`Ql%=(E9dcSgxSg%J18en{Q97|d#s?KHw@C^T&54VYb+Ts5-Jy@FQV z?frpV^R`OmG^Q?<)=b8m>e4;1s&8ULLIS^~w}i|p9USiN&2312T94GrI>F?CE1>B( zMyolo$UyGK=Oa|S3jL)@h2hX%gbh{sk1-pjvHzN6;;nl&n~rA<*>Jfj!OF1`@BE)* z+j?!m@TwFx+)8gr)XP?3LQoB)d3rZELh;Rvc?bUQ!PVHgg*lI>@KsvH@ZN0JhhDVz zzcQG&``twvXk-W|`6gGFsD<`JYdw7;qRbcC#!A=BP4*b7gO8q{{5PA6!W!qvLGRtgW1E$88j4BOqG5-TG3*#;T literal 0 HcmV?d00001 diff --git a/loader/samples/minexample/lilia_talk.bin b/loader/samples/minexample/lilia_talk.bin index db61f988382f69f15aa8fa0b64d98a3dea9c0af6..5b4ad810e00b9e2df15e45c8cad2661819d7a6fe 100644 GIT binary patch delta 2033 zcmaF1f${1_#tkeQj4YEGedU3qBAA4*6Oq`s#Gz`!)=w7KQcz%E!3()2Yii$RWSh*c zbD5EG@@<_uAQ`0#A|dPuJrMi49!Pez{%W9eh;afgr(qXo0(+5>1|}l~9y2f;D6#?B z-yk;I@x9_O@kIUC6thTbm3pRr-Nfsw4t zPfx!<>`L^N7iYs-#&8YQm|zC_XV9c}Sni`%%mU+!ivD8)hZC@D09H58wL#StBRJhY z3`MY!T~3KOP;Wi@MF;`_rn!3B delta 1888 zcmcb*k@49E#tkeQjLeg3!{mYFTrde?{|N+%;1`Fe`5$&^@)u2o$-?StlU;&i7+EJT z43^;9UvCcvXW1w33)WR&V8#z8f7C6Wyj&}bk!$k*u(Zh)+POg6pJ~?t$y6N>31KJe zg4mCAF9XSKdaHqUf!x3fb|)*?{V?{B5NBp(pv(s#UvfcxkKf0j@C`SW0)`vm@O834 zgfA#f45=_3*far*QCNJ8h8(E$pjobD2Zl6*8!-RS)E0Q!r&eqNb15^|kaIP$zNcQ= zC)P&F;vW(l)3B!@c~(XbPEE$u`+j|HXl6E%Vq$FI3Sf+j%GJxuijUT3pL`cwU)lt( WXJP;qtDr*ja(D@l^oYn}JOKb*jTy24 diff --git a/loader/samples/minexample/liltalk.bin b/loader/samples/minexample/liltalk.bin index b0aedc543262999dd0b93b880de911694a2dbeb4..ea0f503ae72ce3ad6450b3fbff6aa48b36cf85ab 100644 GIT binary patch literal 1278 zcmchWO-=$q5QV8uF)^qlCLDkr8!}gzs301DAPN$%?SV$Wu19xfp)Q39>FIt|@2je& zpSoSUy}GU4=58NuTem~3Svj!VQPE8TGRv z8dhG&6agPv9H3EpHHU6M#3{I(as&d4U1=a7Y$8BLwfyGSl$N=kCN_}62MtR3+UOCC@M^#IWq60E6MbQ#643l1VW z0|kS@T(%oe+iZ$Zhm1g-qr1|omsGev-I?=pTQEdB?5vV_jD-`kf7_YqF;1MSD^i* Jg8%t`eFMk$vY!9| literal 1031 zcmZvaU2eiK5QO7wiz;Z5D)j(<;|1jiP5Ch-Dj_HdMO>^0>w(gK_F{{Nwieo~XLn|2 zJT4VF*>=kD)QO z`_KfQZAc=a=j3@YHQD$mrWUgh(*!k#@TtG_pn4Z{Q=I_XdlQHGiX~KW1se>-BpV;1 z5=EegJ37Ly?bHmWM*+9U4h)Dtf#&rDp&pcmx{gaRYjvm;-YFC^iNRCrS z5is(=P^2(ok|^hvgO;0eM6w?wae%@Oh`lYN!>L|5v=J*Kpq8durA$h|L?pMlxf#C> z9f2kl%!Ws3M6c$PFZXX|6U5S#LoI!wbdqnq`1!}|Qn}9ARb%VYZ$X~~y;WEWG_QlC zEx^ync%l1-3I?U};=L}pIzpOxx~JHmlv=Tf0TZO%frd^oDuc=Rq&ZcEdh!w;Jy|LN z;R8BY1N4CybMn@c0@O z>qTQ%hpygNLuvb}Js-CA;-)tI?OVHcyB4d5%Gstp_JiwsyJ;I&j;~<^#H%UAPxku< DbE0`n diff --git a/loader/samples/minexample/liltalk_full_rebuild.sh b/loader/samples/minexample/liltalk_full_rebuild.sh new file mode 100644 index 0000000..ea59a78 --- /dev/null +++ b/loader/samples/minexample/liltalk_full_rebuild.sh @@ -0,0 +1,4 @@ +python3 conv_liltalk.py +./build_liltalk.sh +rm main.o main.zx0* +make diff --git a/loader/samples/minexample/liltalk_speak.txt b/loader/samples/minexample/liltalk_speak.txt index 750d4ca..dafdaf3 100644 --- a/loader/samples/minexample/liltalk_speak.txt +++ b/loader/samples/minexample/liltalk_speak.txt @@ -1,328 +1,453 @@ -3 A -3 r -3 e -3 -3 y -3 o -3 u -3 -3 O -3 K -3 ? +4 A +4 r +4 e +4 +4 y +4 o +4 u +4 +4 O +4 K +4 ? 6 -3 . -3 . -3 . -3 -3 W -3 h -3 o -3 -3 a -3 r -3 e -3 -3 y -3 o -3 u -3 ? +4 . +4 . +4 . +4 +4 W +4 h +4 o +4 +4 a +4 r +4 e +4 +4 y +4 o +4 u +10 ? -10 -3 -3 -3 -3 -3 -3 +6 +1 +1 +1 +1 +1 +1 -3 T -3 h -3 a -3 n -3 k -3 -3 g -3 o -3 o -3 d -3 n -3 e -3 s -3 s +4 T +4 h +4 a +4 n +4 k +4 +4 g +4 o +4 o +4 d +4 n +4 e +4 s +4 s 2 .\n 1 -3 I -3 ' -3 m -3 -3 L -3 i -3 l -3 i -3 a -3 -3 f -3 r -3 o -3 m -3 -3 L -3 a -3 n -3 c -3 e -3 -3 v -3 i -3 l -3 l -3 a -3 g -3 e -3 . +4 I +4 ' +4 m +4 +4 L +4 i +4 l +4 i +4 a +4 +4 f +4 r +4 o +4 m +4 +4 L +4 a +4 n +4 c +4 e +4 +4 v +4 i +4 l +4 l +4 a +4 g +4 e +4 . 6 -3 H -3 a -3 v -3 i -3 n -3 g -3 -3 s -3 o -3 m -3 e -3 -3 k -3 i -3 n -3 d -3 -3 o -3 f -3 -3 p -3 r -3 e -3 m -3 o -3 n -3 i -3 t -3 i -3 o -3 n +1 +1 +1 +1 +1 +1 +1 + +4 H +4 a +4 v +4 i +4 n +4 g +4 +4 s +4 o +4 m +4 e +4 +4 k +4 i +4 n +4 d +4 +4 o +4 f +4 +4 p +4 r +4 e +4 m +4 o +4 n +4 i +4 t +4 i +4 o +4 n 2 ,\n 1 -3 I -3 -3 c -3 a -3 m -3 e -3 -3 h -3 e -3 r -3 e -3 -3 t -3 o -3 -3 h -3 a -3 v -3 e -3 -3 a -3 -3 l -3 o -3 o -3 k -3 . +4 I +4 +4 c +4 a +4 m +4 e +4 +4 h +4 e +4 r +4 e +4 +4 t +4 o +4 +4 h +4 a +4 v +4 e +4 +4 a +4 +4 l +4 o +4 o +4 k +4 . 6 -3 S -3 u -3 d -3 d -3 e -3 n -3 l -3 y -3 , -3 t -3 h -3 e -3 -3 a -3 r -3 e -3 a -3 -3 w -3 a -3 s -3 -3 e -3 n -3 v -3 e -3 l -3 o -3 p -3 e -3 d +4 S +4 u +4 d +4 d +4 e +4 n +4 l +4 y +4 , +4 t +4 h +4 e +4 +4 a +4 r +4 e +4 a +4 +4 w +4 a +4 s +4 +4 e +4 n +4 v +4 e +4 l +4 o +4 p +4 e +4 d 2 \n 1 -3 b -3 y -3 -3 a -3 -3 l -3 i -3 g -3 h -3 t -3 -3 a -3 n -3 d -3 -3 y -3 o -3 u -3 -3 c -3 o -3 l -3 l -3 a -3 p -3 s -3 e -3 d. +4 b +4 y +4 +4 a +4 +4 l +4 i +4 g +4 h +4 t +4 +4 a +4 n +4 d +4 +4 y +4 o +4 u +4 +4 c +4 o +4 l +4 l +4 a +4 p +4 s +4 e +4 d. 6 -64 Where am I? +4 W +4 h +4 e +4 r +4 e +4 +4 a +4 m +4 +4 I +10 ? -3 T -3 h -3 i -3 s -3 -3 i -3 s -3 -3 t -3 h -3 e -3 -3 k -3 i -3 n -3 g -3 d -3 o -3 m -3 -3 c -3 a -3 l -3 l -3 e -3 d -3 -3 Yee -3 s -3 . +4 T +4 h +4 i +4 s +4 +4 i +4 s +4 +4 t +4 h +4 e +4 +4 k +4 i +4 n +4 g +4 d +4 o +4 m +4 +4 c +4 a +4 l +4 l +4 e +4 d +4 +4 Y +4 s +4 . 6 -3 T -3 h -3 e -3 r -3 e -3 ' -3 r -3 e -3 -3 m -3 o -3 n -3 s -3 t -3 e -3 r -3 s -3 -3 n -3 e -3 a -3 r -3 . +4 T +4 h +4 e +4 r +4 e +4 ' +4 r +4 e +4 +4 m +4 o +4 n +4 s +4 t +4 e +4 r +4 s +4 +4 n +4 e +4 a +4 r +4 . 2 \n 1 -3 W -3 e -3 -3 s -3 h -3 o -3 u -3 l -3 d -3 -3 g -3 o. +4 W +4 e +4 +4 s +4 h +4 o +4 u +4 l +4 d +4 +4 g +4 o. 6 -3 H -3 o -3 w -3 -3 a -3 b -3 o -3 u -3 t -3 -3 i -3 t +4 H +4 o +4 w +4 +4 a +4 b +4 o +4 u +4 t +4 +4 i +4 t 2 ,\n 1 -3 c -3 a -3 n -3 -3 y -3 o -3 u -3 -3 s -3 t -3 a -3 n -3 d -3 -3 u -3 p? +4 c +4 a +4 n +4 +4 y +4 o +4 u +4 +4 s +4 t +4 a +4 n +4 d +4 +4 u +4 p? 6 -150 Yeah,I'm alright? Should we\n Go before the monsters come? +4 Y +4 e +4 a +4 h +4 , +4 I +4 ' +4 m +4 +4 a +4 l +4 r +4 i +4 g +4 h +4 t +4 . +4 +4 S +4 h +4 o +4 u +4 l +4 d +4 +4 w +4 e\n +4 +4 G +4 o +4 +4 b +4 e +4 f +4 o +4 r +4 e +4 +4 t +4 h +4 e +4 +4 m +4 o +4 n +4 s +4 t +4 e +4 r +4 s +4 +4 c +4 o +4 m +4 e +4 ? + +4 S +4 u +4 r +4 e +4 . +210 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -3 S -3 u -3 r -3 e -3 . -210 \ No newline at end of file diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index f5f43ab..25158ee 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -1544,7 +1544,17 @@ part_11: lda #<256 jsr wait_frame_until - lda #301-256 + lda #<256 + jsr wait_frame_until + lda #<256 + jsr wait_frame_until + lda #<256 + jsr wait_frame_until + lda #<256 + jsr wait_frame_until + lda #<256 + jsr wait_frame_until + lda #301-256 jsr wait_frame_until sei From 04884ca72a8984a1837ab81d37f5185bbe11f893 Mon Sep 17 00:00:00 2001 From: AArt1256 Date: Sat, 29 Nov 2025 17:38:05 +0300 Subject: [PATCH 22/26] fixed the text rendering --- loader/samples/minexample/conv_liltalk.py | 5 ++-- loader/samples/minexample/lilia_talk.bin | Bin 22741 -> 22739 bytes loader/samples/minexample/liltalk.bin | Bin 1278 -> 1280 bytes loader/samples/minexample/liltalk_speak.txt | 1 + loader/samples/minexample/main.asm | 26 ++++++++++---------- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/loader/samples/minexample/conv_liltalk.py b/loader/samples/minexample/conv_liltalk.py index ff21186..f35b116 100644 --- a/loader/samples/minexample/conv_liltalk.py +++ b/loader/samples/minexample/conv_liltalk.py @@ -5,7 +5,6 @@ line_addrs = [] char_cnt = 0 for line in f: if line == '': - if char_cnt >= 40: char_cnt = 0 line_addrs.append(char_cnt) char_cnt = 0 else: @@ -16,7 +15,9 @@ for line in f: i += 1 str = line[i+1:] str = str.upper() - str = str.replace("\\N","") + if "\\N" in str: str = str.split("\\N")[0] + print(str) + #str = str.replace("\\N","") char_cnt += len(str) line_addrs.append(char_cnt) diff --git a/loader/samples/minexample/lilia_talk.bin b/loader/samples/minexample/lilia_talk.bin index 5b4ad810e00b9e2df15e45c8cad2661819d7a6fe..f26c5fbfa65d3a446dbde8d391c240ba1f425986 100644 GIT binary patch delta 15 Xcmcb*k@50I#?1xdmzfq{WeNiTJevmW delta 23 fcmcb-k@4zAMkWS@&4uEZnI;Rcux`G=^g9#)YX=C( diff --git a/loader/samples/minexample/liltalk.bin b/loader/samples/minexample/liltalk.bin index ea0f503ae72ce3ad6450b3fbff6aa48b36cf85ab..209ea3457fb002cc07bb48b263084be38325d4d7 100644 GIT binary patch delta 20 ccmeyz*}%2o3Ns_y Date: Sat, 29 Nov 2025 17:42:52 +0300 Subject: [PATCH 23/26] sfx driver data works properly again --- loader/samples/minexample/sfx.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loader/samples/minexample/sfx.asm b/loader/samples/minexample/sfx.asm index 4ca6ada..164103b 100644 --- a/loader/samples/minexample/sfx.asm +++ b/loader/samples/minexample/sfx.asm @@ -77,7 +77,7 @@ sfx_num: .res 1 sfx_list: .word sfx0, sfx1, sfx1+$29 sfx0: - .incbin "sfx_badguy.bin", 256 + .incbin "sfx_badguy.bin" sfx1: - .incbin "sfx_badguy_amb.bin", 256 + .incbin "sfx_badguy_amb.bin" .endproc \ No newline at end of file From e95a0321ed3a42dbcdf59c2af7e5d338bb07b6e4 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Sat, 29 Nov 2025 21:51:09 +0700 Subject: [PATCH 24/26] Finish lilia talk --- assets/11_lilia_final.csv | 49 --------------------- loader/samples/minexample/liltalk_speak.txt | 2 +- loader/samples/minexample/main.asm | 24 ++-------- 3 files changed, 5 insertions(+), 70 deletions(-) diff --git a/assets/11_lilia_final.csv b/assets/11_lilia_final.csv index e0727d1..604de9c 100644 --- a/assets/11_lilia_final.csv +++ b/assets/11_lilia_final.csv @@ -420,52 +420,3 @@ 10,../../../assets/ys2/11_lilia_final/koala/png/16.png 10,../../../assets/ys2/11_lilia_final/koala/png/16.png 10,../../../assets/ys2/11_lilia_final/koala/png/16.png - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loader/samples/minexample/liltalk_speak.txt b/loader/samples/minexample/liltalk_speak.txt index 8a10bd4..56f441b 100644 --- a/loader/samples/minexample/liltalk_speak.txt +++ b/loader/samples/minexample/liltalk_speak.txt @@ -374,7 +374,7 @@ 4 o 4 r 4 e -4 +4 4 t 4 h 4 e diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index acf76e4..699ee2b 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -84,7 +84,7 @@ code_start: sta vbl cli - ;jsr intro + jsr intro lda #$0b sta $d011 @@ -1549,12 +1549,10 @@ part_11: lda #>dialog sta text_ptr+1 cli - - .repeat 5 + lda #<256 jsr wait_frame_until - .endrepeat - lda #144 + lda #404-256 jsr wait_frame_until sei @@ -1948,18 +1946,4 @@ write_char_dialog: inc dialog_col rts -dialog: -/* - .byte 0, "are you ok?", 0 - .byte 1, "... who are you?", 0 - .byte 2, "thank goodness.\ni'm lilia from lance village.", 0 - .byte 3, "having some kind of premonition,\ni came here to have a look.", 0 - .byte 4, "suddenly,the area was enveloped\nby a light and you collapsed.", 0 - .byte 5, "where am i?", 0 - .byte 6, "this is the restaurant called y's.", 0 - .byte 7, "there're monsters near.\nwe should go.", 0 - .byte 8, "how about it,\ncan you stand up?", 0 - .byte 9, "yeah,i'm alright.should we\ngo before the monsters come?", 0 - .byte 10, "sure.", 0 -*/ -.incbin "liltalk.bin" +dialog: .incbin "liltalk.bin" From d6c9aaab04984c1e5ce1187b442344a7bc8bb423 Mon Sep 17 00:00:00 2001 From: spaztron64 Date: Sat, 29 Nov 2025 16:36:18 +0100 Subject: [PATCH 25/26] Adjust final scene frame timings --- assets/11_lilia_final.csv | 723 ++++++++++---------- loader/samples/minexample/lilia_talk.bin | Bin 22739 -> 22739 bytes loader/samples/minexample/liltalk.bin | Bin 1280 -> 1275 bytes loader/samples/minexample/liltalk_speak.txt | 722 +++++++++---------- 4 files changed, 723 insertions(+), 722 deletions(-) diff --git a/assets/11_lilia_final.csv b/assets/11_lilia_final.csv index 604de9c..bd80bf3 100644 --- a/assets/11_lilia_final.csv +++ b/assets/11_lilia_final.csv @@ -1,32 +1,32 @@ -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -6,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +20,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -10,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +20,../../../assets/ys2/11_lilia_final/koala/png/13.png 6,../../../assets/ys2/11_lilia_final/koala/png/04.png 1,../../../assets/ys2/11_lilia_final/koala/png/05.png @@ -36,53 +36,53 @@ 1,../../../assets/ys2/11_lilia_final/koala/png/05.png 1,../../../assets/ys2/11_lilia_final/koala/png/04.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png 2,../../../assets/ys2/11_lilia_final/koala/png/02.png 1,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -6,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +20,../../../assets/ys2/11_lilia_final/koala/png/01.png 1,../../../assets/ys2/11_lilia_final/koala/png/08.png 1,../../../assets/ys2/11_lilia_final/koala/png/09.png @@ -92,312 +92,313 @@ 1,../../../assets/ys2/11_lilia_final/koala/png/09.png 1,../../../assets/ys2/11_lilia_final/koala/png/08.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png 2,../../../assets/ys2/11_lilia_final/koala/png/03.png 1,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -6,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +20,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png 2,../../../assets/ys2/11_lilia_final/koala/png/02.png 1,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +20,../../../assets/ys2/11_lilia_final/koala/png/01.png + +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +20,../../../assets/ys2/11_lilia_final/koala/png/01.png + +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png 6,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -10,../../../assets/ys2/11_lilia_final/koala/png/01.png - -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -6,../../../assets/ys2/11_lilia_final/koala/png/01.png - -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png 2,../../../assets/ys2/11_lilia_final/koala/png/02.png -1,../../../assets/ys2/11_lilia_final/koala/png/01.png +20,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -6,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +20,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/01.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03.png -4,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/01.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png +3,../../../assets/ys2/11_lilia_final/koala/png/03.png +3,../../../assets/ys2/11_lilia_final/koala/png/02.png 2,../../../assets/ys2/11_lilia_final/koala/png/01.png 1,../../../assets/ys2/11_lilia_final/koala/png/02.png -4,../../../assets/ys2/11_lilia_final/koala/png/03b.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/03b.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/03b.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/03b.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -6,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/03b.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/03b.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/03b.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/03b.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +20,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/13.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -4,../../../assets/ys2/11_lilia_final/koala/png/03b.png -4,../../../assets/ys2/11_lilia_final/koala/png/02b.png -15,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +20,../../../assets/ys2/11_lilia_final/koala/png/13.png + +3,../../../assets/ys2/11_lilia_final/koala/png/13.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +3,../../../assets/ys2/11_lilia_final/koala/png/03b.png +3,../../../assets/ys2/11_lilia_final/koala/png/02b.png +20,../../../assets/ys2/11_lilia_final/koala/png/13.png 2,../../../assets/ys2/11_lilia_final/koala/png/13.png 2,../../../assets/ys2/11_lilia_final/koala/png/14.png diff --git a/loader/samples/minexample/lilia_talk.bin b/loader/samples/minexample/lilia_talk.bin index f26c5fbfa65d3a446dbde8d391c240ba1f425986..8796b1afb25c8ca9523ff77a3294dbb86167a6fb 100644 GIT binary patch delta 1858 zcmcb-k@50I#tlpwjLef8^yPu%2Q3f@VJCn^@QXv#SOssN{7X|@QG|gRFBF;lUblGj zQmtJqKud@*o@nPxGK`12n`lkM`k5K%D~g

{SpO5)PrJSyT@PV!cFR_&3;sf}83A zO`)sM-6JyST?or+=q_iTtl&D>Lm1*_U~(46p6!Qb=s)mKq+LNmO8TB;s5v=PUkq4Q zU?z?Ra?5IFU{q13h?p!H{2m@qx5E&%2C{1@5eMq6$DXk8*D;jH0_|gz;9bnPe)aqR dpXQcN?$H+p`Vq}Xz%XQ*ETEmXIXS$55dhi|tPB7E delta 1858 zcmcb-k@50I#tlpwj4YEI^yPu%2Q3f@VJCn^@QXv#SOssN{7X|@k&S@`FXWp1UblGj zQmtJqKud@*o@nPxGK`12n`lkM`k5K%D~g

{Sq(4IB=krdd=E2V%WMVfZ)Lf`Xgs z0ZpN+(A~o}=v@fQYUnO!nXKSC*h3iNW?*s_$DZxEhHB_D1N}p%e1sYA4TxfRlA-40 zm9~nLe`$%r%Qoba1g~Z+WjIhT^}IG&GWb2*Rky-v03ETp zN_HH?O)vtjF6fPn@Q7dS*Ib5oXc=Z9<)Ic{B-fr++5Ba>NodvnL1~^3`5KK%6X?lo zUFbSdihP|6o``{b#DP3~lFtnV7=KW82B~H-<~HF8}}l literal 1280 zcmchWO-=$q5QV9>m>5(N6Ar+R4Vfzt6-43>L_y-UJ<#aa_2|wl)TJ;XP4}yMUsd&V zW49Z(SGSeh)a}D<>vo7Wi$}LbW7F=^tt}6#quWCWS^p3{vPCy(2G;xL4Eu;e{}PFb zT}Kjpmaz%K8&68@$OhfeZR0j`dk&hX_^V%X5PcuqL|1`w-<4wCO9)XM;f6!o47y1l z4J$8XihvI-4$vsQnnO1r;uKs?IRb&jt~3x3HW47BT7L82l;*jfCN_}62MtR3+UOCC@M^#IrGJO06MbQQ(03l1VW z0|kS@T()aZ+iZ$Zhm1g-qr1|omsGev-I`9x8n7|p6#zcQH|VvK^FR8hYk`0Si|#r)Mz3@U M+E3ol|M`A>18pm_k^lez diff --git a/loader/samples/minexample/liltalk_speak.txt b/loader/samples/minexample/liltalk_speak.txt index 56f441b..9e6e97d 100644 --- a/loader/samples/minexample/liltalk_speak.txt +++ b/loader/samples/minexample/liltalk_speak.txt @@ -1,32 +1,32 @@ -4 A -4 r -4 e -4 -4 y -4 o -4 u -4 -4 O -4 K -4 ? -6 +3 A +3 r +3 e +3 +3 y +3 o +3 u +3 +3 O +3 K +3 ? +20 -4 . -4 . -4 . -4 -4 W -4 h -4 o -4 -4 a -4 r -4 e -4 -4 y -4 o -4 u -10 ? +3 . +3 . +3 . +3 +3 W +3 h +3 o +3 +3 a +3 r +3 e +3 +3 y +3 o +3 u +20 ? 6 1 @@ -36,53 +36,53 @@ 1 1 -4 T -4 h -4 a -4 n -4 k -4 -4 g -4 o -4 o -4 d -4 n -4 e -4 s -4 s +3 T +3 h +3 a +3 n +3 k +3 +3 g +3 o +3 o +3 d +3 n +3 e +3 s +3 s 2 .\n 1 -4 I -4 ' -4 m -4 -4 L -4 i -4 l -4 i -4 a -4 -4 f -4 r -4 o -4 m -4 -4 L -4 a -4 n -4 c -4 e -4 -4 v -4 i -4 l -4 l -4 a -4 g -4 e -4 . -6 +3 I +3 ' +3 m +3 +3 L +3 i +3 l +3 i +3 a +3 +3 f +3 r +3 o +3 m +3 +3 L +3 a +3 n +3 c +3 e +3 +3 v +3 i +3 l +3 l +3 a +3 g +3 e +3 . +20 1 1 @@ -92,313 +92,313 @@ 1 1 -4 H -4 a -4 v -4 i -4 n -4 g -4 -4 s -4 o -4 m -4 e -4 -4 k -4 i -4 n -4 d -4 -4 o -4 f -4 -4 p -4 r -4 e -4 m -4 o -4 n -4 i -4 t -4 i -4 o -4 n +3 H +3 a +3 v +3 i +3 n +3 g +3 +3 s +3 o +3 m +3 e +3 +3 k +3 i +3 n +3 d +3 +3 o +3 f +3 +3 p +3 r +3 e +3 m +3 o +3 n +3 i +3 t +3 i +3 o +3 n 2 ,\n 1 -4 I -4 -4 c -4 a -4 m -4 e -4 -4 h -4 e -4 r -4 e -4 -4 t -4 o -4 -4 h -4 a -4 v -4 e -4 -4 a -4 -4 l -4 o -4 o -4 k -4 . -6 +3 I +3 +3 c +3 a +3 m +3 e +3 +3 h +3 e +3 r +3 e +3 +3 t +3 o +3 +3 h +3 a +3 v +3 e +3 +3 a +3 +3 l +3 o +3 o +3 k +3 . +20 -4 S -4 u -4 d -4 d -4 e -4 n -4 l -4 y -4 , -4 t -4 h -4 e -4 -4 a -4 r -4 e -4 a -4 -4 w -4 a -4 s -4 -4 e -4 n -4 v -4 e -4 l -4 o -4 p -4 e -4 d +3 S +3 u +3 d +3 d +3 e +3 n +3 l +3 y +3 , +3 t +3 h +3 e +3 +3 a +3 r +3 e +3 a +3 +3 w +3 a +3 s +3 +3 e +3 n +3 v +3 e +3 l +3 o +3 p +3 e +3 d 2 \n 1 -4 b -4 y -4 -4 a -4 -4 l -4 i -4 g -4 h -4 t -4 -4 a -4 n -4 d -4 -4 y -4 o -4 u -4 -4 c -4 o -4 l -4 l -4 a -4 p -4 s -4 e -4 d. +3 b +3 y +3 +3 a +3 +3 l +3 i +3 g +3 h +3 t +3 +3 a +3 n +3 d +3 +3 y +3 o +3 u +3 +3 c +3 o +3 l +3 l +3 a +3 p +3 s +3 e +3 d. +20 + +3 W +3 h +3 e +3 r +3 e +3 +3 a +3 m +3 +3 I +20 ? + +3 T +3 h +3 i +3 s +3 +3 i +3 s +3 +3 t +3 h +3 e +3 +3 k +3 i +3 n +3 g +3 d +3 o +3 m +3 +3 c +3 a +3 l +3 l +3 e +3 d +3 +3 Y +3 s +3 . 6 -4 W -4 h -4 e -4 r -4 e -4 -4 a -4 m -4 -4 I -10 ? - -4 T -4 h -4 i -4 s -4 -4 i -4 s -4 -4 t -4 h -4 e -4 -4 k -4 i -4 n -4 g -4 d -4 o -4 m -4 -4 c -4 a -4 l -4 l -4 e -4 d -4 -4 Y -4 s -4 . -6 - -4 T -4 h -4 e -4 r -4 e -4 ' -4 r -4 e -4 -4 m -4 o -4 n -4 s -4 t -4 e -4 r -4 s -4 -4 n -4 e -4 a -4 r -4 . +3 T +3 h +3 e +3 r +3 e +3 ' +3 r +3 e +3 +3 m +3 o +3 n +3 s +3 t +3 e +3 r +3 s +3 +3 n +3 e +3 a +3 r +3 . 2 \n -1 +20 -4 W -4 e -4 -4 s -4 h -4 o -4 u -4 l -4 d -4 -4 g -4 o. -6 +3 W +3 e +3 +3 s +3 h +3 o +3 u +3 l +3 d +3 +3 g +3 o. +20 -4 H -4 o -4 w -4 -4 a -4 b -4 o -4 u -4 t -4 -4 i -4 t +3 H +3 o +3 w +3 +3 a +3 b +3 o +3 u +3 t +3 +3 i +3 t 2 ,\n 1 -4 c -4 a -4 n -4 -4 y -4 o -4 u -4 -4 s -4 t -4 a -4 n -4 d -4 -4 u -4 p? -6 +3 c +3 a +3 n +3 +3 y +3 o +3 u +3 +3 s +3 t +3 a +3 n +3 d +3 +3 u +3 p? +20 -4 Y -4 e -4 a -4 h -4 , -4 I -4 ' -4 m -4 -4 a -4 l -4 r -4 i -4 g -4 h -4 t -4 . -4 -4 S -4 h -4 o -4 u -4 l -4 d -4 -4 w -4 e\n +3 Y +3 e +3 a +3 h +3 , +3 I +3 ' +3 m +3 +3 a +3 l +3 r +3 i +3 g +3 h +3 t +3 . +3 +3 S +3 h +3 o +3 u +3 l +3 d +3 +3 w +3 e\n -4 -4 G -4 o -4 -4 b -4 e -4 f -4 o -4 r -4 e -4 -4 t -4 h -4 e -4 -4 m -4 o -4 n -4 s -4 t -4 e -4 r -4 s -4 -4 c -4 o -4 m -4 e -4 ? +3 +3 G +3 o +3 +3 b +3 e +3 f +3 o +3 r +3 e +3 +3 t +3 h +3 e +3 +3 m +3 o +3 n +3 s +3 t +3 e +3 r +3 s +3 +3 c +3 o +3 m +3 e +20 ? -4 S -4 u -4 r -4 e -4 . +3 S +3 u +3 r +3 e +20 . 210 From 31286bcad530238aa4034a1f35e16752bc1ea0d6 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Sun, 30 Nov 2025 18:39:21 +0700 Subject: [PATCH 26/26] Add beginning info text --- loader/samples/minexample/lilia_talk.bin | Bin 22739 -> 22739 bytes loader/samples/minexample/main.asm | 5 +- loader/samples/minexample/minexample.s | 74 ++++++++++++++++++++++- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/loader/samples/minexample/lilia_talk.bin b/loader/samples/minexample/lilia_talk.bin index 8796b1afb25c8ca9523ff77a3294dbb86167a6fb..c1e4edef4127494a3d2b0dc6410cd5b7f2c3c8d4 100644 GIT binary patch delta 219 gcmcb-k@50I#tjKd^$i0HJgH{=M8>GiP0E3$0K=YZ&j0`b delta 18 acmcb-k@50I#tjKd8wHdYH#aEcopyright diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 76eca09..3fe7e6b 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -14,6 +14,7 @@ pntr = ZP+7 .org $080d + jsr print_info copy_start: sei @@ -53,8 +54,8 @@ check_return: dec $01 jmp CODE_START_ADDR - .assert zx02 = $082f, error, .sprintf("change zx02 address to $%04x", zx02) - .assert check_return = $08b5, error, .sprintf("change check_return address to $%04x", check_return) + .assert zx02 = $0832, error, .sprintf("change zx02 address to $%04x", zx02) + .assert check_return = $08b8, error, .sprintf("change check_return address to $%04x", check_return) .res loadraw - * .incbin "../../build/loader-c64.prg", 2 @@ -63,3 +64,72 @@ check_return: .incbin "../../build/install-c64.prg", 2 code: .incbin "main.zx0" + +print_info: + lda #$20 + ldx #0 +: + sta $400,x + sta $500,x + sta $600,x + sta $700,x + inx + bne :- + lda #41 + sta ZX0_dst + lda #4 + sta ZX0_dst+1 + lda #$17 + sta $d018 + ldy #0 +@print_loop: + lda info,x + bne :++ + lda ZX0_dst + clc + adc #40 + sta ZX0_dst + bcc :+ + inc ZX0_dst+1 +: + ldy #0 + beq :++ +: + sta (ZX0_dst),y + iny +: + inx + cpx #info_end-info + bne @print_loop + rts + + .macpack cbm +info: + scrcode "Code:" + .byte 0 + scrcode " Aart1256 - engine, music driver" + .byte 0 + scrcode " Natt - engine, tooling" + .byte 0, 0 + scrcode "C64 Graphics:" + .byte 0 + scrcode " Grongy" + .byte 0 + scrcode " Natt" + .byte 0, 0 + scrcode "Music arranges & ported graphics:" + .byte 0 + scrcode " Aleksa Odzakovic (spaztron64)" + .byte 0, 0 + scrcode "Greetz to:" + .byte 0 + scrcode " Gyabo" + .byte 0 + scrcode " Yosshin" + .byte 0 + scrcode " Hadohado" + .byte 0 + scrcode " Kazpulse" + .byte 0 + scrcode " Gam" +info_end: