From ea49a5d11c6b51304a90c2ee94d0a9700026220c Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Wed, 23 Dec 2020 14:54:17 -0500 Subject: [PATCH] Add the scorpion sounds. --- BUGS.md | 1 + BuGS.xcodeproj/project.pbxproj | 2 + BuGS/gameScorpion.s | 9 +++ BuGS/gameSound.s | 117 +++++++++++++++++++++++++++------ BuGS/main.c | 9 +++ BuGS/main.h | 1 + BuGS/main.rez | 1 + BuGS/make/launchEmulator | 2 +- BuGS/sound/scorpion.raw | Bin 0 -> 6634 bytes 9 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 BuGS/sound/scorpion.raw diff --git a/BUGS.md b/BUGS.md index 4fe3aab..376b968 100644 --- a/BUGS.md +++ b/BUGS.md @@ -11,6 +11,7 @@ This is a list of the software bugs (as opposed to the bugs in the game that you * In order to get the wrong value in Y, I noticed that the segmentSpriteOffset was overwritten with the pattern 70 02 70 02, etc. * Something is trashing memory. * A spider moving left to right went off screen and left garbage on the RHS as it exited. I have only seen this once. I think it coincided with the player dying. +* Sometimes at the end of the flea sound, there is a short high pitched tone. diff --git a/BuGS.xcodeproj/project.pbxproj b/BuGS.xcodeproj/project.pbxproj index a9b1068..620042b 100644 --- a/BuGS.xcodeproj/project.pbxproj +++ b/BuGS.xcodeproj/project.pbxproj @@ -95,6 +95,7 @@ 9D62AF3F2499CD1E00348F45 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 9D62AF402499CD3A00348F45 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 9D6DB0AE2591A67700CDBF05 /* flea.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = flea.raw; sourceTree = ""; }; + 9D6DB0B825932CA600CDBF05 /* scorpion.raw */ = {isa = PBXFileReference; lastKnownFileType = text; path = scorpion.raw; sourceTree = ""; }; 9D8AF0B72535542400C10E3C /* level.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = level.s; sourceTree = ""; }; 9D8AF0B82535543000C10E3C /* score.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = score.s; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.asm.orcam; }; 9D8FFC602491CA28005C9327 /* game.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = game.s; sourceTree = ""; }; @@ -128,6 +129,7 @@ 9D6DB0AE2591A67700CDBF05 /* flea.raw */, 9D0DC8EF258C715E00DE9E87 /* extralife.raw */, 9D1553EB257F3E5200657188 /* death.raw */, + 9D6DB0B825932CA600CDBF05 /* scorpion.raw */, 9D1553E9257F3E5200657188 /* fire.raw */, 9D1553EC257F3E5200657188 /* kill.raw */, 9D1553ED257F3E5200657188 /* segments.raw */, diff --git a/BuGS/gameScorpion.s b/BuGS/gameScorpion.s index 9747347..c3c29a0 100644 --- a/BuGS/gameScorpion.s +++ b/BuGS/gameScorpion.s @@ -170,6 +170,8 @@ updateScorpionLeft_nextTile anop stx scorpionTileOffsets+2 lda tileLeft,x sta scorpionTileOffsets + jsl updateScorpionSound + ldx scorpionTileOffsets+2 bra updateScorpion_maybePoison updateScorpionRight_notOffScreen anop @@ -178,6 +180,8 @@ updateScorpionRight_notOffScreen anop stx scorpionTileOffsets+2 lda tileRight,x sta scorpionTileOffsets + jsl updateScorpionSound + ldx scorpionTileOffsets+2 updateScorpion_maybePoison anop lda tileType,x @@ -192,6 +196,7 @@ updateScorpion_done anop updateScorpion_offScreen anop stz scorpionState + jsl stopScorpionSound rtl updateScorpion_exploding anop @@ -327,6 +332,9 @@ addScorpion_common anop lda scorpionSpriteLastOffset sta scorpionSprite + + ldx scorpionTileOffsets + jsl startScorpionSound addScorpion_done anop rtl @@ -372,6 +380,7 @@ shootScorpion entry inc a sta scorpionScreenOffset ldx scorpionTileOffsets+2 + jsl stopScorpionSound jsl playKillSound jmp scoreAddOneThousand diff --git a/BuGS/gameSound.s b/BuGS/gameSound.s index b882151..c1ef28f 100644 --- a/BuGS/gameSound.s +++ b/BuGS/gameSound.s @@ -38,7 +38,6 @@ SPIDER_SOUND_ADDR equ $0000 SPIDER_OSC_NUM equ 16 SPIDER_FREQ_HIGH equ 0 SPIDER_FREQ_LOW equ 214 -SPIDER_VOLUME equ 128 SPIDER_CONTROL equ 6 SPIDER_SIZE equ $36 @@ -47,16 +46,15 @@ DEATH_SOUND_ADDR equ $4000 DEATH_OSC_NUM equ 10 DEATH_FREQ_HIGH equ 0 DEATH_FREQ_LOW equ 214 -DEATH_VOLUME equ 80 DEATH_CONTROL equ 2 -DEATH_SIZE equ $36 +DEATH_SIZE equ $2d ; OSC 12 - 15 for L/R channels in swap mode SEGMENTS_SOUND_ADDR equ $7000 SEGMENTS_OSC_NUM equ 12 SEGMENTS_FREQ_HIGH equ 0 SEGMENTS_FREQ_LOW equ 214 -SEGMENTS_VOLUME equ 80 +SEGMENTS_VOLUME equ 128 SEGMENTS_CONTROL equ 6 SEGMENTS_SIZE equ $24 @@ -99,6 +97,14 @@ FLEA_OSC_NUM equ 22 FLEA_CONTROL equ 6 FLEA_SIZE equ $00 +; OSC 26 - 30 for L/R channels in swap mode +SCORPION_SOUND_ADDR equ $e000 +SCORPION_OSC_NUM equ 26 +SCORPION_FREQ_HIGH equ 0 +SCORPION_FREQ_LOW equ 214 +SCORPION_CONTROL equ 6 +SCORPION_SIZE equ $2d + ; X register has the address of the register to read ; Accumulator contains the result of the read @@ -200,10 +206,6 @@ soundInit_writeRegLow anop ldx #SOUND_REG_FREQ_HIGH+SPIDER_OSC_NUM jsl writeConsecSoundReg - lda #SPIDER_VOLUME - ldx #SOUND_REG_VOLUME+SPIDER_OSC_NUM - jsl writeConsecSoundReg - lda #SPIDER_SIZE ldx #SOUND_REG_SIZE+SPIDER_OSC_NUM jsl writeConsecSoundReg @@ -224,10 +226,6 @@ soundInit_writeRegLow anop ldx #SOUND_REG_FREQ_HIGH+SPIDER_OSC_NUM+2 jsl writeConsecSoundReg - lda #SPIDER_VOLUME - ldx #SOUND_REG_VOLUME+SPIDER_OSC_NUM+2 - jsl writeConsecSoundReg - lda #SPIDER_SIZE ldx #SOUND_REG_SIZE+SPIDER_OSC_NUM+2 jsl writeConsecSoundReg @@ -253,10 +251,6 @@ soundInit_writeRegLow anop ldx #SOUND_REG_FREQ_HIGH+DEATH_OSC_NUM jsl writeConsecSoundReg - lda #DEATH_VOLUME - ldx #SOUND_REG_VOLUME+DEATH_OSC_NUM - jsl writeConsecSoundReg - lda #DEATH_SIZE ldx #SOUND_REG_SIZE+DEATH_OSC_NUM jsl writeConsecSoundReg @@ -520,6 +514,51 @@ soundInit_writeRegLow anop ldx #SOUND_REG_CONTROL+FLEA_OSC_NUM+2 jsl writeConsecSoundReg + +; Scorpion sound + pea SCORPION_SOUND_ADDR + jsl loadScorpionSound + + lda #SCORPION_FREQ_LOW + ldx #SOUND_REG_FREQ_LOW+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + lda #SCORPION_FREQ_HIGH + ldx #SOUND_REG_FREQ_HIGH+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + lda #SCORPION_SIZE + ldx #SOUND_REG_SIZE+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + lda #SCORPION_SOUND_ADDR/256 + ldx #SOUND_REG_POINTER+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + lda #SCORPION_CONTROL+SOUND_HALTED+SOUND_RIGHT_SPEAKER + ldx #SOUND_REG_CONTROL+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + lda #SCORPION_FREQ_LOW + ldx #SOUND_REG_FREQ_LOW+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + + lda #SCORPION_FREQ_HIGH + ldx #SOUND_REG_FREQ_HIGH+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + + lda #SCORPION_SIZE + ldx #SOUND_REG_SIZE+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + + lda #SCORPION_SOUND_ADDR/256 + ldx #SOUND_REG_POINTER+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + + lda #SCORPION_CONTROL+SOUND_HALTED+SOUND_LEFT_SPEAKER + ldx #SOUND_REG_CONTROL+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + rtl @@ -811,12 +850,52 @@ stopSpiderSound entry startScorpionSound entry -; Write this code... + lda tileRightVolume,x + pha + jsl stopSpiderSound + + pla + pha + ldx #SOUND_REG_VOLUME+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + pla + eor #$ff + ldx #SOUND_REG_VOLUME+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + + lda #SCORPION_CONTROL+SOUND_RIGHT_SPEAKER + ldx #SOUND_REG_CONTROL+SCORPION_OSC_NUM + jsl writeSoundReg + + lda #SCORPION_CONTROL+SOUND_LEFT_SPEAKER + ldx #SOUND_REG_CONTROL+SCORPION_OSC_NUM+2 + jsl writeSoundReg + rtl + + +updateScorpionSound entry + lda tileRightVolume,x + pha + ldx #SOUND_REG_VOLUME+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + pla + eor #$ff + ldx #SOUND_REG_VOLUME+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + rtl - stopScorpionSound entry -; Write this code... + lda #SCORPION_CONTROL+SOUND_HALTED+SOUND_RIGHT_SPEAKER + ldx #SOUND_REG_CONTROL+SCORPION_OSC_NUM + jsl writeConsecSoundReg + + lda #SCORPION_CONTROL+SOUND_HALTED+SOUND_LEFT_SPEAKER + ldx #SOUND_REG_CONTROL+SCORPION_OSC_NUM+2 + jsl writeConsecSoundReg + rtl diff --git a/BuGS/main.c b/BuGS/main.c index 4c905cb..ad6db6e 100644 --- a/BuGS/main.c +++ b/BuGS/main.c @@ -118,6 +118,15 @@ void loadFleaSound(word addr) } +void loadScorpionSound(word addr) +{ + Handle handle = LoadResource(rRawSound, SCORPION_SOUND); + HLock(handle); + WriteRamBlock(*handle, addr, GetHandleSize(handle)); + HUnlock(handle); +} + + int main(void) { int event; diff --git a/BuGS/main.h b/BuGS/main.h index 38bf0f6..bdefce7 100644 --- a/BuGS/main.h +++ b/BuGS/main.h @@ -25,6 +25,7 @@ #define SPIDER_SOUND 6 #define EXTRA_LIFE_SOUND 7 #define FLEA_SOUND 8 +#define SCORPION_SOUND 9 #endif /* defined(_GUARD_PROJECTBuGS_FILEmain_) */ diff --git a/BuGS/main.rez b/BuGS/main.rez index 2fe97bc..2a273ca 100644 --- a/BuGS/main.rez +++ b/BuGS/main.rez @@ -56,3 +56,4 @@ read rRawSound (SEGMENTS_SOUND) "sound/segments.raw"; read rRawSound (SPIDER_SOUND) "sound/spider.raw"; read rRawSound (EXTRA_LIFE_SOUND) "sound/extralife.raw"; read rRawSound (FLEA_SOUND) "sound/flea.raw"; +read rRawSound (SCORPION_SOUND) "sound/scorpion.raw"; diff --git a/BuGS/make/launchEmulator b/BuGS/make/launchEmulator index 2f4a9be..ba082a8 100755 --- a/BuGS/make/launchEmulator +++ b/BuGS/make/launchEmulator @@ -27,7 +27,7 @@ sed -i "" "s:^s7d1 *=.*$:s7d1 = $DISKIMAGE:" config.txt # This magic ensure that clicking stop in Xcode results in the emulator terminating. -if true +if false then $EMULATORPATH -fullscreen -mem 1572864 & PID=$! diff --git a/BuGS/sound/scorpion.raw b/BuGS/sound/scorpion.raw new file mode 100644 index 0000000000000000000000000000000000000000..e1db2be74a66d72dda8fc97d0f984ba23cc238fe GIT binary patch literal 6634 zcmWld`EwlSncwqYZBJLOGW>v+A%uC;vrI$L{XwZ zikAq0#4%_0^nFkF+!%lWL{heuO0qv}Roc}xRsG9!zx}??^ZkCl&qWaV?S=eD<-6j1 z`toOe<)_a6d#i4A8oI2Go}eH7%auINq;gpd&wh+&uIpB4OUk)&ZUu&S{_g1#d;jBq zVLv&_J^<1;=*7iHO}qVnZ>?3|??->qYcxQ8N_}(x)6YRHMQ!k#ZwBw(k%SD7 z&w7Wh7AV3Rle^A*`4zW;a~sub_9U@?R;RhX7o2<=P0n8S-U5VqqgzNp6+rKpf0w3LpHM%FsAc zg$wQ8aHJm@lc9ZP&Zft+v*}dtDU+w*`wjFO1pqjJB1DQz?h;FQf?(G(0*Kx@-#h+7 zh~mE;HwIlRu*d!+I`;qUjO+9##TpD^9KMqL`z4e`D!EK{kt&G@_{6h(+fqHph$1Zv z{G%}J4QB(ziJt$@4{F2;U&YHpi9;$R#}sjHkpZw`ws~R=1Ix8-HNFhfaZJq{gtqC- zZsV(!<=V>fN==~o0?V*`fuWfyC!}vX-R@!gU}s-Z+J_xUQFPg!O@dK4bjvW$(+C2Q zL_U>82;^&{-u7L6AjNM8Mvf$1&sCTu9$)5)HInDn%bRD-@Nr>gS?y?M25w++RFPmI z{2EihOBGfsz3h!A(J&gwsx`GdcVw(WJeOy0{`LaT(D9n6!oX2Rt(Lj#XucG*BKMnz ztiadU5>|jpBDzek4`&zw1a7HFqW;^kJjlSQdo!|v3)xyvZdcs3}_EMPn$g> zC$1L#<=>s3?!)EMb%1_EP*eg=kSHs;ofBnpe-#ioFiI&|3r=UAw$>t<~u)ph?S{)8T|G(!cy_0 zmMSY1^bUh>WEIOEb={uVbrsX}eS6joTho_W3g56VaU4a1di*5n`m5rToI>07>6K)z@c1j zE|>jIl~lv_+l^l6?@i0sjCw=ww@&YYIKz?v^&L)#09~j6B0_RBx;1oV&oaNi)No$u zil@}It`zP@PZOYsu>|v)PtX*G-VmwP8gdg@Rh@}?sPq?}+PmG|<5#=-;VVUVz6TTH zLLMTwZ*i3(mjWqKAP`EpDNS_A);-|S_?6!FWu-GZZ0g-Qks$DS{PMk8g2?iVs{l$c z2wvq|Cy_JjoEFxP4xL`#up1*~AUE}D0?b^lrN8`av52DxoVW_W3yWy&aI6pCg=h52 zNE(|_a1@OE;Z*M3M9~rgW^O%SphyDArAU%YWRX;-rR)4S8cp8%)*=aiD?+5m@>>!LTN5fF~}!mV7kLY!%?-M(X>q2vDKzO3^Ip6P`gvMyx>&-MRu!6q!>hX;{n7;rcDF93WcpA%Qmu@jHCf2}^J8?g& zYNOui9dy3>jL9rq%|Pi4l+555mInatD^hjTfoBhG_c-i1&e_PBK6)$`1RMs~D!s%I zaV^v7_2tc(?rGXk9Z$!8ZyNkyPgyv^G78-BVDfhOelT_(-9y(3ypUnAG{J(& zERHT<|Lr#-fk6O9upB0=^MyiTbM@5?@m^&kJUTrI&rgR(M`LYfWP`EWH;-joHcZ>z zRlBjF_@;Cq@7EiV=4>Ycw1{D)f4*7-SJ-@oN7riAHEOfM*YXdq$AXVtNaJ`a4bLYR zfd#gs=}PmU(>QE(4pWWJrSJMS@Cy8C#s^1-h!3 zb#wS?Vk>R6t=o#!eMXR&2xA1zt(E_J3LM9X1cU$eSY=g_w3f7=klS^2$5$n-+wLfB zGZ=2+HKrsAG){AZAXds{0ImTLJ3j~1bW5*yOr^C`-|y^o_ILNRgN~sG?V+~$iv*c1 zrrBa1qq6a4lPrMH3rQTwZ1u;QuQ{RBv!h@-b$h1Nj}P9^>?hdI7tjrZna%AhEW@+<(83=8h~ zk|WzePi`uf<|*xmITV0%8JJ}SHr{oS+6@LhRcm!LOEwKxG8GQSa8k(OG!9e3-z3Q| zC(`tl5=dTXw_~hv+BaYh7U5ejLk5Tj39G1VDZU3L1ZJLwS#0_SF zVGme}1C}$D!m<|C-*o$>we#1S5G~ z?h|DUDQ`TBg&Qob^B~vP5C6P>Rsi4a#YijLXLsgqrDLpY)MzGG1Q>Xw+pWJf-`rms z?Tp9XV1M!eudu1b^wu>Xl|(Nl^XRMg6Ms*;#`ZPCFefMPcG;C`v9j@`NV7x{W7&JDzS`P*x!buOn|TuX_%ZZh>O(x8y2yU*KT}$xR(j&tYS?q9Ezbz_!>x8_ z`}X2o>T;4^1pfICSBc;KEDeAe5G670`X}F<{cv=Aay$&RD2$F@nTPv((*DJ5Wp8_* znM+^56Bx#zTlZlBg#|p1EG7{USiFhf@9+A%&Dcp=p{c|oaq8+Z%1Y)wok(7~1f>^} z`2>>7qd5YhAvl*su*{>-IhvkK9mg{aE#{=588@QT?H(wb$)!vAJdEX2O9_O|0A%J$ zx%{&W@WK+N^_tR=FWVi{n)Z(@a~znBZpUe9-O}Iw9$mnbIg&_%c>wu%!Vr+Y z6_{FFjU&a=EK3=h&g+)c*^%0ZaufVd`TX3)bmqchCbxvA)4)O+MR@`)<+smg6Eo24 z&e-U56~Aw*%Im#7w_~c`Ui=5K7<2ndv3i|c<`9+upaNSYQ3A7$72S;_qZhWdw&z)o zOC_`l;jy^!|M}-|+|Y-XW;w&aHBV&oO*kDsW|x7@J0x9+8#T`&B;1GY+e;v2@G zx7d7+^8`!tWDzQ75h@F?Pdue-TjtroGl#t(7%Ku>xxT*1ujPt#OsJQ+3K!{}rdB^Y zR~38jz&ps!EoH?li(%9Q0WZ>g{n#?>(dnc=Rsze`wWq*E^zVMnG^q58fpK#70Q-TO9J59m5pyuHX)FLK;N@$yRE;$Ue9(0MpKT4U!fdVE>uOP zyduQ%jNSY5)Uf>VQNQ00biK86KzxJ&6fvL5f+U5cS@wPus+JUuo5!lF8!>;F<8IgJ zJ$faOC31~pI033=AY|ir|8N5l7`8s~d-g1}O#i(ToV`DKH&k53mshd1|M5>e1amb` z#DM%YlwPNwQMt|_bllMBtM$S6ZyywXu%}%^^6XXSR)J@Tr`4EL5uy}_12!#w$Ze3l zpm*Ln=(k*Z@^8a1{Nc!H2B%N%k~9G_7*i=n;fz8xIJayM#?gY(h&QAy0^ z1dezS(>u(^%fK#ujEVUz%MTlMS%+Sq8|O#T=&buTuH4Z+Eao{Dtv%bISt^Bc|9UOQ z3fZMqrR&RG$6b8Y-&ed|`v-Mmd%@%dTSYlC2W@ZAD?~9*Bt;m;m-yN%#j7{Wcj;U2 zr9tydiR8X!JGMs(3$bmd?%smOye&w#Q#t?SmHTK=hN?AvZ&>(j}^G^n`7 zS(?7NmlP2ulZ^>BnMSA!u2Hw`1OG+Zw^hlvN4g&ve&EqKg`%sen@?hsi@SMlVSYZF zfq@scqPJyBQ*BB2!k9tgYUrzsmSYa4jWtGy(+W!gIXVUZ`VZ@iOUXxj ziqw{y&9GmOnb?uM;g7-Rt0J;Mq>(}{5pyNT=b$;Eg0$MBw%qoIsv5aXTMAD0o~$n5 zpio8-jNve}P$3ej>zVJgLq*p0c1yPGwtCR9!ml3|*<7A0@ED%wS+Yc>Q?*Y~scp$} zcVB<4^i-=Ew)E~75A)y>K*n5viX2as5;RfZc&{aO2Qh5zsBY|6#{Tr1ukIDZoR~lb zoLOLN9Gn+3TdD88w%KTI`+FUye&9GQ!&%uPIWmr|YZMI?SC~?o%o8{0s1t^EqaMo2 zvzFGjwdmF6-GzCWT}0O463dfpc@aWy0^bh1R(EvRau3>a%amo+SbGd*nFJYsF$S=4 zA+rS`b3clSB#yq#u4Pzq`=Gt|T3b#gQ@LCgL~=|H1k%YRG%rZL>soH?6P^8dXXH5M zyQK|!=EX#4qGTpipg^qG;OhVIdgbn$yoJ-8-3iDVd zm-uBaf#nf46R)W7#5a1j()5SE)2+vNBz2|cOdHTZDfv$yLjOxdAb?xPP>6@Y^>XT- z8x4+R`|V-Rx4IL{-u+%3w-@yrgm`5>=GGz$E#yI@EM9+7sV*lTM9NI<$kXmjcY~k4 z7NcCp!@mD01$59L` zqZN?lR~W2%QB7g zN5`*whH5&#d+HOQfX6>}zQ`SW1vHe22OW?e3Q zQBAK^mrK=4nbf6BTEI3q@ovJ@TW_4$*Hou%#8UUt*}wBe1`|*W1%OKn3>8=PYVk9w z8n!*tv)!H%cxp%8+n(J0;%;I!39|6gTz&z#w0L!)2t1;xZW9#998( zZ(H@lW^sYSfHl5`f!T$^@Be!iEMy5R&MXCdS20_LSNA7+q}j1i9`w6r+um^+($?Sn z8cAmpB$O{_1qzBe6DUy6YGfI%>2`CcrPrH|?!Gu`WbJ;xC;5>(l)7SKVS!+?H^0tR zU^t6i`NLe6DJMvxn0ojPHE0+et3T;QqnM4np6kDM|Dr1s2}9GD;aobKA#ofj{qhg_ ztFS2KiwsY{?ghg^5D)%j|1W)G(tG*aUjSE<839X!D=RpdT!bqk;p_|T3c#GwpI=9x;7N76ViU_`8=V!qhzd&9}lnTATBxq966iZ&dY z)8U|ZNY}gC&>T&sqrN}v+x@|jJDa}gR{!xM zmaCLe`Zka*a$pwaV*)6FIgWhMcWgtq9Jdn%k!8fgW+w<7b96G0fS+ej2rUvkM--Q7 zjHx@L+2KeHM&t2NX-U)P5HTOeB)kY?B!R9Vd~Cr#vR_QJi4t~PZy4?)*Ldc$YMlR} z@(sSU1%K5E28O4YmScy_$dIH0&a(^L+OMFsbzZDgna}LrAozd%&I8xGU(HRJ((Sa_2zV+>c%7L&L)`yNqSinu_7WYQN$O0Svh&r(58LuWOVx8 zoP0(ulLAbM%M1&!zqwFddprEobokDW2GPWuz8Sk^Xf0X5z^%d>DdHfJyw=zJY2)8k zH+rh0S?0;Gh}070H1R0MQ4E_W=kMzA>}c<#c5`?b?2Y47d7db7n>ew}vdb{RP_*d! fEvr8?;~A^xYhG*c2#RA15oaBaVMqvs|HJ