From d5b27e5441f3d86268595ce3c4ebb2e4b32ae8a7 Mon Sep 17 00:00:00 2001 From: pelya Date: Mon, 26 Jul 2010 15:25:35 +0300 Subject: [PATCH] Added Jooleem sources (I've changed them too much from the original, have to publish them to conform with LGPL) --- .../application/jooleem_0.1.4/AppSettings.cfg | 13 + .../jni/application/jooleem_0.1.4/Jooleem.ico | Bin 0 -> 192086 bytes .../jni/application/jooleem_0.1.4/Jooleem.png | Bin 0 -> 7668 bytes .../jni/application/jooleem_0.1.4/Jooleem.rc | 72 ++ .../jni/application/jooleem_0.1.4/Jooleem.sln | 21 + .../application/jooleem_0.1.4/Jooleem.vcproj | 351 +++++++++ .../application/jooleem_0.1.4/changelog.txt | 170 ++++ .../jni/application/jooleem_0.1.4/gpl.txt | 340 ++++++++ .../jni/application/jooleem_0.1.4/makefile | 3 + .../jni/application/jooleem_0.1.4/readme.txt | 78 ++ .../jni/application/jooleem_0.1.4/resource1.h | 15 + .../jooleem_0.1.4/src/UI/aboutwindow.cpp | 141 ++++ .../jooleem_0.1.4/src/UI/aboutwindow.h | 55 ++ .../jooleem_0.1.4/src/UI/gameoverwindow.cpp | 152 ++++ .../jooleem_0.1.4/src/UI/gameoverwindow.h | 60 ++ .../jooleem_0.1.4/src/UI/highscoreswindow.cpp | 152 ++++ .../jooleem_0.1.4/src/UI/highscoreswindow.h | 57 ++ .../jooleem_0.1.4/src/UI/mainwindow.cpp | 172 ++++ .../jooleem_0.1.4/src/UI/mainwindow.h | 65 ++ .../jooleem_0.1.4/src/UI/quitwindow.cpp | 103 +++ .../jooleem_0.1.4/src/UI/quitwindow.h | 53 ++ .../jooleem_0.1.4/src/UI/uibutton.cpp | 559 +++++++++++++ .../jooleem_0.1.4/src/UI/uibutton.h | 166 ++++ .../jooleem_0.1.4/src/UI/uicontrol.cpp | 59 ++ .../jooleem_0.1.4/src/UI/uicontrol.h | 79 ++ .../jooleem_0.1.4/src/UI/uilabel.cpp | 205 +++++ .../jooleem_0.1.4/src/UI/uilabel.h | 83 ++ .../jooleem_0.1.4/src/UI/uiprogress.cpp | 141 ++++ .../jooleem_0.1.4/src/UI/uiprogress.h | 76 ++ .../jooleem_0.1.4/src/UI/uitextbox.cpp | 282 +++++++ .../jooleem_0.1.4/src/UI/uitextbox.h | 99 +++ .../jooleem_0.1.4/src/UI/uiwindow.cpp | 307 ++++++++ .../jooleem_0.1.4/src/UI/uiwindow.h | 86 ++ .../jooleem_0.1.4/src/common/common.h | 62 ++ .../src/common/effectmanager.cpp | 211 +++++ .../jooleem_0.1.4/src/common/effectmanager.h | 72 ++ .../jooleem_0.1.4/src/common/events.h | 67 ++ .../jooleem_0.1.4/src/common/filenames.h | 168 ++++ .../jooleem_0.1.4/src/common/font.cpp | 318 ++++++++ .../jooleem_0.1.4/src/common/font.h | 84 ++ .../jooleem_0.1.4/src/common/fontmanager.cpp | 83 ++ .../jooleem_0.1.4/src/common/fontmanager.h | 59 ++ .../jooleem_0.1.4/src/common/musicmanager.cpp | 183 +++++ .../jooleem_0.1.4/src/common/musicmanager.h | 72 ++ .../jooleem_0.1.4/src/common/soundmanager.cpp | 146 ++++ .../jooleem_0.1.4/src/common/soundmanager.h | 73 ++ .../src/common/surfacemanager.cpp | 182 +++++ .../jooleem_0.1.4/src/common/surfacemanager.h | 62 ++ .../jooleem_0.1.4/src/common/texteffect.cpp | 140 ++++ .../jooleem_0.1.4/src/common/texteffect.h | 71 ++ .../jooleem_0.1.4/src/common/trap.h | 67 ++ .../jooleem_0.1.4/src/engine/aboutstate.cpp | 291 +++++++ .../jooleem_0.1.4/src/engine/aboutstate.h | 58 ++ .../jooleem_0.1.4/src/engine/engine.cpp | 451 +++++++++++ .../jooleem_0.1.4/src/engine/engine.h | 111 +++ .../jooleem_0.1.4/src/engine/enginestate.h | 46 ++ .../jooleem_0.1.4/src/engine/gameonstate.cpp | 398 ++++++++++ .../jooleem_0.1.4/src/engine/gameonstate.h | 54 ++ .../src/engine/gameoverstate.cpp | 327 ++++++++ .../jooleem_0.1.4/src/engine/gameoverstate.h | 55 ++ .../src/engine/highscoresstate.cpp | 282 +++++++ .../src/engine/highscoresstate.h | 55 ++ .../jooleem_0.1.4/src/engine/introstate.cpp | 394 ++++++++++ .../jooleem_0.1.4/src/engine/introstate.h | 63 ++ .../jooleem_0.1.4/src/engine/pausedstate.cpp | 255 ++++++ .../jooleem_0.1.4/src/engine/pausedstate.h | 53 ++ .../jooleem_0.1.4/src/engine/quitstate.cpp | 214 +++++ .../jooleem_0.1.4/src/engine/quitstate.h | 54 ++ .../jooleem_0.1.4/src/game/board.cpp | 740 ++++++++++++++++++ .../jooleem_0.1.4/src/game/board.h | 153 ++++ .../jooleem_0.1.4/src/game/game.cpp | 344 ++++++++ .../application/jooleem_0.1.4/src/game/game.h | 101 +++ .../jooleem_0.1.4/src/game/highscores.cpp | 211 +++++ .../jooleem_0.1.4/src/game/highscores.h | 138 ++++ .../jooleem_0.1.4/src/game/selection.cpp | 215 +++++ .../jooleem_0.1.4/src/game/selection.h | 63 ++ .../application/jooleem_0.1.4/src/main.cpp | 113 +++ .../application/jooleem_0.1.4/src/resource.h | 17 + 78 files changed, 11591 insertions(+) create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/AppSettings.cfg create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.ico create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.png create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.rc create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.sln create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.vcproj create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/changelog.txt create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/gpl.txt create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/makefile create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/readme.txt create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/resource1.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/common.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/events.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/filenames.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/common/trap.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/enginestate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.h create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/main.cpp create mode 100644 alienblaster/project/jni/application/jooleem_0.1.4/src/resource.h diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/AppSettings.cfg b/alienblaster/project/jni/application/jooleem_0.1.4/AppSettings.cfg new file mode 100644 index 000000000..2fc2f5664 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/AppSettings.cfg @@ -0,0 +1,13 @@ +LibSdlVersion=1.2 +AppName="Jooleem" +AppFullName=net.sourceforge.jooleem +ScreenOrientation=h +AppDataDownloadUrl="http://sites.google.com/site/xpelyax/Home/jooleem_0.1.4_data.zip?attredirects=0&d=1|http://sitesproxy.goapk.com/site/xpelyax/Home/jooleem_0.1.4_data.zip" +SdlVideoResize=y +NeedDepthBuffer=n +MultiABI=n +AppVersionCode=01403 +AppVersionName="0.1.4.03" +CompiledLibraries="sdl_mixer sdl_image sdl_ttf" +AppCflags='-finline-functions -O2' +ReadmeText='^You may press "Home" now - the data will be downloaded in background' diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.ico b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.ico new file mode 100644 index 0000000000000000000000000000000000000000..5e4a98f9c6578618f0592290cf792dfea5ccac31 GIT binary patch literal 192086 zcmZQzU}O+tNJwA+gB4R47}OXU7(6_{T!xMi28MG}85kTKAbbrc28OU#3=9Sa5dI2P z28KEvMg|21D4&OcK`n@pK|lb)&tPF-I2Xr=Fu#C-!7P~(ZoY>D1H-+`j0p3M7#P$< zm=Na6FfjPJF`=0MEr|(XJ~IQuynH5v`8o^?Y{g7)^G`@KFsz%;gfL%>fuU?SlKFfL z4D&7`na{z%;PwE?d{zdAcQ2S2G#D5dKtXhX0Tf;k&o-z+{5TZI|Ns9p{{R13yUAiQncHWV5p2ErgUXU?2q1?dCn2blvhZz%YiUTy@1 z$N&HTnP<+N$qEXykdP2gA0HnsEiEk`At50?etv!detv#I1_lNp1_lNZ1_lOEC>CR2 zU=YWHLGmCBQV-H63^E5~9>`pf`L3?6+-YfPTp)Wv_JiC3iX(dYo!<6<{02&k_4V~^ zpl}9-0Vpg$;ljYcAk4tP017V&1_lO61_lOc1_lOM1_lOs1_lOD##LfqU{GdYU{GOT zU;yP{H3kL-5LRbkV8Dh!av*ge^&ov9{fbcYK<0wX2iXI%4`eSmegp*t`9baixew${ zkb6PyrgvCT!#+^juCK3W$<57W2c>Csb#-27ScB3dDD6r?!x$F6pzs2Pr6vOdgEj*L zgDwLDgFXWTgCPS0gAoG*gE0dGg9!rzgDC?8gBb$@gEgnlmgYqym z%t3CJftDYj^aV=WpzsEzK~Q=G`P~v4&h`up44^Oqg&8OeJsB7nd>9xQ{1_M*0vH$= zf*2SWf*BYXLKqkr!k{>ufq@|c3kHdUFi2e}R3At`$Q+P)AalK-aR;&wWG~2mSiFGT z1&R}pJ3;P6jt`K3K>h;d4FOOZ1En=kngfLcDd9$`T9ADpdkYH-IYDUxT1SG)Qc!vU zmD`{&2f1AbT8@Cq4p7>*W?*0d`4^NfLFp70*8b420)-hUT%#Bm7-AS07~)w(6|+Sg zlG>#L>t`t>PFt&#v2eRe!J5NhoWJ^r3KCY#Sg>6_aq1e0z?xY?HgWBo(z*o<3=D}N za~K#HVi_11K<0wX2iXIPQ&7D4GB7ZJ+yRPvkh?(c1H}g@kAU0_${(P73i1yq?}ExI zkUv5BT1Z7jg%6Y`K;Z!j7fQpHkbaOopl}D-3#~gr?f|6?kh?&6SBrsx0hFIX=?LTp zkY7OM2&g;&l@*{g2=X^5J%iFJC`{r&;l#wwlg@7v*eo61x^@kH)y&)f4f?NRjW?~fb6*rQ7VHJL3Ji9+(Bsyl;0zv=?&!9bS?$s z8oAgB8@1cce?ty)y`F3TEoa>N@4o#0|M){M|5x7o^uOc%kN=$?e*W+J`161FCkXEO z{Odn5?*0rB2dM$61?efj^YMS&!I%HtmfZ)N2{IemF738+Uu7b@H*m=r)H5(J3pFf&2-|-=KUBYDNQXu2TDI6_k+S6^7{M#wm0AZx4-)V4|{O9fBp#$^WHDN{$s;EUw-{Z zjt5X2fXo1y1u_$4cKFU`|1D?S{tvPf*$v9MD^7FD>o+nmFyt{XFl0i@D3H5BIYCg2g(beZ~@f~VxaJfiHYF`wUvkrY7AwdwoPwuFDEEI zp?yzK*n{F3RL&!ZJ;*H}H-X#+D&IkA2Gj-t|AOi^P`d&Y2cYmkjssCpxPj6xC=Fu-E&%~h`2{M+goTB9k;)uU*n{#K zsE!4tdrYsl7U;FqAxSRvI3E7QuiPLs5v2cRgPp~ox z)P4f_3**xO_9i_<5Z{9b>%PIUp?3UCmntDzv|xS z|J4sagZ&N)15kPdg*_;2KJZ5Nu&@u<^!R_t%@6-8?tc1Tb^kNi z&mg}yJpBqTdq80iDjz^)H7NW+=@u0BpmYohe^9yyh5f`IzyDAA`RD(nUuYNx+B+wb7~1uBC;aRAD9bx*$huX*(4f7OG}V7GzX2x?!!+zs-Ba_-6_ z3=9mZ(0&A{J^;0kK>ayTdm7Yd0M*IJFka}p@ z0~)gdKc&Ubx*z`!vEf<|7Ev7f!&&Q?(KimDL3KyL9_YfOLlS9 zTm}XPP~HaB#~}ZL`fZ@R4=MvdZ6Z(`5L6d~`um{p0)-p63<9+ui7kU*;SY*8w6Y&x z`1?utl(uQNo&N$0d;blO{^wnO_rK`+2e6+&eyh0m37pm-;g2Z$LFEFdd~)xyBQfGhk#=@OJaLE%J6_%nj$Htg-~ zd7xtppgta`y$`B;LG4{oKMU06gx9@t@l&SibYA)i3VTrBCuZM^|9O|*{V%xk9&7l6 z>RwRV1BC%7EU|K}fYT!G3ftl|F#QU`U*#sV)wuJZ_o$n&*^kr{2?3JF@=GF0aV_C%3VRAj)jiTgZg-&v2;-00`<2*{SQ!o&`vR9;Y^*b zE5AWuZ$9m4BeH zx14$FfAXHp(@)bi&GqV4$#v+W5gf6&W+P#F&@XF%y4gr`930gxC- z4pjb7qx?rs|Df;()dxw(Ui}C85#(3h?yG;5a+b|zU|;~10idz~R3?DZKB$a9se3`; z2ntUkf*nN(sQ(43he2&v=(sYdJ^`5xvO`NLb8($c=aoMo_t?(40}lI)({J#HKdk-p z=*xd%>t9e?22`Ga+WPP^=oeD`3vCO5u-2KCjD+y0>N0fiH|{{^ad zLE(rJuq1FmdO>C&#Q``U$j45O(&@Si4tr34KJm!Q|EVWlgWU*A|G5|6{m;Mh{(s@M z5C2PUd_c5+klLT1HaMs)4hj=+9q()P@9=^r}pzsH^X+dpUP#YK2{si^Gz~K*V|AX4ZptdonjRvcK zVc`#Izk&P&3jfrTum2|=ehD7K0Hr&fuB*Rg!rMV@Qc#)%g*~Xv2_6H2jZ2dd+*p;O zwTFbH{HqLfy03!!RVI^f{*OKI0^F~Hg@48wNcjT}|I3i@FTU~Nf9b7{|3UQ|sIPxs11s(4Fn2DPoETzK~% z)P^g(`u>0Mb>#5>^dHpT0JS?n?GI2o1eFKiJb*Oz2FnAWG6WQ!;5dMd{eZ?BKz#xz z4GMQq{J_KhGi1CJWCl3xL;GGJJ3#$yke#5h50D!`ZUK$6g3<;kjeych;kEZ*x5L68 z=+!syI1Q{H04h5`X&4*_ zpCRLGpfCpYuaGfF3=}`0c!IV0L3%-HA7mD2>;aU&K=BL;dr-d{Z`luRdxFvs$S>gV zKl%DU$dBOgKlBpp_uws0{_FNY=7{vVuCCty|33@m0gc@R-R>Knpl}Caw`C9hN9}$7 zAJjI6g#Sx$-2^HhLE#T7FG2Yhlzu?@7*+>>(pUN2PygX%5V#)x3T_91(j}-Ig4F|{ za07)OC>&vN018`Bc?1e)PINDL$giYJg-kRFg;aG&c9WZVIs_MhS@dv1RCUv%vQ zxZi?a_kzmTl;f|!?Q4*qL4F5?0chR_6eb|7-*p4j9>N}g6o~3fxFilTAB2r2T>lRm zM~~d|{6DB1j63)OTn2&4MUWdoc>t7NK;aKcKj>u;sEq+?YkC|`o|Cnyhq+M%F)3u?Q8(h;aF0ZLb}b`U%dJopSAhX$1eus8sP z6DX~M+A5%O12k?1D#Jlx3JP0L+6G}zSc5Q#4Z)B(1CUx!yn*zB%mA4MG7}WPAUiT><7(Pf$|?HAA<5Ds15+74^SRRKZWQAfXg6II|!*B2Im22 zUjWqp0EG!CO@hJ)6i%S<0)-p6EP~d_pfCl6EeM0+0vUtEKp3P3)XoI8qmaWMRJMW4 z2H62h_aHk#`45y2QS03gDD^Hl?Vo-FZ}))w2=Xh)&(V9I|Bu-H?0?vfr~gB?KKbvu zRPKZP22T42 zUx3S9aM`o#88|J1!UQzN4r&vE!b-dA%4MV=B%7(*f87sc9;l87&58SOc>F(T^Al(p z^b}GCf$HG{FTnFip!9(+4}iv0K>h^vaX@(Vi)m0$3;!6AR2VedN`4yD*LFF%~8~~L)ftw%y2c=D)wU7RT z=Cwg#rqg}x94HLQ#kyTrT|nl5u=C>k;Q4CMcsQsG0>w8d-a+vXN(Z2_5R@)JWg{q$ zg7N^Uy#UI)pgaun52!5!@*k)!2Kg6M4k5<@C`>^0AviC9<|iM00nbr_!VnaepfCkt zQ21iQAUO~QsRii)rFl?!18QS|;uRFXAUi;L4ixX;u!r__L2d%M4dg~p+6TEAREL4; zGLT>5&a0p~Dzc(LxBJ>EP}qaw z(__Vh|6Z#e{s+Y`D4s#_jZzOIwM9X3056A5qK*lH{0H(U$iL`u0IQQx^1{O};Pw$H z4TJInC|p6|iw%S1Kx#m0;o<)9GkCreWF{=^LE#Ri8oKf&&NL~TSgVci4JUr|nZA_5aAUi;L4m8gT zvKu_ka0N2Y0!ka8e2O*ggZjJsA@wfEuOL5z${tV}1eM32v=1tuL1`2eR-iBgg`G~< zwO<;2*Fa-(Bt?UE_tjF6e*NBS|3Uf5ZTbEG9xEUG_g?)FJSPXr1K@gi>l1MM3se?@ z+M=NJ0V{{#c>v3}5GW6T;sBKPK;ZyNi=c49j0Z^i1(!(=AnPVTVGG8OAam!);SH`| zA3*eg`q-ed9un@Kz~g@)J3!?<$WBoFBg*`D;5iHAv=3|V!_)r0=ioj+$gkkE4=Q^$ zL+V{n+6R?Ao+}^x2Za?V%s^oW3PatlYuO|PK4=3(_qD?yy{40I{C8RmS$7GFS5W+d z;u#d*p!OE1-32NGk?R3a9H7_5pgtLFTmqEFKxqv*4nXAqC`?e};S+eg6qX-A;R&uE z?nA;Clt0ihSk1jp;CX&nxP#Js>CKPeF>sI_AiF^E4vK$}8$fPBE_Xof22lF})Q$kv zWgx$R`~*s0pt=s8_P0FwkDm5HWe;eLs`KJ||4k-A)^_Q1Upquf_#3p|5(R}l2wTs* z{oirnT}U2ShM5OIWgjRHg7PBBU7)-Pawn*N0&+LV{UCpU{DT<>Z~ueJTu?ZG>H|=i zfWiipK0##?D6Jyr2T*u|;sPHAsR3bdnBV#cN%J>8fX81!W`pbirFoE@AiJ@L{cCtX z7gUyl`~qrUAcsAu%>&B+pmG2`?SuNLj*IU7x0-be-WD~Td=0dYhp1@K>ba5)3VTq0 z+HUTh{|*c8BJ#j;NId|`Yv4Sv5!N3-ltUnQg4_#oH^}|i;s8{}g7N_<-GRaZlny~* z0*VJvxc~|)P+CRK53slZg)J@&QUk)ExC7}0#U*Im17s%1Y>*uwyFhlr+L^F22a@hz zgU1m;^%tnz0hOhodJR0zunXGP1(iF{_C6>KK;;3bTmY31ptKJvFF;{tH}B4WP#A*3 zQmgw4XdNa|;ji6&Z7WC*Xq?Sv&h7v9^Y4K304Ps^))IsA7^t2HwS_?TgYqD#9D=n+ zL45*HJ^;BJj|08}o5@+N5P3Y1ro!#)O7=I?p_A6Djr%36?LL4F3U zuK}ffP*{NKMo`#*)BeJ{|Ly1B{STUxHJkulH_>%ef16~{6T##(7Jou zxp%*uwyFh6k z9QL3&6{L11EbKw;IP|awr7w^lL1iw;&mg~p!T=N&?#mzicUcPAe*jMVbMO2IwSi!D zfNuA-JH&*)@ys(^y4_d7>lr}nEv#nV`foG)_J2@b0+|cSTcA7!%4?wZD9C=0J3#IM zxeMezkUO!)!NHf{acWQ+gSSng{R2=~fG{X*Kw$(5E95)@3PVs>g7KC2;CW?G7=ti4 zoIzrjA#+xswme8ZB+TFa2bl#j6J$0x+)uv&&r^fTn-h@o2IMAC9tGu9P@csa_FJBS z$6jE4E%b5+R6c;h2ozSJas#xc-fSv#j)r}L^8DD8tVNUz28TmP+Q z-3I3+P@V$S#h^R}%4^_q2&qp1au=vh0_9KSIDnT$`(ONr)ybfA29AT{ufSuApu7O; zZ-U0HLGb`8mq6hK3O7*rf#L#$L1BsygVaFqTX1_4WCjSs!~N77@YoBAUA;8 z$>6X*2$|CYY-FX?bHXm;k=yqRi0;vV*b z;Ie27VvG*t4{#jpeGVQw0p)E_Is^F`lx?i$UPu;f!qf!i$G&^NO1tJlXpJ@_g_GBW}rL{@-rw7Kw$t1 z3s5|O>IRf}I0YHM0EHtAgTfUXhRK6yNSMC?&qsse6l5lPxP$Blwa-9q0k!WzZ8r3F z4k#~!##;P0J_h$YL1itd4+<&s?}PWFfy!iX*w4H3A6D*w!VI*2*Lc#6|DZW5P?+lW zTw6pa{B^so9R;ZcrGHS}4bl(FL*Q~~=I#GBbM9c)1IQcfEgGNAGk9QK!x=ho;{A4=T?<2H62h?;txtc7xmi zO7kE$h3$mQrGWcZ(7r7w9f8slDC|Lg1En)iTLYkRq&o?kUkIwpMp!NeO-GkB&db$U-bx`VCaG8GxynhoEHlQ#9 zg%zmW0EHbW3?X5E?Z0l<)fc3OKS)2w9FTb+b3x{V?7vyuTNew!!$o3-FpK zkUDVrvLCcY;RV<%^e{&bcSLyu8OsE@6;$TH)BVZ^;Qh#;G6yuS32*Db!hY86|DZ4d zg$<~j0EHE(+yI3g2vZvVATvPbfy{;11>iQ(ZAjk?ln>_L{SRuFg33ft`T)lPc+LPa zW(`V5AU}c96*wL?KLO9?+7y3dk?uzU|_B;QjT8w$2@J-w0co4+=9FrbhUK%mS5X@VWq0AEU(qsP6%4 z3xLuGD4l@Z4elp{>Sa860hI5-ZKQ2az+nT4ho}ERVFu0B3pnAb`6{LOSx9;J8|Midl2X1)uKM1s*Wz*yTAzMKB$^TH$d=4lc zwmtbD4l0{=JpCU5!aJY-j|Agq|0ALK1C&QlFi3nSDBd7?KxrLp2Gl%|*&$n={14vz z_&jC?%Zjjf2Pk13_chp#IvXC;vl0Yg<6`np>a#4+G(CPydI5@b;(wBS3h^v;PtJFeuJo z7*xM(efmEXgh72lP?@*s2{_zA@gBJ0@qbX*gWTe~=FxwU+dyuFr1|^cF?UdY2Kfc# zCs3LPr87`^1Nj-0{y^yvlpaB00-Ena4=WHK6!s8&^&+A0*X_P`8l)Da4D@!-GD$_M{_S3mskx8@-@4g%Ia`X9Ld(f^%0nOw zipR}Qz-EEW41t;-v;kr#$Zk;BgWLjg6Uc2KHzJoeps)w|1s3k0{YRj_EhOx3K-&2I z*TLibxWWq*o?zT{^(dk6*Xg>p53IKP8eTI&c7fsmv?dPJE&}znL2&>o4?%7O^+iDG z1(a@_7T*2ux%B>j?`8M@`>c5I-*@GM|Ng5U{tsCF@PFW%hyR1tKKviN?$Q6?^^g7s zZ+P@SWFrWJ;^6WBuuYHuhi!)7@GVdN6N6#uL3%?$Wg93?H$uz?*%7qv5!lYawGaOX zfYQOLhhR5>+y-)^7ib)L!Ci1aAC#X#eu1TVkRL&Q1^F4&9sz{`C@k<{Sa|AoU)@YF z{JXC%gsI18CQJ_0HU;$$K;smkauAd*KyC!Z1IW$xb8r9mTy*ch*OGgX@Lzuazwhz~ z|NT}z_#d$9;s3zZ5B~?PdH6qg?IQ?Y_vnAf`p5r6L3qRC|6v;;IDFIN|KXdSK=9@# z|HH9im^>)Xp!&i#K+FP}83KyqwV<$n1hx}oH^>eCDmU6G;qVQQ{)caP{6Bmn1V?Oq{2v>J$%EByc=SIEgx5pN0-L$^ z5!jAkP@IGE-YSS2KyL9{{@}kaD1R=w4|Xfa&7KSI{s+x}gZu*W6DZt4Wj*LTD3G6t z2^)|aSa|C6Tm_vWfj0_tIxm^P)Prb{exh*iHSiu~P@V+!z0D@y`0qCN&VR23cmI1Y zy!+p0@xA}POYZ&mTYCS$|FZl41D4&|3S;|{|{dN z;D5-92meD>KKLKH>f!&;)erxNt$z4Fe9fc(;cFlLj{xCykN!ujd-OkY-Q)j}>mfL5 z{p0`GFiak-7OD?q2FNUsnIN-47-Uz-%7He7UVoLTJ|07mE z{2#gI;s40B5C2E4ee^$S9Rx?Od-NX#uYdGE8idirVd_D8L1uu>TK(`p$ZVKBVJjd0 z4_om7>;{lqKyCuL4dh0UTS0CHxgF#OkY7wD+#uKJ>mU6`#>jFYHb@T` zL(Ku18M*2q*p3KLe1kA3?w3Q{0&-LElKWscg4_ynGsx{AKY;w=JmVHc;jhzur5_Zw z#9*DyOYk{hLScmL0_$1pjNT96(v2AQ!MVrKNJhhRHEc7ZU+Zjc)ymfZ)tDGZc07DL<$a&yoEgg-!j zGMj+EosS+CAU-@DcaydkK&Klr4h_-|GKW~~G3)mK@J08q;)uof|3@sn|37l+{r^$R z?*EToe*b^WiU`ThT3HxY1mRJ$f^gnIwqyK5^AUJ*9qyJ#M{?Y$*Y#1gFRS(je zy7m#otThk+gUkluWRQKU9{vZ}O{#k>LG$T7gvSPu!%n;BGU%Kj>sUjOKS781^0|M)*LMwZK5kE9Qze=WpJ zklE>LD083NOycTcSh(qQU42GWU}I6F4_ylcGK-k-4_$cof9|?R)WPc?{m)(h_yqI>_VwmluzICSAXg6SU= zRv@g`bFB+on35u9)OAZ4WEKqLivyoIcm6l*d^W7H$87vQ8*2yiS~bbD`vg3N|tP*`Kb z?z3+HpL+Dwu*CSrfMDSQrhBe~&L+kZisTDv)n8%L>AH3TY<@TXK3VDJ$N%S^d^4`*T=yYB^VqZ_2GqAL}?n~%&T?3zS3$hbi`Ui=bPrUJe+R<14m!5q)Eb!DL zul|F^6+wQ(hCyKg!a7}7f9SSf0^Q9*enKapQ@iiFFUT$!#^xT7nA7xI|CgV8`+wb~ zcS9O4JNNd#!?c@3r2VV^bbGFX&O#>;f)q;s|Iet~b!`qT{6RD*ys=@=*|-0%y72D* zw(B2;Bwl&`?SDe!4Iux6uuk{2nG6j7i9X+%l31w!|DQ>x>*`gIy&#M&>|tWIQ*QoW zdEwpveYZaiDGW+CgvQ!Heg|Ql?rSG02~TqM>U3Xw46+}DVd0I92F(XgI`s1Y(feQi zAAc~oG02V6j=lPC(2IYJ6Xa(Q*6F%-m)!89hCbcytIt910AXxlk1PhN6As<|^8doq zZ-Wx=zw`OO{WQYkn;^eJ@k45aAth#LO?k2*KnrX=jBr5DsU(C)qhFN?tLBQQq+%HN>6?bw6Q z{~v$&IUxAZz0d!>=iDY()_~Fu$WJh=(|zrZ%EVjj)Cxapn4{i#ofmZ88O)6!8su(b zu+`)n|1;M<{D11vm;Z0R{-!Ag)jw&gAN~i~NsQY-YCwL0Q@cjmn1A*Z*hI?YxnK?skxW$i+5OZvF@LB|!5FpmhqM^otEg zExG?cbkRMqT2MTaYad7-y8Ct8uOu+k{~z!>mx+xo&AzMJI^9=L?s)|H3FNoIj6rTh z#yVYBPH1&s0o^M?tk(yPI{W$eIY8s!$o_$`2U{G#+=Wbo&cIWdxNT6?v*bjscF$#5 zovtfuk^Kf^4|F`h+ySS%uKv^Qy1HCz0(IuD$O$i6>Cx-HYOd3DZJTcQHSpafa6fnB z?`zT`j*#t!vj6CGU)!kLa~*V#6s>|_P?)RTeZy3z``QNG?yK-QHE0-s&#R+Fc!SJD zwgbl2>ALn+yZg#Iy`HN?t<4`40Z1iB==Yx&(C)t64mx96r~4}S{x(>+pwpo6BL$=D zN9KdhMAhxSdJ%Niky6JQekyrqNE-v1W7h7v+@{lg?UGLSwRgzjMHP0}wYNH5S1*CW zoZ54A%^bDfzQ8TiI<-sH9B2aU+Z>Vd!*HU zWuI>6wL-P-3yL_b85JH4fzc2cz!3QV|Ns9#3=Hxh8p4EgK=*DlFn}d~KwQWV;v9gm z8UO$P{|~}sV6gxHAF70bf&c&i4={1&|No)N85kJ<|A&|elKlT4L_%;q+!zK1`#%sd z5GfBgl7WGrR5r3X$ZTZ0kllddHe@$H067JO+5i7XX2aDW`;i&RkI4RIMD{NV8_7M$ z;ZTp{X5=tIVIzeJa#-PH!=r_Pfqyu$Neu^L!WLJ&Ad4fVACx#nq$RX8fGf=)rz?2G zAm<}~r2J)%l<(^QBP<5xO;9=oVGtXd*+BUemI;|b;!w-jL2RgH;Cu}Y6?>34)R!RR zp(z?{3^WITwL)D4EjYj$Aj-j69&8iHq(9)o0mQ37D99X;c`7O@e0q9%-1heN9H8(6-5UzB zpCV6CSu-de)6&vdp>E{i=jRs$`GJ9f0d%(o$p4_k3%Y|AboVRTHzFff3|HcS{87(n+m!!U>s5(mkH)PdB4?$HK~xq{3AnFqS_8Wg57TwGj|JUl$$ z`)x%crq|Bcth{D_h(>W2xMSljp0_c$rG}OtP^p{Y!~$? z=oNK?VvmAekeGm3cpayTMFA5lM;rqKLofpaLl6T414zFw0|Nu-%w;bI1_qG%Abac> z7#KkJwS(*jr8SUyK<)yiFHl$sgWR2)n+q!DsXE^RN~fT3;pgWEt&IkiAD}V;luqFH zxkK+W2c->=dqH6l01gLGSTHceu#3uN3tC3BNJn-pQ_Nm>T(NZDUDcW+FVyQ#e$Z?> z_f4bi{7;Rxb6~99cJ3!g3?!#gefWh^`QCeSIcrWxhj%U)G!JiM7nRFpU|@)6U||iNZ&3cDw5$T@2Zgt~x;ifd0|O`zfzk`e z9*}*Yv;s=sHqiV6N+TdQg4`RVL?N*Z(8;zWyJ3=*|DwLvO)2?$De6k^A0&<$O22{_niv<$v>;kN#_S zUj47yc96U|@)W;z($Cf!0}rs&7zU1-TDYrh(EF$laj) z2PzjuKy?SXcM^l@0?_^Epz@Z1fdN$CfYPZN=!zO>c?!Dk6_l<)?f`{LC<6ln$bHdl z5{kt#;T>y~%Xi(->b&t^Z^DEB_6r~VkJtk`L-);p(A^E7I}H22{r(TSyBTzUHs~I0 zWDF7m%YFO(A9VL&@r{rFQ%<}An_;)`5!g(v&g=h`%XZz63Ts`*CaO@*z`y`HX9kq6 zq8S(%K<)v#3*duHZ3s|3Lu}ClN;g=-22}Qe;=l}A z&VtHIP#FL!6CxNG7@}Bs#qwpMy4NUI9ek?OclW>f>}UV|H$DBId+9y+K2p$KrafPN z{s-OZ3%cJFM1$}71>b%B>p$qOYZ!*#yZrgrf6!gDAhn>ofjd9`1e*mqtKNU(lmBM3 zpZ(YEz58Fe;?Ogxu#R;syuu|63=9bj3=E($3lv|0(6SFXErIF|co>1o4bZ*f#Do#3 zj9;~C6&ti(5@%pwfTbHyJ_dyiD80hM29%dT@f0KOSvXUz=FlUpuG{~u=05!&vi;eA z&|NDH&%XT!r4`WKm!LZ?+uwcv4+|%FIp@iLklkvPdmo9r<;{ksB~ZQtg%KzY zL1iK=j6mfQD2zbmHz*y6fy!=BUL%x-Ky?)8u5bnh2GG4Ypz;P(4uk3fP(2DtqoA}3 zDr-RHuRphvNxnkH!aZ8uxBi<-YbOzy2UFD7?Ny@*nK}XwV(It>j%28 z%x}Y!|HjiE{0F&3A${IHE+vyvXc-PF4?*sQK9OX1ghTzL3!r?|NqSR z!U%NNJgD4)mdBua3KYhmJPQhQP}%{-0mvR7VaL=4^_s(vbtgRh@38Oz_*(54xufrQ<1U$y4YQ(^n07HGQw6h5H( z4di}M*$FC(Ky6h}+ZB`!ghA;7ls*WBkG;J;XdRLW0|Nu7oJS8IP~GV+8`(KUqv`A? z!zqvc2W))uKkxEe@SR>|cRu|G-HirvFUaj6KQzDm4!`>ylm;}03*jBZnGgPh&SuZM`0hXGP8rbMJ|MS&%4A6TAwGYB@)9h6O@Zb!kQgZa zfZ71y@cHx;T(0BFUm!bS;RA9@{$+@}KyEaj1uBzn{8q?XGLM0Q0n}y#g$=080Oc)E z86s+BWyMPL1J55C6yRe-6FpY7gWZ9 z${+Ob0mT{UzLc!afBxTc)`S0=o!5UWr7dh@U|;~{DOlKugX-#u6DNZD9YpWr z0JVWYVI(NX0P25oC}u57((bwa$qbaIc0c+ATXE;p z|LXf+{)6t*1l41p`m5#DH*mQDx?3DnxA%NPjEUVr=F`10HTdQkp){N;c3gD>EF2|;!jU;p?YbaxWSOip6h5GPgFyE?6hj`Sl;97Nn>B-H-nuGeBm6%&dR%6>JB{E>O7) zy1x!o_JHCF6h4{fAosX{+zN6t=*)7XsSp2aw_kg!Qo0FL&oF}emT(V~!2qo#*X+1* z#9;Dc@IBLzI|e{^X+Z8Z$vE>Ce2*2V&H&vr2I@P2${_U>GEZoUcH7THpTo4>ALEmo%ttRsRHX&nT!(0jf7a zc7xhMAh&?x40P8J=-w4j_<-)80J$A>j<~^;NB?y?FC7k9N%-C?LP4g}eXT{O_wIkY z`S<>V?gfZF0J;nO1^Avu(ETtOXI_Kv*#^Z|!4=4TkEORi{x81=xvR4lsT~CJSL^F< z;QkaSEp&bS0ZtoTpML%a)!#jzL46Mh28(_C`5&YPk*~gk@7`{F_Vqs~?bJN}@*i|R zYvtX~|3P^RbU$C=)erwcbq1*H0o?}#awF)@4$$2YAh(0cYmi^Gd+z?%?Ys&dEGHBS z*yS}ku32bzUHfc4^C9?5|48UL{qYB1{7*Upy0-NqvjXizaCCeL3V=E&ZYNYw}8q;P~HN$5#&~on?Y^|-5mqEPXTlv z4yeq~ZojlqzWzQ3o}j=grPFmSP^bIGKdV`H!FS1qfX?sU@f3V#L(GBa|Kkrs!YK9l ztN$6N-u%xx`{sY{g}30k15($2_z#L#P#9G|`1BtX*Pwf%LH+}!0Z^R=Doa518Ypdm z(g-pJiGk!mY8qdB{on8$lBXc|NJH{2$n5gl(ED?*z5icu`Tc)Lx$_2mk6+4(SN}nG z-hlEJ=$;kO{Rg1Cgg|})-8W)6^X`A0o?D>%Pe9`!Si=FEAZU+?R@apShLa)pjDhaW z2-@=aKj{7*(7g(vdvrkej)2NLQ2c<>5Gb#M@;s;<0@WX&v<@mSL1i^4jzQ@Nl-EFI z2B^&f3MWun0+mVNvis#XaM=P%TObS)1IdBZfYgHOK~UI$!Wm>1sQd?oKd8P0x29Ns>eWgi@7a(@ZVt4ga6uH*Y>DP{73Y9U%jpy z9$KB(ep}AE55DIGbcY1UJkUKtptKpa=Nb6!7Eru^;s;befYLH3O@rbu_tLxnpfm&z zqdOnL?GsRWRQ2%lf6%?wAisjj5l|Zjl%7E0fQ&(6AUTj4P`U%@0fjFpY(VJ-R9}JW zbI_frAiF?e1F{=Zr@sN;eF$g3sy3A_Uz5gJ;>U3NK zjSFK-E*N6komZEF!qtAkJ@CEZpgULsK?RMhsyVvc!uCCd3<+15>$USPH`+`8`fYT7@9thC=8#_Vw zojix6Ay8d*6cR?DG!07IpfCdEGf;T|id&FBK>h*6H#ooD{RFPtKy@?7-=I7LN*~A= zBnHADHJ~~Qlt)2rKyW>N^CR@$==b3A4pyIo(l4mZ3JM!=nSAIaxNiZvj|Eh>fYJ`= z9w%7Z0r?GdHx;O#t=VzqkyhJnP@e-My&wx{bzV=?>%0Bma>gC-y{@2px4b}iXRLb& zzOMz8cR_g=R1SgcjXCfFTvmhH7@+bn4SKIFD2za99@MTbfZkaP3nx%N669A07AWn2@)oFm2ZfE};(Oq`9YKE9>Atei zen0LrPPDr&D{FOKy=ycXq6c&z4(MJe(7h(0yXkyDcdvl%zS;cvKPat&+C-o*0@Y`r zFao&?(Dfx-w@=Y!k{&TFS2eP@tAKp5mFP+5_8334AX$iE+TlgihDh82yP4{)6tev6^uU zobDXvgYKZe`yZ6gKxq<`Z++K21mE2QDvLn(SApCCiYss!LHlQkM_+>b_^|v29t%11 z_CILM0pvfBKXWg>{hxag;%`v8K*ykT0>U7*AUzDvH?`jfcyZ;4^E39ca?+hO`UZM>}QbQb-S;D=FiZBh5>ZO zhfe3!Df$!d{RiC#0lMQBbmu4NjvD&~pfG~ob+qyUyiEj7NASD`YFk6@NCUN1;}5+6 zw_QQ;3QGH+vH?`TfyxO`yo1UNP?`c^kiW5EkQ@ku)PnS+pFzE28Dusn&BQ^=Vo>~m z+8*#cwFPp=DI{zj{Rh=ops;aXeE&Z}xT&T$dsjvP?FvYc`IKgh43 z`$0f{*Xg{v2~brsR2pFGy{Xg~O8w5T9 zy8jzA9}Q_+fz*Tag3JJ!1uE-6W`pbiw~aw{_>QOlgSUb135DDp2MQaI8@*P6?n!(A zz8f2oukL{BXVCpMpgUARe%0^0{$H>E&VTK$E5|`$fgV0u^;dXwIZa$PeR5=A>$IDatx#vgh6Et$PAEKkZ?iVqZ$Hj-@y6~ zpnAk>%|mdW0=08MX&;maK=)dK?uP>16$QGl2vpXB?v(-g85%y9u;|P}P}qRn1WMzeut6?!Ky|Y9>^opTf&2!#{{`e%c=&W)xo3=J z?-D3{bUUv-fQ1i8Jt)nA^qWq(0X7d5Mz(Wq{|DD;ixBtId9Hl;-)r@Q|De1Ex*rha zMo>J0+GL@i{>YAJ|3P^U> zB_O|oF(iN8CpLUQdJOs?_cwve1Kn*0x;qOLMxb;GO0OWhLGc4>AA#~YD8GZ^59C%* zdllSH0`+S_cO8P-OW->bpMl33K;to>vIC5f?*|3n5en+#LGHH%g$W3Q!)5!^|FCcY zr5RAU2f7~=WG5)ifXm?(55V^dg52h?@Gfdy1-%;)6z?Fvf&2)^{dfNBbXT*!|itI-)8x%g>mv5=m-{M0rpY^&gaO-woJC7}V zKzc!84GMEmUNfH#x~K9MxDK$L3(9YhJIh@b-}~>m{QiHRRS*7y?p^d>_XvCsV<2d3 zWaE?npt~_cHb4F!3c7m`eDB~B=pB&Hz;|+j?|}r}1qn)L+n+(?K7g z!{Cii{)6rs1mE$v?h*LTL*G>o{(CHkK8|E_C?_4;w2({0cT%WF6OgUWtTy=FBF6i#>kgW|~* zbYB|iF0vI5{`(=_6BxYiA<7+rpu7D*cl?3w`y+HOAV>{JEl3ae9>xuj`vyUG0mAM9 z1la|;1JG;P{r|3u?}6O{s-s|O26XQtC~QD&98f%i;u|aOzx!XO`|3Vy-5o+5Q9$VwQ~K5_d(+z;5r_s zIlb5ZgW3$B{06#r&u->z@O^JSi|+pSS#l40*WUgA0V^K-4+P!wwi-K+;+l(e&{|~yqjnMrix;@wbgZf|EJy${N^Dx2&B%s@M)dkc>((57a zPApJ-fbPQs-6iL<;O>9lMRyT*u`NTohi%mZ_#JGZ`|3bIiz(miXSd-ss;SOdAmbKaf*7L#xO*8`om2g2CO8zeDZke|Wz z`(@A?Ay9B&V2$nzIy#+KUxUUEaitw}anRX#e)A#sr3Eayi*i?52=tz`@Kum|(m?l^ zf$vB|x*v_uy=dS&(bhf!->C+=4-I4n{4O-4d(eVF_v3-?$phU%H~;Q`keeJyxqGYc zHfa6uOVIf@7y$zn0PVj9l}`qf9^%bkpfCdMF$SII>o@Ptf6(0*0rT(v4_b8Ze=z8t zswMaShl1|XT7Lh3#EJ+1LHCM9t$Of33Utra>WBZM*F5|mv*ywNn6;1o$F4(Q_&r%j zVxYUSK{6*efl;?Zg9l9MbYH0h&6(=;;J$N97n&}?cU~>N_djeQ1cUC13SSJl z(+hmp)$;rQqha@4f$pC|zT;}`qyO=+`>NJG`k#PyzZHlNyZ;KL4t6gV_QNg_y5NtW6(WR%aHD&S_Qd>3Up5t=*}qQ`=uYYK!xcTKH<+%=WB3UsH{ga7b*rl9u0?wW$R1>`nR7#a8DKUW;&SKY3wAGL_M zOAXX_)#=VNKV>Bzyb5xEQ|ju6|3PPerLTSX zKYi^Z2wwN-e+CSL?jAzIaB#a`}xk=-Pitm&%O=0PiXC<|2gY$V2~U#hN*+!|MU2N z?gk?8`p5rsKp3VUL}N1-B#wl0L2A}L`VYFB0~Dv2`Rdw#z1|!DLG_VN_mvzx*$PEU zvGtO;R>zempmc}LOzp0#{{!aV`42kp9)wFaKmI=$G01Ho3_4d36sOqy0`jAF*OkXw zT_-_%Oi;oBA4jL_TD`&KNB^;vYoPG)nS1Ad?e=H?>vlfy|AWdMo$eb~$i44IyYq6s?xg#_(aRx_UHU!O{uge1{D11v z*Wf!U3Yt(CfebR~N0m2ZfJe-*s>~wB!1R{~NEo|G)n7y8*=@H*CND z;eW%NG z{_@-Zm!E(AfASG>R{W#)KmR{?_v8P)x1?c^9*|zpne!mCKxTr>o^kBe|AgiD|AXQN zWH-nS$ms@DW`f2eK=G>Hc^$N$4XeMXDX3L{Oh~u)=6bz}_y2?YY29e`XZN-L%57Kv zt9M@gAH3l1|KiP$!Q~Oie;~iT`}X_)kKcd)fB*gW|JPp-{N?B0|Hv374pIYB3(^D9 z`|$nG|J!eT{9m-`@qf@g=%6rBX}f~i&Ih>()Q6mK@4rs(&DFHNe+fN&LG$(6Jy&~l zdT;-Nw6Rg!N1!+al}W1YSN^MYT=@^WKhR~yZSXkAgo7{tAG-S)eD3}ECtv?xe)jGE zwHM$2gYpXqgV-Q3kR0f2e2`jDdk=KKH|Q=lkXdRSSO0^|2H63!3mJpb5V&pJbL*FG z*VPWt+!ea}>BZOXz8b4L;qGlv7=i0f=-3&GdwZ_^2bGtwJOBzWwf3vvJHJ79;n+{T z^&jMKWDF7m$$`ezL25yIKxqYJ2B>@iwegVcfV2Bl5axmE3;nLkZn{0!7U^_feW=}Y{Wr)zpmYUV z;|NM)pgB2w^8jGE-s|9Y1V|4=@BROvHMTmP*BJj;q>Q-B%K|J1&>#bX}{^?Y>$Anp;7}y4}}n zbh@ro=yYBw*6O;Fpxtp9wEvzIYev=5Aq4(|&tZfd_Xs(LksW;WBbZ=ds0W=z2|a_A zAIydv^T-TlLwC1=*x-X285kHqo2H>BK7tR%ft{fV>hyeo`UjZ}+LQ(pCx#8ui)<#c zUH_o&sRym*hS~*k8wi8AAR6XQkQ$g?WH*D@F!MnN``}{3+zfILG8+;+3=AN@5W|KY z-3d|;V}mMRda{XeC$bu3|Keif3O8I~jvOz@Y*3uR;tqQLDI-V>g$)TTNScH=lpU-F z;y6gUg*ZqaEDmvmJ(vw5K&KId(hS&8$eFtT!DpK?gR=qT;9-6!8>HDD$_8nM<(>aO zz^5I9&4Hdt%D}(?I=}>U=o~0%4#YX6pfegk=Y52RhBAZB90i?I2s%#`bY>w48yg#Q z`S|#NF^CPqAaM{@QBh$Bsb^qdUo=7X;IkTK|d zEq?|E<`5=UjxZ)xj&K+TC3OY{h5!Zz2GChnpgqB$^;jSbVuQ{u1D$gTG8YsspmTUY zXE=fSk|6t~Kxe3`sHpIP!UA;0Ahp5)+&xZxs3Gy>2Zb0X4f#MM4 zUyxft?gyRE2RchJkcpi)kaLIH^>)|CT;O< z>8SpdV(tZ#`SiVNm{@s|q31G!&e8*g4e0z&&>3!^^O`{60ZKO@`$1t33JXyFk^rR( zPV)6 zl0COo>ra0I^t6o%T=(+7%Ze9ZIrBNs{~JuW`(L&G zy>y^4CeZnhpfdzPX%3VoKQB9qj+?rRLrN30b^#U+pfmwGi^3h+6b7YDP+9=R8K^E11D(?a zsxv_T!-qj-9H>l1I>QW<&q00%NC)dm|CtxPpO!0W@C-I!h812B0zm6b7L52}-B1vm`<3Km^p@z?T<5=^k|U z7AW6<&h=(s0H5atN=u+J7nH|9X&#iOzpz~K6;Acld z&btAf9ohK-a&{!he;~hu&SwLiO$Iv44ve8^B7)>VYG7xQfzHWke)au7_{@&y-@xZ; zg3hD>of+k@!xa@U;a({`?bp7jel_Y>qkP@Mxh&kj^hfzmFhJdgm@51_P- zEB-Hnau&;En1iZiC80 z0nnLa`1}t#>koQ99q8;oP}>X^|KRj5lQ3nbR@;>yR`Z^K_t}E>rI+6N_`mGVC-9j~ zp!fluAJY61a_(CD+aLcyXUBs41o9i`Tsn|{L4JpwYY1Y4#6WVOvqeE_L3%)XL1$uu z!V=_vklCPc2A#10I!6d(FKFMK^}HwlHQTRzmyPb3#lXM-O8=mI3Mvah?GaG?gX(Ju z(3xxa;vW<)pt>H^rek1WfR+28`b39;g~e1MbIDw-j;sG17Cre7+V2Y4gZ>_T1{2Kx zpg01#6~+G_K;;?e+|*y-b5lWQ6oUK=I?oY=L2Qs1O8kHP`5&MEL1zMj&gcNS0kjX* ze$nIqTAf$_Dx@z2omB{GCxPM~RA0f$Kv6>ZALM^f9)P9+L1-BOD*qJ}Gne;kci;Nw zwDbx1tcM)%9&^Z9Dxfp~Ipg2QG|Ddxi@uYuHc>t;dKT$P*{WP1o|cpff2zc@ggahhM;FQGxO- z$nBu=4^+2<`~)i7Kb&toIddWCEOe0j;b#bg{6)y`=<*u12VAwfZhy3% z_xOM8f#={e6F}!mfcAug&aVKSu>d-Y0+bg)=bnJh&jHncpfiQwdEgzW{`&zrKlsZp z$l2WAAZG}J(mW{Mk^K%j0}WL6fzGu8r6W*&0-p=_;PZcw9iX#hKw%CFdzk-0`};wA z{XzRft>-@euhn(qgG$LJP&r8US%Sth-|=g7T)AL63$lkEwyznK)c%USdf9Uon|3PlnZohoi zb>}~B^f)D!uhn^FqTZxO|Gic}0-yB)+Pe-415h}F&Qt=OkpK#RP#FZO13_oDfZ_*q zZYb!iBv8CT!T{8c`3`Q+f#Mc?2H+=1nFuQD!TtuH(+UYEP`U?|9pJc!`W;lRfX+(< zmHovxKY-700_AhW6g7Ol`@1SxIbe0k*?}OqVWG5*9f#Lv^_CeF z*+TX^=u99`dIQ-B@;fN)gU*Zroy!PHpE1z$*g*ThLFZr?Pk-`XtL^eG7h!xGM(}Czh>u^9iY9k*nN!<)$Y1st=)6utMy#S8GNAq@u21QgDoyaqbg0$dkB&%6SiQ3Ps}fZPdkFQ_~OxgX>YP`ef6FHpGvP7hBYVFB_p zsGIeFridRNsKgJkU8?pfU(_P7lZ}AUA=|Lx7x@_5_@6 zLFX=j_RL$)x&L3M`_^amj_aUyA;Pm*Sel(zdyS?&`42j81Qh=u{h)IKKxYPoZ3msT z^Xxz9JPJ@b0LllTasYHT8t5ELa6W*ZuLmj%K<);$(?RtjC=G+c0OYsoN1y+L+A<)& zg7HI8KK~3p>k^~}RDMAG4n5!W#)to)^KrrT-9^xOdXRG}LG51986%K<{~UbACMe&7 z+zN6tc<=tI2VlQ|{G`=+trLrv;X z;~aD*-1QIOI~hRv3Uu}r$ZSwv1C_g=bO-V~$PJ(}FLDng--m8{3O<(!bcPJ*3>T0e zKxY=1PQU+OyW{FrkRRb5Mq_~X0c&?&`2#xN6Lc02=&UQy8E~L*1eK+rJOw^y0d%$r z(pi)scYw-ZP+0^zhYH*-y7=xtsGI`V3(#}&Kw~+eGy$r^K}0iC&MIrH{^`vrIYgUKEEgw zbOz3@Xa7NELEM2C;B#C+?nyZgIv4oOf6&>|+2=rKaJ~BvI+GJrW`Xi9C_RA622frG zVNf{0^}S((3x4F_yUCk=$tW-KR{=1g32#Y zcz`e{Oh6dK24S$=rFY6{##7D^&fOb zgB|o-Bv?KGm4zVlL2Uw%eIR>5VGnW#sQd+;c?GJAK=m=GOh`KkDW^c^d4n)09zo|8 zg6hhgi!gt_`wwPcc=taWgwMbI4^j)l5Pw6?egu{C;PcoHz67^HK=B^2^BMT;P*A=M z-1r!Jj^D%opgaq5Gw3`HkRPmO-v*!41M-`0=an;{{n}tpBM};%7mai}ue~*#boW2# z>;(&?GsZyq0DMl}D##gZpz;u8U-0H9VEaM!BB*^F4LVy4njc`{0CG2|tOB)BLH+^t z8$sy;6tBn_BnFZLsR5}4=}A2fIYSF{Rurh+4XSfMWgRTPhe6L1^WXFs+)jm`@3`## zf9FN_{@c&H13qgHbUq8nPll60=V)AeuHSJLG$w}Rdj6X51=!W ztY+N)4?3>{d=A|r$T@VNbDz9dKLVc#2&!X1c>&Zm0-bLLI?EMQ2ZPQj0;L5|o=7+X z@dGIBg32v0J_#x(Kp1+4+9}W(Vo-bndUp4*SKza>L1uu=0;MmI*|2gRbS@Ss-a%~~ zP+1R3n_ep){C8jW;6FIs&%gU0bha1h95s+%Kxck|{HD`!<%d?!4ba#as{cE#yX*FV z&P})hKKlry9nt^am&?tsq%0+|as2L~Jm(6g^V=kG$=hfn^4>RwR$3)KGrxfOJV zD#+civ%x@V0)#<%7}Rz`!AD>H2gmb~m;b?jKJ*fNMlMJ{D6ND2z55y14$#?%AUgv# zJp#u&=zK|#n_%ZULGt{a|5h_^fzN{h`2~EwO7BhZnpK^SOQ3OV6#wgXUhxB;!`FNL zzkbhk@Hrr+lW+b9ozVg=3+95(+JT*I^#FYS7^s{9K0J_>J2(`Xzj!Qu=Bk@@d7$~3*=T%dH|J= zpfmMAXP1G}1Sl>+?Q~EZ5)>vN3}S=CKyn~8AhjSpAibb7nm}fO+8wa;4zde$o|pHk zhv2#iRMvsoI8LDRQRdzG4=V3KZU*IfkRL#Pfvicr0XZuVi~seyFZ+V(NASLC=o(+p zIVa$=;HE;-0q9&p(3wx5^aUytLE#OmXF%sefzlwTuMBD<1cA=V1)ZC;^~rxw83pn~ z#ExhGL3e?G`~^C%4CF@?3`#E`yzAM2P`M7$1JWA`KbHzpw}b2e#W|>chnMr9vTniM z|DgB*#XG3%2E{w*Tp^GjAbtn!Bf#x{t*$E`pmn`^eUSKv>*>ArA7qZ{WXM@>ptCt` z=0eU@0;L5|nE?eqG7DrT=v*t%`BtF34zkl_$-V!M3!!I5&bb4wvq64`$2UWU{HH;{Luh&i zumA77@&h!sg_8L}moN5QGS=?C`c5CT_XVaNjRu`J1Uh>Nbbb`5P6dU7hb?@&>2yipZpI;#vrjx zkN<~()Pcfm!{h%U>mPy50GSoI=HY*TP+7C$!GG^%kn^G(=imJgYO90X0&)|`ZJ@Fa zk>3$<2nq|(+H#%F%dfS%&V%N2QG&p@=ZuJM_tlHw{Um7q2I&Q1P?&=15m0>sI-AO7 z#;yOJ3-12+UVQJr&yxH9{gyrW?+-c~YSn}PL7=mW);#QHSJ{Jn42Xrn}$eM>>vjSH^%=TOU;J?q(`(Qgg7vB93as$XMAUA=| zo&&iNfwIgU(#?U3BliALxvs zrT6~_F2Dajc*TSNAuADQKY`9~0-fUoI?oAot`q2tC#>f_t$X}Ga^0iHYsvpfiD1Joq2G z^1=VORS*8hgU$?E^YDKH=nSE?kNzjFee^$R9d-3MUjOKS8Zrint%Isr z`v|NDq!)xiW`WF1Sb@d9h<2j*y{}16KOW_`v0Wm5B_JZefU3P4Hmo_RV;JOqyJfJAN|i-2gU0j{m+Ku$N#g} zgD^xaYdusANbTB3|3P};c7V(UVJvon%m>AT>4fXp&r|BV^cmwS3x*gB{ zS8snx8s7Hwe>E|fM04wQKKoy=@$r9)i8sLe@lpH_IvWFY2T1o7(Ap@Renyr6ojDIm z1EBrkx}g2g&@ceyEl^&{UH|BR_x_jvTlYL46u5i;i~peWYC!oD;b|cyFqSf z-u(<*|AX8H^FL^BAjs{YyCpC@Mx=nwguCL}T~{yZPk#7c4=Epj(tzjeJO3A*e)E6b zrFZ|ApL;tX7-aXt({KKJ%({aX_n^(PLxRRVpXQyec3^;=k{mhHW4U~ zfx-Zk57u6K_kYi=kN>w^drwykvUAPFcmG2d-uw?jILOxf!^KvQZ9AQWpAi`U<{px?4DL27q zy@A|y>-CTSm!E(CfA-1O|L3TLL1ux>1epyA=hi(h{)75FptBiZ{?_Zc`XA(XQ2z~d z4kYU!OX{w63dfZ`!!;l2N}PrUkn{^{5MufP2I|KtPYOqcub ze*C}t=EwiruYdf%4WjYk*ATTJJ)pB)KxVx9@(XO{?BlP&XP1EN0%4SKj{ZCU_51Js z)9t)oh1&;|%jk4pDc0`3@dp&nh_Hv8a|&{ka@*zqpmbTa?aBY0H$VOdo!#>6)35)Z zfByOZ^AF_gmT$ixXScx4Y5~z8G0>SUAT=PhAU&`%TPn9b0hx|p~6PG{uKjYZz z|GRH~1eXiP?tcNF(E>Vy1%^RqNrB1?kecboUW5BpE;DZZH|oC*J`+c+{R+J70oeh; zH~xd%pxtxru~rB1?K{FgB&xCvV0P1w;? zR-skDicPooMuEkT zoHjt`dQ5%#-w+KOOnnMH*W)4ho(ApCtM9eDuH4Y+zTU6feZ!N|b}UZE(pUm?|BZV4 zbp`G2tI1kjSElQ9Tv@2ob#)nN92yye#2|84rfPLxNi^&}D-Y63W9N-{fv=3kiqVKg*+ zz^9}zFfbzG18gBXzLE76j;=1Q{6_PEk=&9?)Jh(7r@u3=$I;7w49j zm*>#Z(qaScTgA6;liHaW=3OhTy0w*V@H0aC#(B4vz-=O|tqL$lXZU&hRbuVcDCTQOy z$Q__42JPVlt$zlseFBXOfcA5O_6qtlFtY_QFt7zfFau~GF=&4?Xv_?x282QCL3&M~ z=P`ix1j}=Aae?;Q3xL82bWR63egU}~be;uhe;V{`0g#(P;Rmt{(kBLW4*(m6kH<3-&u!w(l?F)8GGRUi|()_bLKsUiuCe58V0jzs=lx z|FzrCf0N5ue^JDvY7q;+Y#{>!18C1XXe=AFp8>SL3lv76eV!nH$b#Y?w092_uK40( z|Ni|f&@cz36Hs~vr4i6R8IYNvebm7$LehESVcqLAYLC6PUHI&O%#knuOKyYquz>b1 z{Q~db1MS_M{QK{J$Ue@$|3Q4vURKba_m($5!Rn(AfBA2_@acc`+M}<#S9uzO2_yFx$2gSQ0D4&4#YT|M~s4Rf)Q3vhM2klV??RAH_9b{gZh-=Yw)taNv z9hScQpM3Ju|C+~N|AY3_f%X}J_8o!tT=jnb^&hn78npKiv?m)xgZQBRXdrozI*@vh zzS>7$|0kXN^xuBT%m1p?N1h8i=gekcU;v##0E!EcoghDe_KAb?n>;8UK<>om2hcuD zP&vTBzyR8p4k|}LX&sbiTv!F9V`Z~e?lYQv=YPch_uzfSpuHg=4B8(9+7k%cL)P;N zbe6#H{}X@y{tpUoSh$1ukUhk|{)5zk)PwdRHiGuiJ^KbWFMQwo|3;JU{FlpEc94l* zJc)sU0kmftR2G235EPc6zJ)lhy}}^(%gf7y_Ev(Z!N?L3wC5M>evmt{g+C~7xVpN6_636W zID^!x3E4!2s@0!-;Iir^c>Q|OHPAidAODww_B1~H{2ydL$Q>Z}fWj5U{lEYGpYrDq zB<=tF15Q)e+z$!|ka?iJ%SG4UgV#AbuYCDmqv6DTL9<{`83n38KFjlvl`sFNpL+ctwB8)FUjnqI9<-kVwC4omepvberD;(5 z2JO9^0NsZ>`4?nA?u4Izz-Lr|(pTsEAK>#FK>9%XLFPc*|KUG)FUp0t;5+X@_Nq6W zy2h*P0oo%k2|9}gdX50dsW|cf`g$gn=z2c2rZWfZmq6~V2CeZ2t^EeAmj}fGXnzD~ zFA(T#1yC9W?HL2@6YTo%^FJv6g7(dV_RzvGhz}A6@1KA7IyFc>uKEr{U?>|III;=K{R{`5&~`6}0~oRNjE`*I)lZ{BF?R_xC^k zgVGu(>_PfK`-DJyh(P9n_5y*z2ebzYWFKhX0cd@&*{rAkwK}fUBD)VCTf6(RsZRIx zU%u;~{0FT;1+B9Ntyc%d0cfp0Xzxk!^^gBSX$TYtwNJkM2klD)xe4U9cJR3#KfwL~ zr6-VoKzRd{zCiMz{L=93+yC0fU;kG<{0uG+K>IyF`*}cV6ts5^WFKf9FlZgD&-y3- z^}4V9(CNGcDo^k^ouR(|Ka+O*=e$-%Qcf_y0j* z1`0b+`URyUP+1Cc8|Z8WkUK%;I}C&PpuM*sd5}7gdXPR)9D>XNhy5i;-UY4E2iXVO zivhA9wB8rw93u9{mTcn+C0K2Ce^%KMcCx{?&ibJ^)A@ zy!#JIub_MYasz087-*jy$Zd@;zWoQq1t^WfFo+Kl2g!r>o`T#C@;gXBXfGBhPC@&V zK<0z?@q+9F?OOoZ58B`5z4p<6!wI+lYj$1&ovDK>4j8pNu5P!P{}{Xv0JQG}v>qRn z20`o9L16+~=MUP`0N)=B+ZziiPak~#4@%D<_kqe4kXvCG#0QCk>$-YfSAIAzdGH^!ZW*-4 z6SR*3vcD6uuMM<^1yq)1oqPKqwAU7tmqFzz$SoCjKmG^h2ax+fdsIPg1;q&ngZQ8@ z2gz65`29>`pf`Ji+UTK5fF=M72&Aa{V=19F#c&(-g^+z&eY)N~r; zUUbkJXwZHqkl#UJ09s!S%FCcV1fV?^pm+xDK?2zg%6Fi&1lmIk@&_nigVF{%28n~@ zL3tHa27~m0^n=nPXzv}!T#)%7dqDPq>;>5m3VYC+c+i??lj#rsV?CdD)qiH4&a3+^ zW<3C}T?VaP2d(AyTmR@kXni{<4}tO$s5}7K0kR9^2T-_y%2ZIj14;)Ve}KXjlqb&iZhUUP?`bh2bq&{98%tc_KtzppM&fJ*$cAYYxTqbpmo)tHPs;ZX|`R($OEAB zjX~qQ7BlYr2d#w%t%C=xfd{QghwX<6+X1?R8nRa!{vfDxF7PJQjwD$+J*Ae6%(4Hrd z`?Nc+g3bj(Nk*Wx&pJKVew$6Z_1}8-?f;-jqG^P8W!!&YbpAmJxY@x>+wPB&_VkVT$bJg?@0lL12`T)Yso?PVDE

odeoibN4?e zFMz@UR40JS0?=L(P~HNS51_Ofv;X;j&>k7kUK!BdW02cGS7PR1lR4L zy_z6%K<0tcJ1C62*FO9YbGsvG-^|=Q|H1o4Cg1!IT1&0def18=&9FEC-SMf@4Z2JC z9(XPev>qO`?i{oZ9+VfrduEs2hr|PDz54n`|3UYxgX$H~ehyIi3i1c2o&%*TP&$r3 z2q|wtX$*`HzW5IcYmhu>{|_h)g7ks(gUkW#GXjMTXiqLEtU&v4AZZ?S-}deQAoqaw zDuCt_v^%dnF`J0Ea~$3MAT=PhAU$wDEWG>QWyyW;9zsxg04mc!X%rM@pnX@MJ>U_b zyVZAt^7ym=(R)Go`G3&99SDYqgVG5|9Y{TB?+z@jgUkb&3(9Yx^bRU(KzDS5_LYF# z0orQUESpg9$gJQzdwr-1Z=_IrWS5@^3GXpa)8ECZLVYajiG z?8|xlKLmYW&Q8dF8_=E`7zTwk*xjJLH=CdQ58CwjKWP7n-`a=&LFR$X1(^@B2V@_} zUXcBuJDI`v4nx<=>2zJWuiklt7nXkH>-Tf$bY9H>&j+E+1%c8MXzzx_jN9OH3ADEa zbg#Sja_F7qYajg&0_}$Y?Tgs>1iYstY|G>S;JqWD{Ub;iBo5v~0=oMhv=?XnBk-OS z(0$|}^IR4|_lV7c?285O6`BB=cS4@Sy$)J0d>OPB5axb{`g$hq&dWZ!Jy-ui_LCv2 zhuobF+Jj*__2z&3*|-0L?iKf0cK^R0(w+#=o#G*|{SX@;{|^UY_`VP*AG8Mqv~L8o zhi2U)`2GiwIiS4{Aam{K+ySR`kbR&#yTNGz8t!0r@AdyWT~~K7F#KnPyPtu9LBHju zw08HE54h$hLHB-`O}gUxPpB{^Vu%{|ABgG^~2~AG9YSe9fc(puG$cp#2K# zAO8pKXF$dv@o*6n&(Hh zAI1iyah;wkpz}JBgCES+?Y`QJzJ3Ix4>Ye2S`!em;O>7A4h7wRyyV{h2+%#mp!M%7 zAN-G5_3%IFuHv{gkb92fp?4gE?=@cc=s$=Ly4M&a4^jtGAHDLy|0vLX(xCkVpgX1) z-uoZ25Ml?&K9Id2`;jroeYoy_)a$eVU-~SI< zyAE2zp0xVmf6zU|p!N}Q zd$0f3?Yat{2>}N<8Uf1FS{+v|g6d%uKlfbwAHC$>|D3fC|7Weif!99z54ztkdmUuW zdd~VskUMTc_uPUpL>w#+TK5jZILrds6S?@_f0T7hJ=gw&+@;-hee%C-3+*w;9?)IKpfUs59bk8LU(G;qFd7GZr&O%FKF#;_x|VLyT?HGf$RmHn*zFvMQ6e#(3mo+ zBMI<8XR_$_-1rDiOVB&JjQg(tZ`i`=9@V?khWV@AH3>@!ik=LHa@F z9DDHjfBW9&|Bd<}cY}f44zgFL=lTay&q+h}mUho|ckP}VUt#e8TF(W#Hw$#P+PX{c z|KEJ|{r}_lKf!B2Z@hxs$#&)WxBpjPU}A{)_x~Vupf#hQyZu1=LFPm+h1}@}G9T>r ziT6Nzd%j@X(~RssV%S=37d&+OZoM`Dt#=2tCAzPH?}7u_ld$4Gc%A>H=ik707Jfln z&k0(;3Bs^7oFIA7y?Ym*eFN_i0O<#n^PshnkopRAZ{@@PI=weuQp4>q|LL}0GS=?7 zeipQc4YcPE|5}?!%e%Nf!ErC z)PwYaFvuK`d7%C`$b8+N>u0pOu7KtZVb)WH292@k^jz=P>ACS6bT27vKPD*LKxqoJ zHd3MG@_!Hpt%(KkVHm^*iGwgm45S{U5A5!~oBu)P>GWLx4cZHbb$p5{K7bga*?HAg zr|0S>-R|rE4W>Q;uV+JVcZ1x9jzMmPW6;{a33tKzL2VlC?rR&gI{WqBO5bPgNeTj+h{s-kDkUG%50qw4LkH*L zv_hlpny_~FwFsTAE3Mj{*A9Zl2eiAcywdHw_7;Xge2}G3{~?z${eQr~0J`u7ygsR(fdRaJ zNuGfLysn9zfdRbEiJgG~yiAE1Hw{w<(}!XXKf)ZCI#b73?y0|R(n7Zw_H?+pVZ z0|Tivx_MxGVg7*Gi{ww3`@sI-hlT?`B3!_o5PJp&Sa?B}*)cGHuK597CFwJ}n4EziXLP8AU;^HbQDxsmFFd3p~V`F1MK|wAqE^MmV7#P?v#W^@QczJo{ z<>euF7-1@ah}hfPb8~}c=^G-y34=vB|afU<6jhleLEEe&i4lrT019X<}_FfeeN#OSsh zjX3zV`q{tEkH31q{ObSqd*YAZlYjr2{QJ+uAHVy*{qFtxtMlWp>SzDL4}8^XI?QPZ zS{eg4fuElr*%#{SpaobES@G}*b_*WlUH@JG^lQVjuPv{>cf9}6`{mcfpTDR4`8(y$ z--$ne_kQ`+@%~5it8b0ZztunentT1X-GT?gL0u3NKq-lbXVogi!4U8?Ad|YxecikK zYhOxleXO|msqV>_=2zb!=1%~b|7Xe{ko)20*FE`Kaqm;v?T`7_zPPP@E0wYkVuh9# zXjKe^4JT#uwmPkRopJ6%&V{#y*FKcr`BeM(OVi75ZEt^cfBMVthJ!^si3?9HyFf_th`}5<6ivH52+_! zWuASLf8~AYt&i0YKEs2k`_s>!FQB;S{`9ls{g0N{-y5EOt$z5q?DofkEAKPUzD+&x zI{xSf^BMOQYA%9IM8(=2mjiZwirxP_@yM(6Q*UxFzAL`|q2lhR+DBg?RV`PZ69Un=f>D!%a{_u{+s({B=wyo%lbJaFeHt*$GmW;3YNpSM}~EO^_q z@LkX14!%e^{wnL-+x#oN_a_eKo-A~mIKG#0_QuhReY9D{8e(<^CF39kLtM79zyh}UvCh^G2=)EsOw?FmY z@W_4bJFO0c7v$@&7*4q1y5foV>W6`wpM>vx7PJ3F($QDxr{CmUcw2Dgeev}VrMEto z-}zK=7lg|1fJ`pF{vrPg$nf;jZ<3C_irxPreCM;E%}>17Jak?0#Bjn@#mY+%FQ~U) zHlO{}Vc|Wu<@bHpJqq6XBx2XI*aILd(oVh3I`=mB;=BAS?+dTJFS`Dr==z7kYao+z zFTTq<_cra+>!hQv;tsrs*!3)U>l5E~kKC6(a9nuLY}ONvw#yLnwL7nx&3R!x`?lkv zdmbwv_^p2wyai-M%>EaNhhL@~f1P&fb>`VOS?Atnp9i6=b8j=xzDYmzI_3DQ#3L_b z_k#`J^2BfbBaf92oEF`)nSI-A&I_HcYY_9by000}cxE>BrtO?N&WrDPu6*FT?orT| zCt*9DM(uqbci=_B;g?BAU!@#>m2%=W2pxZwbo5oi;g_)oUPSGE9=7vY&=!!(Jy$+( zUVP7X&Ks|9p@z=U-+(j6u9Ye=(eX3yPieu zc^?|2%y^J(O+XCSom zY50z(q1&DWZ+;xG;gR>6hi=R6J1x3rI~Q#D#2b1&AP4JoLEW#@eHCIpNPNO|^J%xN zX5DsPc-Lpe1OL?zgVsF?+4wkY)8p{XPr|oAQP`%(AsZhDt$XCZ`k~K?2hI!cTFts` zKJAv#gzI`e*Ffe>d#c+BO`;(4r-IxMk<#zIZZ++u_oBOgOYaA+co4GsVd&aN;p-kn zYy->qJ=1+a91IxuaotO0bZt3@d z{G|)F-E;Qsz=ijM7vBq8em`R6gQ(RHqt`x)S@$RwjAGV3ieCFDYW2g2l@G#}-w$4L zKXBna&)K*2dagmVgN*9CrP~J$f8&{Fv^y^wOnRW#b4|PJs_m4Uam(&UFS#GH^nUE} z`|&FuB(8p#wB}Lr+D9qtKqz_bqolQu5?4QrU-=+*`Gc6HAjNUZ?%Phesoix|ujiV< z$E}(2Z;F$3=G;`R}H7X)atrwHR;BbBd=y3e?9f+Dau7AAo^82M{-%daJdg8&C z<4EYlgDLd7C*0NPx~AKE zL%Z*WOyMzHCJ-sE+kQ#A`?_w|Ro&hjAk=kLr}vs}J9-MoYTEw>M(~cF4-5?K2N=Nn zUKkHBFn}=g2L=Xi&~6YAhRQKFFfcF@gJJ4HdO`RD0|RI;kNh77255JM@&Er1{Qp7y z6wtz8P+x`E{Ur7b3@i)`44@7KsGqIEz#w75z#suyOAT6=E&^(wGGOUQfc9u`F))Do zGrA1Y*6BvoD>ekJy>u_}!2J)22k(6Vv5hL0ZDNoz%VuC;0IeyM2kkw91soqA_?|00 zg}C0ik-MM%YW?#6|CIm#|IdbE5WDsB|NjxYp8k@H>si3Sz+lS71-1`n1cP?fmY(Eu zfBx4#`~AP^#n=C!HISe+%%C;dAT~%0B$s^d_kXR@b^UOS3=9nF&6lkLw!QtIeeoms zJ`d2^G0>VskUkIwu|Z;>wPPSP0bAev(`dT}+P45U#(dhXJ&^~${!cjc;y-B34QL${ z=&k|SS~?ILBnFZLsfj%F6?7i#9*}1F`tu5wvu^+P+wk;1Xnh4}%?L;x$S#l`5C*Y9 zVxaXUAT@p)pZ*8wQK-HuuhD+V+kEy@@Hz3IwNs$=gP`>rpfy6Ebygq@VuQp$>rOyw zKxdSK^k{Zm_0;LO6b9M@30f-yTE78WKLuLL1hNORj^a7kT_7=#97qjFE$9wB-L9*l zpz~=!V^E-RGSIpK&&But2d;kbKNNJ%AZSh>(MPWP3CdedM2Phb7uf6cb1|4TPL`45^qfz7>v*dQ^GT-vG!|MjN7`VZRU2+|9} zn%!6BRl9F~idgvqe2xm}Op7IF-h$6n0iCS^VuQp$=bV7lsCVA@2+{-63&YwS7u+>^ z?|e_(@c#eCs~`Sfd-3i6{kK2B7{uOq<->oFoJQ~M@7gUFKx_PATH&--#}zZB&fCZJ zr#$%|u=3siq>b;v7{msNDR$gErqyyDw66uO2OC4Z=bpPl`^{dt=4&fKSfTAkk9yB- ztad(NXJBXmjn6PLFdSe;u(6qotPZ5_hdcxLeq+#{HPCnsd^{uvo9VX$E54m;}>@ zpwgD<%W@`f4D3H>)pJg_`x;5es^@fI|Nfi_>zk)89)e!S=j7VSOQZUB7(;YwJ1x5By7a!^`bTKU6+8xLHS@MX|8+Et#@!bp`*u`Kgw7q{vwLvMCHHSK>OusI zUe7hl8MoY*-;Y1^vhv=ij`u%0Km6?a__O;H2=#pa1xMYVK_Xore|CNV%}tcw`51Tb zrQ5RmmNRaFMg?JM&$#r9_gR~*qOH@c0H?o@}=eV_qI3R+uwoa zO*%h-0-^i!&z{eqX_{W}WDT6``SJ@MN*(Wiw7>h&_U3!b>+iKszJ%|5W;x@welH?j z1$6Ji?vBAH>eI6q9x_G~Z}_f%RP*R_N0nx51ri(04uY=*!wiU+SNLCOw9Aauebz>%MaX6+~?d zx0%42H2xbNul~B(t82 zZS(0}BGoK9VAyk6xBHqw|Mi%CFY+$EE4TuhZAT6t@cIE9;q&qbq^%2w-YJdBq^$nk%r11Ii zo9gKY5-XNlEzwPd_;q-e#S9n{@1z<;+{U-PiPcu2wEPN$Vie>jI@5 z+c|fVkG;w`{RVsZ-2DWqzX+Ajz2G+Cgde}5zmUqGf-9i>m2=^3=GnLDr{5$Wdu2TvG^uLP16`s(qfpZ81_h4g zjN6GvUZ$RSoem2h*n*!AB{x1m>n~XS4q7Pn9JERbR76AT_a9v!p?!+JZ@>ECRT#J+ zf~FjJ;D8I~p3lD^eKB}11Js0ul+WPyPt|?U`lzzoA4_h21f?Hv_++04uM0Z;CiUd& z#KSKwXMlo8pJqX%2QG6=Cf|fCg@S}n#u-rl0)@}z_l4I!6yJcZysAWPA2z)NHGx`D zt1xK$84^U`iVU(I4^(Y|Qx0U+A|&x(DV(2wg|wfmAAUxJ&ke+KENJ+gdYyXWb@H)S zG5cPaP6pNc#=X#mKvYacMtz{+8iT&;QG1?4msg#5oqp;~#u?B$uAB?+@-M$Hyoy+v zR(TJ;1P)q6H@`$~B7%|-q!k3J$iNv5)TaRVGC+)Pzd_YHBxfNtp4;9+Ggsqtkg@eo zP%5v|TOW%-;qyNK^84J2@3POo%{cQW4IDm@1z?f8p6P>oBIXmQnbGpsKZZ27LbpGS zJ@6v_(96UluORE((oaLe2V6v7g;(+5CL&4}gSHakNeI#f0|gPJ^A7H!_Q6PK=M+}0 zLq<73Ekjt%-tg>e!&9WjGjibruH17jfR^)t!sq1cl;fa9eF=v^3*>^gJkjj|#dYz< z$J9zckic{aSX>_rf0apT=j&@2Wjr9pAs`21_rOK2A!(olp4 zQ8##q1F{$uGQI)owxbRKL7F{~k{OhEo?^>fH$N0z`+!zBr=EbUOMDf72(&aYYVUK` zW%nUIqDuHcj53;VJ$&c0$UUHig>eT#D;PoHa{{zf5>f=AWwEl`;8rv^2|;?P4bQ+G zF>o$xeFJSvcYZ(_B7+Q+LCCI;&^{@&%?uvdK&rOBf_kRlo)@HLh?%*di#EZ9Pr~7s zaR*;QmqG4)W&kcO$Xh0a9I7?jpXqjA)9bw!vh8Wuj%Sg(pGEHjukbtsS>gFQ_2lae zFnkk#Fwwh$tS-~(l#P=X{UNIlj0;b-Ru&=?x1!U8v#At?va zr+^g8pl0*K&y{F37e?kvhOIu0JMbcU-}A^l&%$>;3)u!*KdIY&t!mp7WdD-Nh9n;6 zCHI22J_+3pUYm-@Vy_@cDE$<)6$GutV5KxD34t3zkb#am@K^`5y9&u@;IYKEx1doA z$cQ3jJvJ!8yaNfgy#3sUke5wR@=c~aZ9!O;os78ad zi&|cRQb@~dRPq(L6AEr8g9_wlpaK~=<$#KvyP&NQkTzlARYbLpns{D&H_&RjqJ(5xm=)Pa@9E$T|(5iLcb&mozJ`UOfNkZUK8kU3-4udNC6j();b?$A> zg?EtdJft}d52A{@pDOQvu6h6-cYXAw_VJgxC!iz&YRQ1Awy%xPQ4mBNoS{HfRqZ3t zIBN9+Xj8fT4k+b-0teI}gxBfNHevcHc**lJ{@_b!$-Em>GKX$^3Q0VE>p?5+UC1hh ziZ?yc?Y?F-@rK8W2VScl`mBBAzu|G<=EsmE1m8grcM#GR0vFUsZ6T~d1SzgTdF}pZ zP(ph6r4|}W(15B3H)-Hx-4jsrul6xWS*f4?!oU8BiF26%5mO*Vo(58v_ zL!iKcRO=DDpe1wQ<|qCe9{a9)8dg#950jz6(o%k#U8ZGI)=CTB|L&sy~1Mk%jeb<4K5U7;i3fkuaN| z$Lt4fLVa9cCJkZ3m?|IbT=g`En z?P<_vP|57O4wSh(S3YoCe&1!uJ^fx#kAukYiCgwSxBHsux>5<_MBJf_Y z%kK-WfD#g@#J&z{U6FJrGPknQKAQB1RLg+swIbKmU&7!n@9kL3`6c71?S~ zMFwpP!Rq?(U7${D^gd{d5haMgqeGczL0kNCE`aJ6cqkQI1r4SZfy^;BWSg? z@`2m3`=G?L@UH#*yS8)g7)}7qP?v5ZFzDe49;Y>#e8YOyZQHqb?C0NgT6E84$$huw z_dQoW@LmHgr~@}a>-w-A;7-||=V(EceEd}^q)`MOgN5vc%(;L_OZitoDFGZ%ps)fZ zDsUME3ADm%pe7%rkSVwVDuj{K3?yVS&w@th(occ<$SL4XC?s&=4!l4PoRDo#L3I{t z&T?P=z-1|Dk0B`W%)Mhh`!=Kq@|t}Ie-eU>Fq=)eX*Khf&FtHD^N?~GxUNS85x5|N zbUHxQ89az!87=u3X#Zv!xLuTS2ILobD8Z8xBt_+428RG7#2}$@1=Lvpg~?@5JqXT9 zpxlHAnbV+T11gQd!xxYO8PbnH51cKaVkclDN}UcVmO+6t?~cu!+g3Agn@t4`z3LI# z&jl%*&8FV8m=4;NX*&m$gh07$2`rbvnnR!#_2wtR(2NF3MUjvof^|Kh?IKu00u9EV z28B}QSx~;nKL0l70;sVK39H1T%M_z$jKG#hq-!PkY({jcw z>)Fs;=D6@4ye{(s6-3ao8kEt{f(TOSgNI=u#SthW9S3a$PCW@4PfLe}(i=!XK@t^Y zCo&od3lq>Z1f-lvKlK`tW*{MxbQH8<8Pv`>_ySa0frfWb%N%e&3)~t6x0ay|9+aGA zIpdc3w3{ZAZxSq`bJu~!ne}_G8&AApI_0MM^jpwe2C2(n1(C+d zEz>DCjVImE1Gf^ZwmrpF1jR1B4@p0U6RsOix&h5)GjH3>xr0&=fy-)05JB42ftw(` zSLhf~#BR_QZ%~Q7|3w@uA%O!5cgJ?l9jjTlEvAEV zmdT_WhTxsry4}~(S3klPKK^s>LK;8%ebuk^AS7_WJy1|n2QzTM6*|1w zF`0bRXyOgXSeb73H9TV--m^htK9F7Q27T9!Cf+cad=pv_&AN>!t0Dc4<)C)8=cr^`d*uOYXTY zyYI2$0jw;7wu_*Z+SVtb+n$C&f@l|LyeMi9sFN7I4|I?Ms9ZV#YHx$Q3{Fvy5Wq@8 z)Ii2?Am=c|>;v^0qV_zG+yg3#A%O#G0fM^^fuO*FRpqN8We%t*=&}S>CW9*UJ61Ch zIm>9m4gEeu_&7|xi7S60hmT&*HE1rw8$@p4-kBF_DuNbAsG$@AZfQsD0mVBgp!R`k zoY(`PoC3;y;0zdd5Ht$|Nn>$fDUgEwpiqs*2o`wA!15HRWA3*eDdntu04b1NmfUk% z1no!IAQwB6ZyHSikgZP|TL zBY81K;DB2@@L~rNIFQO+xBD7N;R6byepo>SX*AA+29Z4|h#&KAH!p4+3f(`K^2Czy49+hDSjg9|v!G9J1wc z$d)IeTc3n&1EKKkpc7Xjc07&P2|k8p=d(y~x&j@>0y&ap7g%H`NI}F7kYbP)u-?$E zPeQhUj%o?s^f+kaA%0@gqBTL-Sh!N~@ar<{@Ul-=ArHnTyU2uM2_Yv91skJGdp zxXK@Ir1}dUI1mObh@g!k%bB-9P3t*#?7)3k$AzGg5NHE?#RH$!4}I4>@?ZN197K-; zH$D#9^f-9alaS3IuZ3=X8n*Rm*tVzP+n$DRe;Tp70&vKHw1jSb8oC8! zNbsg7K^q}~^EhBV$Rgi0k9=T#2T)PG_#UW{Gyg6qWahvE2h!Amr5ycU(77}a-$6)7 z`4hb0F0Sy2SbPuC{(-1RBcWvxxVSc-b_>+|m<7sfpo9eO#yT#%=ep#c_lgHTDLr% zAgQfS!nT4`hHicmy6H&>_#B?#jgNyifQ$`T2MQd&H4lAPKlEAozvk7 zB^%3`x6Gk|a|6`WLCschZ$iQ+cIkaw;ghriG_s06hzuv(Fqs7IeN4M$G2@oyOi=3) z)WDv5$7$hR&!zXhm)-YS@xXWG1OHVI16Dr_T=Ot!?Ze=8kAl}f3f}N2WaFcdjgLb& zfes)F+x$3e^JDlKL|7RRHDRDo1)We7vJqrR@cKtV>mCKIeHgg*VZfS){;MAPu6*FL z;(_D1|XF$RyXC2P=bJaG`v<{x| zfmHgC-iPVrn`TpQnu9~hYUXYGxwkzR-Sb*<4-`Jj@B1!);J5NYz^aFVs~-lfc^JI* z5eTh&6tezt==#T@8y<&k1flRvkHa@T0in%LK<70flMwMuAY~xM8$cRE);|te2Qn&X z?W3SIAj1PzJ@jAsz;DF^pXH#a@mg}vbMZaUM`0U4 z>LGeV*FFka^Dubz!=Tj<16P5p@L%!3Z}|h?W%qrS-1lC5&uh^=&xLob!9zNbkTIHg z!?6FlelMsIi0K`;2qb*)1P(lW@FyXVfxXbCk@3VEW|MEY&AsEb;I8+=yFQEW`7XKV zxAeaMvikwcLC0+ct$Yx?3Uufe=-jO}prg0Kz^8A44&Ykw=un6}I+K=$eNis~?7}dKkRwLD0$vfh!&aEC*TVxAea6l6yXj?|Co0>$Tvn z``kNbQ*Ibf1a&+OK!Jl^8iRb%gAjxS4*u~U(D^X^pe_dC@By2w-*?@h@4EerTVC_- zc+bD>}?*%NmAGq{>(DM7i%O8ZSco4GkLFlT7p{pN;t$rB3=27_CM-giu zMXUp%$aRk+*Mm^h`p0MpA`VgjRvEDtq%nNWqcE^Jp{pK-tb7=<;z96=2SLk0)&(rR z@4w`p-=cfI3-5Z*zw0&cj>|02-b~DT3N2(HTuAs>Oe8Q%7zvw?hUg+lnohXkJ@<~! zygR=0@A@yi8?fkJ;Np8hOYR3Ry&t^ne(3TCp(`GQt$Yx^>S6e*hY_nDMy!4qx#nTy z+J{kVA4RPLq3Csw5NQ3Q==DfkumX^>wT~j#f;FxN83HjaY~{nS6%Rs}KL}n1vMy-J z{lLZd0v6r#UwGGd{#~DWcf9A`F_{25#rJ}j+zVNHKXlpsu;ur|S3C$``5=ih~(p!s)$7v2k5 zbT4G_z0f81!k69;Uv@uY`TfWh4f7c8=@I}x&ko-k3a2OaEY^D%f1bNK59lq!u8j4taKVs?q$fftA zmfeqDem`c#gP4^MVpl$hUG*St)x-GJ598N>P{P_r5R|y~QQ|rrXzim!n6d=0uK3jt z<5oY6TLm&OX61vJ6%V49KZsg>KMHJP#FG1HjtO6M&wVE7AVmD(0|^|P$vAr!$l+GD znQ$veujiV6@3qJ!_hOcUj#b1YW0!%>T8vxqAb!Pzgq05xRy|Bu^$>LKBIxMFhskRm zCa(n@zz8D2XD~ueVnid8*TK}ReU!ZBVbYq1NvlDIfK3A#8^7{F+=>Tr%kP7%!{L(1 z#h~Q}#Dq`PHhe7~e@$X zYagYp1EKVFk3eYsqjWR`5eKVDTl**#gh1L;RzFNx{V;hI2qmq2NYDX^D;`)*!dFVe zJ&POy_}O;g$uj)m<2mbg`s#-yp^P<;GS)uIT>B_<9Sp61lm$cC>mS1rTrhJzOyxR| z#*DR(GS)mwUqhO`ZZkor3gAjYknnNDJ#2^>R#U+fVfe!*bm3jdnW7|<>mTK=e~f+r zDe_^Ym~7DTq|g&eNw#j?qkwsLaRm;%X2%Q!{34K0#S=ski|-Y0dORdh@Isv71NSEW z(7=>!B-9WJTXe5#+tVR|LKoh{m3|=M(|7PCW(W`zf#}7RgnZ`QA?ZNf0aWY(KI<4W zh~OS17!+6)OgZuzZUUy^Mt#>?_dIXk`(p4T6TAarSp80GI;YmX7vu+c4p!5JL!`cOddy1g<2`Y$M3|h1RF%UB%N;f~A zd-BboMa3H*W4amQ7v1h_u}g3cH4_XLWCez>lZY_wGM{*3+R;}_&%PamXzGzyX4u9z zAmL-wOU*5)5HqnBL{8IhEkE~m-KBSf3N1VL)?pfG$rD*+=hx znRe`z0mj5AB&kCJ$72@G(JdV7oL8jGunUWv;8!j z{d7p+xXq+(;6Osv0=%08PY~(#TuWW`@Y1udH(!0H1G@P1Yr={LkVJw>LPAEj`$zq<`KI68JC$3XZn^s5`>($wp-opmRBU zB$`tPiW|BJ+BAZ=3hq=oGa$A@$f(6QmpKhoC_x+sC+QhDa7!VKfeHbF_7-daZLfnk z5<=2ClpwZ1NWHGB1UI-5^a33eWUPJ!*&z;bHl8*BC7}m5To-gU-L>3x1h)Rs!Q&)Z zk-Pq}Nk3@cG_pr12@r^0WYa(=VD#U}+kkUL97zry5XJq6UIfg$1KD7X<~1VI6{arT z?rR1;*Mk?_opR*WfOv`)mQFbIB5?j)EAR<&SiMY)pv|P4f%ESSr(nSq)bT6sJ5Rr5 zGx>&T{|zJ9EC6y48TDN^?Z06=`G)KC+X*YFGZ2c)F{9$6AwZ)L_)ksHzz8=DbpIiY z1G+yE$_8KeUJv2?0C@>?#rgmLpj+M<7}z1=kSpmSY>*NL1~B^%gl!MvfVDC(fHgx8 z%>Zi#-FC*nz`zVr12%?%0qi7*R)|4JY_MxU{QCc(OCdol&~=Ufp~izP0AFAalHvdV zADIoc7VK)MwP1^p*-$5d9f8aS83)10*K&idwugu^Fx11HhQ@}50!W=bE;iix3=Hzb zu;JcfV30>*^A9#QF@C|N23J@ii{lD&Byp7ZLfi+;@c%z@{KDDH|NkSW2jnz^%!UUv z|9_OU2ltFTYWjpb2$YjRNdbh>(>&B-a9)5~2F@c;%lJX+p}q&_DX5_!BcZ+lXC0^y zz{Wsx09Y&3MPRM}A;AJN5rjeapMq#GhGaT06C0tyz`)?az`!tpfq?;bPvHR@kbg$; zXb6mkz-R~zvJhyQxiWk5mZ07P4xPs>J5HN)oHOjWpx=2(zw@Gg=S73gi-sK+Oghe4 zw4bu?JRZ=yFKgnarfJIunI}-36W71pqWz?H+hv`uYv!{aIj?-_yXjTPj@OZUU&kJL z6MN`w?4h@Dhu%c)dlRzbweP0a&MRJ;&wQlac~!ghvPJu;n7*wj#tj0FThB4A&Kr6Y z9@sB@6tU-3%8556H$S$${oV&Yb{uk|J@l@lAK)YYzkzOtYJKy)_{PVS6K^8+ys}&P zNN>UetAPz_`7MUaR|-$+U<58=n?k`v5wS`YGsS^QISH zn_quxd-J{HJ?O%=p3gt~zW$!@{rAN0zbF3sJ@MBcC;}gj-}eoAZCmGuAFXdeC+dO@ z7lxdM|MY9&wfBA-o)}Mipw)egRJW0*-oEFw?u3U93m>GNd|i1Tbm)KeL(n;!4bMQA zW`Qn+di%W-;;%2i`oH~xT&DrLMFV`%2+J4~!-HDHEyHAnlT4Hq7%-?O?b^ho{! z-}?nRA+h|r&O6?Zmi~R5b=Y*G*?UjM(+85OjR=`{ElPK}X8o z`&5I~U!P(A0^jN}<s@V(BUUo?8|(AH?i?o_7&+&|AS(h`&Hr;1EoQlYWA(m74tf z&lGS{oJ2%AtN`DmP<-Pf=m<;j(Q+~So}15lpx=A5Z1HhCP9;f7x9hs)?1!=YpM#I9 zdy{+d9l~FCKUF`#nZNqJ!t&QIsMjX{0$oZ6x~S&cZ_srS;35%ni$>E+$o*Jfsvmwq z_E+AecOZMuzm3`d+;Y|fy>6m*g%R|i*`&K>Gag3lewG0~dN1=V$Y1$aKv!av-TGK@ z=Tr54(0y|CPro+3_}cR7TkC7kO@yGz3zo(DfBc>Vx=HT$q@N&0{}0d|grM8wK7npB z=zv~e`K|HgxB6$GBcZDwd;y)2ed}ZK^^XNtKsSP9oqLmh26SOS_hGzXng(^a^FeSeNdrMdJB}f^1=SfJohFIbl&&t&YL`p{}3`HOX8mfka%{McvhL-2`9uab|0&N9n513FJI@AA9CYoMcq%Wi+H1Qi{i zD1+V^0J4MIz+dlHM;U_awEx{m~4*C$iz`*Lv_Jf0g$?mE8f| zKvsASbRc!kg?E`}-$MKaIfBr8%|nAJkKzdJ0mhXSb$ajG&A%7D??vo^m+^;QBpn4E z!I^R9b=Eo1v6}@~KxeR)-u_sA4|LRTEvy!6eDSUIHT3Gou8*Kt>-zK)eB;Q^9?-ob zKS5m3T^c`NDG+q|Q{yvGWYs(d-CS6C_j4Ke^xML#AM!4OGFQeK(D~y@N5R(~9C#VC z@44Old)htZq(;*TH_T@~4Bql25`4~4{J|GVu)Aln&Vr&W|MEM~l^8cal->CVx>DuA zXZTGI%`ZS#@_=u(1m!jOWg)OTFhH>hX+A+xAgDTi3chjYA?V(V@;jiTT0z(8T>+gV znRV`M`f1Sde-MAgfKMn3-ulFR=0np7H!nQ>hAUpMitA5)?7reb*bdP7w$Xc^$AQiP z2c1!vcJg)R8PJ_fd6(XSE*!e?p%ilA;{DGxkDy+IX0%t(Y8vzI3ed$BufI2g>*A*8 z&}%rWAAJE`vji&P!Pf{~{g8L*J>*pDv{R6ScVERFdI*bM-QHVPv+f3NdK|J9bY@WG?q@Lvp2veuV0@K&{8h%OH(6)jT4#)tAd zpo@a4AAAB`(eVg+X8@?V`085=_(sWA$UPHa5_G@9E6_DmjW517K*|cx`R1U+3_7Cv zHt782qHFI9F24uoEYSIWRABSuMoi7%(=NbG4BghR;nP=aCj##|}s-vM^1IJqB zz0XzPTSGuM89e=3{|waBN4~=Vbg#p+uXW%I1-jP(e9}6o!ny-GW4#!53nM79K*c+# z!~h-Odk}mJ5$qNj@LBwzv(&9--P7+TyjQ1e^Am$f59}A*^IrYXXYIp)jgKIwfk*Cs z9s|8u2b9ZFK$pY4hMXar56@^f!I#6`0bTe}egAU}=)#ZBkdyT5o`PZ!a<)FmzmLJ^ z$UpoHx_1+NJUXPTfZon^P^b=SBXbn#es4b=v1}vUEo_uK!+@YBFkgt1J`BuO=moGo<^XW*6X`%IpdDY();eq zLC2Q)u6qc-%m#F5^4{k$2VTS<1|7JWa^h9mY0wF+kozD(=h}l0jE4BG>^8{3l{k*G zha6-N>gnA6RCW_o`hhOty9TU9SAs>_@UZ}Ts|1D%e2^+WNs_h8?Fk|p^1hmYlVP!RaM^-m=? zL1)$%gHGfJ6%_fG-{oF-n|=OW=2=jyDfI;C#CgzRtOq~`M}kfo1>ZjeJ}DA(i-YG% zP`Ywle9vaiZNq8L@SH#EG3&O`WRNn41<+&D!IxV+^55_%2wZ@K?EoDK3OZO8e5x$u zPJ%SpIq9Hc1k#HECrij_`w$O;ya2k90#xCa+yot%4mn95aw>Y>CD7r{NLRnSfgFaO za2RxCbId-_$%bJ&o`SA60jEHpwU0bkJ#~?t0qFE|qbc`&=iprXZqR$fcrxfL zW;@Ukv7j><-B*B4V?^Bhvi)iJ&ZnTWDfc}`+$8{sHSoPSS?54a5pW+3bTBvcp!}<# zL(Ge=fi7JG9cX^_L*Z4>O)a2fyDvd5P5_@weHP^!KX4fcJ{cBt<;GLcX}MdU1Z;W& zI)4y+gdFGu;YIiC=Yx)oGoF0Qupehdra$q4$>f_>Gj7?;x$Q9juG8YXuFF8jxO;)_ z+jtnb5p{^yD{!z3O1u zeWyjBqv}CtBG0;IGWn+dMC=WZ*4@wbC*Cujbi;hwO)JPD_27FBASaC?U2*`b(ZY5- zjob}BC3F9a_(LxsNB4q#2Ri2(lvoAfh?L&G8GV#k3m zM*-b=w);6W`E7aZzY%ndruUjh9*`sW7vBe^z`2mKjBgrGx~V?_`w>4WD<9}jxN9`w zhAH^WV$eCEpwxI5diegT2R>^-2VO&pN62Z{&=ZRHgU%)fmn5K5hC#))dB&V9{a9;i}bsh|Uh^(WlLy2LPS(LMbMcMSR@lmN)s&yQ@C|bnS#eKg4UG^W1G_-?5)}7wonBAg_VXnD$-w z$Zx|V&~dJygG!%nR5qpisCd-&N75-7w^9lv;fO(2OhI- z>-U5F1v*on81JD-Bix$~m{4`|Ki{PLQ+v??f!dQXa-Hd!W~k z<(wCTUeNi@rc-V}&YZQHb<1Wp=(+;eMc|`CS3K~8oueAO?jigTRrm?2SWit2-|_@> za4PK7)Zh)E(^rGmJ%XH<>bL5l&x!|L%kH}_21Sz%_@q>e>9@caEr1V@#q?CqHNF13 zN!U8h#hV`MO~B$WP%+Yb-Dtvf&>8wuK?k8)&baL~?~d2vd)`a$`z*Wfy8?RtY4BR` z`KRk1g+fj~-S8N3>?!n+Q}7X}5H|Q+)UXYY5l5Y_c@((%VF37?Q_vx&OYeIvx#v9p zuGP%j(1TwmgN`YOmVWSPf-&?b+%3m(cb)#k`?@{Y5B=2dy=K@CDkM!N->{o`+iSsH zpG9|lmfQm$U3x!Y#e=|=4}w>N&*g+1%DL`Q*t$pI>p>@$f{xwX06Lcw&IsS|IDGx% zu=OA{p|B%3gI7HaT=^hi#RLE4pc7GjmfZ7RbkA$yUHe(LO(x$kng}|7AJ^fMx;@u% zwGSB>81z8(7rxDV`n}i9Cf{(Md&g(NUEf7_p+{;igPo_j>H*|1%`oJXG%=3Rgdd;@ zI%*SqdS=*a&?%fDt6=A5F1rsuG}C9nUC()UEGFO7>%9g-u-E}*C?vLS&kenPER`~( zQ)xTpmR=u$)9#$6-}0LeIt?>m(Ovjam?7YEFvC|pKpcVzI{_2d*_X(tUPgdV&kSFM zIPVgE*ro6MyMFWUI1)U@vG2A$?gPS-Rz5VC^bjp5;9TAAYvvPg_|3Z$Fz;@_{JTMm z?gcNt7qaAD=+gV)%kM|50G%}%wdz6Cs)y05A4acv7_;V4%-Tn>>!1jF4kL^kyA~uH zvj(I%YSqIi@KKc!D;|U|zaO^je#jD#;X#Y;1G4ygTOL3q;|LL1P$925k$3 z#12+cfAV8JY*|bf9O)jjZig?v7q$?DKqnh61|0+mI$Cl0{b3nk5#;Pe&oPp*ky`Jm(Qyx!0_8O~?Ac7VXZ-R3fxCRIN1!4&3TG0M$5lilY4kcWAKNgOb zfzBv|o`<*!bRHt;FvK;8lMvC4K16UK=OltpKTKTxFcEZ+;sfZphhQ@yM;}5gid%j^ zV(~p=@U9_7fo_P2L;svZ^%+mY%lOAI3oYCpNW%a;?%0Njdb@jv4RS#2EJ;Z8w>MGEn zuHDodI^F024yuMGJ&YwZXSDG28@>M9dcEi;l4y5d^PYVhbmraKM>*>-(Aq~ia0HQs zo|N}EcLQ#;{&CLw#|YEVOn{gJCUe1-dd$9!#b3QQ^!jj)*dWK9)3jTdNm0A&YQX$E zrJEm@Zhl-scLcH5Z|)s!%=qfR<1+mwviotdryYH5F!>Q$4%P0u>NEFF?e=GNJD=8W zr#Avy`pj$gZSAhB$T>^5=bFLf$Fq*(D>0D0=|BI0{-g)G-3UW;y02MHy4kq%S;yWN zZF}gAI`+P3+V$LOGFtw+sz2#r-~uddU1YzYv5lrYM9yV8;JufH8y`>NWfJw4<-)oOm`5jHs#w+i)U;ogs^QmF)b?q*snyc@YKJHd7#O3(O>a9-=raac`K{WEU zx~>}cUvJp?Z2z54`|o_(b@L;Q(EdB04&41zzvHP<-*qjd6sXsG!(j5`8r-+{;r9_- zHf!x;u-6d%GOezwI^EX_H$L8V^V9jK-%dUJdi4GmDxy;lzn*{cZTHPjC7YjUcU?vC zRL^yT$&a(vQfGs7@~VdhQ=cKycF#5KuB)1zS6ye`o_*rY`6u5VzWaIg`S(lDzFm6u z?IKwSqW9{H?+@SoJon_=tmCg;XMzd}va)~U)bSJ~;y_)P$&dAVZ^E07y4}|_ zI$v*eie+az4(6l*|+mgzMgvY z<IE5*>F zb&pwhQdT~w-1>C;^^X)0DL$CM12GJOam|*v}d~>y!jfkHJcyG1}z<7hq4bq4nzQ}2m2Bt z4%zx`58A^HJ^Mf&%!U*s{1|MIk)Xp4K<0pq1RZt&Vng=2GlJD4v%yv|Fw}$8AhAI% z25~{+5GOD&*fTINAhTiH-sKq>7_hPVk;Fl4h?5x@@UbDzhp2(E*%=rZ=*cF=oycln zeh2vr8yh)%(8CZpJdwj36i=}5hp|C4^!x%yJR-+0G8+|pf}heFZ`#Bq@H1F;yA zt{@iIgVjSUfTTU}aUZbs2{H)A1{ov|RRhrlB@ckl^Z=zL(76MkLkA#iNVZ~NU;v#X z;K0DZ07` zrJQ_Mdh1ii`yZgK>7X4}pe^r{|(vW4cX$}@%~52t&hnk-nuM* zW;peUS?9T^u1%!5fCAN~9cK-uJn~rkBJ14Sx+kE}Zh!k7w5#gU_(9$O z<2QVdI%qrGXV4zM_IIGT0BuQn`@R0j*Q~Q|J=VO`pY+JA{R{<;B1)@Y??IjZ2Tn_$ zrJQ(E_xMZ0Q_vojrWc@HVQp_fd+edxo4@^@_~Z9P@J`@Kzy3fr%Jw5|*lvIKz4_Jm zrWfBDpMPt3_O15Om*nHG9hN-R>A&yOwU;QTkgmw0`=ZH=r$JkvmE8DH4c@R(^XLm` zFXBtE``^Oc|Mge@cc|kb+s+|gm;g>fJ&+B|?|!s^-QV!+D`+du!_Ug~B=N}0lA9k(Z+$Gg^Qr2==h{bK>cQLQTVH=~fBU2J z<4^Ee0H8g+lfWB#A$zbvd**-rnegLx-`C$D_ka8e*;o$Q&|CZHOZ9`#<##@n-UgYR zaQLP5ye9_T*URVZ!sjNU<;oTx*Y3LRu;@w3@mGacLA$$4ZbID;3IFDo-=OaQ0CWHM z-;ll5kd5&m_k%Z(_kI0^$Ni99)`eH!r=ECazv!_}*Y(mxR5)uxr}vK2(kH1WUgcZ_ zZTl>|`X1!|+aIey8wfGd&*z_@Q!_Bq&%~d9KpXqN!VWBW_Z>O?R6Y0%*~nUO6|@;3 z_u{+Mldm0@Jl5$UYQi2*ROt8KvS0W(>FCSMGjB7`L3dCW-}q1lasNZm7C}({ef1rD zoCNfEf1W6LpKWhJ`M2@Kw}z)*YafEPL6+SHZ8a&l z3feWDc^0&-DCy`+`-P7Uh+A`j)eB~m?pn`#9DCq->WSBBr$7ttAv>juuYV}L1>R2l z0Cd7aBY2xMC<(oTp0LpK!859avJ51DuKKpX0we64x#x$@qp zvRj~COwirYuzfzU`=49SeQZwFsAb^1JEpUqhV6I?*&~s9@^!|UH#z6u=3RaV+4Wa` z_fz%#&$ZxE6dVQL+TMUR&~|+UAL{W16xw~@?a-i-AAHmWtRnu=@)}%nKK)wv1hiqe z;x1?xG-zY(<###f-(`SzRwN&Nm2~7~==LY3vz~^|CvD)hea~~fNsqi%KZ-p7TJE2C z2{nkG+p8h0d1yM^kbbD?(EW8iePPz4I*v_X>d!NT1 zc#(Jnw2dVFB&cM7YjY9e+J&r`|?}!OHc{f@(M~ezXTr_@&df| z8W!^44ZWb0UkKiLn0xVE=D9cNr`{wV1MN}<2mbT$o#2g>Tb?*9e4x`!c;Y{K#RJos zPd!&X0Pn$j60+@S#I9$covw#oCLVbS+2#t`|9|0K0r)7263~$ipk1J#>fj+HBEEu7 z>Us7Reedp5P@1WI^rZ$|V1l+--vL#)plo~PeeR`qS)h~;+qHWLw8=kWH)zjB(3U3w z8y|bFdT2W1Y1%5tkO@4cqccn=-nO25-+RqN-*uqf2*F#QfOfQkqafk%%cNtV9X^na zk$K=#LW;m;Dd=Dqa9*eeH!46oa-V?CBdC80@=N^_u*)BR0W}pKLidN4-3ISEzVQK6 zXI%y#Qg9Zup(`1*I~TN#FnaHE@GjOTfuOy1553nsw4QU{Y!ZQj$Y|OVr$u)mTbTSe zfHu^HZ3pe9i`fs#1&N@e3P9Udv%s6EAv=wWZh-PK=pcr>;1cNps4-Uk=yUBukb`R< zeW`u;rREV>5S&{6^0e}K2_caotS`3R@?(gfr1^pg}CS%XzOF%C1{zGar#Z_ zN$AGZn0+rIL3D0F&i7sa$ZPdO_vH_q7vD3Te&25{&M46Dxn?=@uH&M+u1i6i zY<NBufe+eJ>#_2I z%hLOfi|$#@x`*qkw~2>e8ce)zIrFytf;&!&!26C?J@i@oC;*&_LU(}5;i$dO_ zUx9byzsWfBHXD4LNA4xaCgJymuwBsLowT4EJDw+29?spc4}=y~_h{ zcn0rzeh)f$=*oN0c?Xx@<%9SA=3ac8b^dMESx|ycI|)62BjM1?xPvdE_dExcIp95t zklm!9l(XW2^OAcG3+~#@1?^5Wp8m9WBbKWV!WP{#n)=9M8fXKU9eB?kBo#q+kOppg z0^QQK>sj<3P>m1|I-vu!|1br#yAtG>%(HJZ&w}>5W}gRb_|Lfr+NGR(5tKc1FTBgX z04ii4YSK@?NjnMJUJl(23*PV+z3+L%PH2G{xbd<725`z*@xXQIeaD4&?dILJntj`1 z`YofWkHQyX*)nQ9`KIBdyP%C;Gj2gPi#ja=?ahOfMWEtz0Ds zX(9OBBkmEr+$(P-CUUbiX-W{7cAjg|dxoJ50uER7e`@8get{L>-GM)(9 zVQ4kuw#}S7_6zPpGs4OT-m4$^t^@5Y3bZ8qhm@uV9D{kM#Iu^c?1+jA4N2bLMpX@jgNvh zgHCD)+X3D7AH5fJs6p%j(1v8lo=-@V8?oW@7^qYSg*J2x>&v(UFJi%273A{W&%$;* z4cP|X7`f?@-?~TMpgn{SAbSYG$^MSj%vd)4t}R=L%5Bg9^-r z_iVviI?bowGMjSKaKa7H>^P1sF<|$DmPhFKTm$Wzo&wrhY&G+?{oFea3-3BD29>Cw z!!lMq@Ll`RfBhrS=`E0*oZCU&obX-GK-;JHfHsFm?*s4H1Uof$|BIOYpzZh3;PZW= z_JAtZ@LkWscYwSfy6p)h&G>`2Lwm1!=nl@X&WrCkExc<#?~WB{M>J^brqP5O`p|_M z*thiPPq?es3v$0+&o$^)+o_;f0OjSmpoHYK=pJZWKkw&e+E zkK(qc;ai_ZfKfQaQ{bJMp_`wCY zYUXW=>0rmBggn@7eYdb)Qf)o?hJHV24-Y8tLD2+O+;hzkv?K9`*;LTBZL68L9p~Ng zTmsr@>AU=a|H=n}s~-lf0dGfK|0s0Byd-dl5rHdl4T6 zuYDA>=3(HPhyJS`_^x>1y$rMq(Q*D=OR&q$rrtD}e8Uit=An+!>$#@if5&zTmhcZ= za2K>X4awyYkLdSa2knNPbi-uwO`93FJQv*cUVP7I$$h_N5Byg=2we3bX!XO8H4j79 zJ`7#=C=9gW5WMGbPkIoFt^O_A@YrC=6NsBJN&VjI#uIP2&4KJNyyv(0Ucl1( zfy?g)uXqr$61u%GeC?x%wT~j!J&IiSICA~tC?o{hTe$9VJ5vxEbY$a#|VaT%k!AtK4F1{DA=$_w#yMFWU*iOBPypk2}1~B8g{)Br|kGw?h zH-h>47+Dys1+>W0xc|D}+&h8u?*=Zo8w}nt7`ha+!4G-6V9e@=F>4-z_6owb3nK3o zjDu|yj9L8@-49!OKV--}#wKWgdysAczKS3HPa`5yZ#x1SGZgQOa77;^fsJjfpECCagd;b2(^hT+jm0i4|xoQ+2zq z8BD>~|7BocFrIi@uNP&3tWNhevx(P}mOsc^`!Hh-Dq4-;X0CaZwf0fgIxt%QC>x3% zXRm(@VP~xeORWPb%UtsaYSik78Ayge1hdvYN?88Dbi#GCwZeLRw@e9*KO}<>>4T>n zP~z#jYBl*r&bmh>n;sW!#EA+wK8BzoJjymf)fD13r)cBjl1-1Z*FLnIbOU{n{p81~ zgvNiiUi$#rya#ItLELXS@kY_c$8|fNRd0Vv7;Sr6jRz57Lfy`11sfk*Ohk2m?@hhF z+q-TOUbYB2xM%WX_+~a;@FMTr^^dyuzii#}oDQga|BJl!k94}PA*KJT`jfHrc_GCP zCTTw9KJvzLjn1p#i|$Q1@@gXOx2sJ&^m59PSD}mUYIY)a1M2nPwwOv_1d!8*i^LEyW*RyGcW}SGw=*-*Z-Or5s5t&!F=eog^r>(n582@Kr zU4hAXmnonoPB4}={M^xy<2|nEsfB+OYat*e&aFg4pQJ>)t~eTYl8#x7xet`sk{`vd)=bvYv zenB=$Rc?FYH}8&0+Z9lnfdvjI%};z_g!>Rc^4!1e`UjVp_rQfJQXjtuv@J@x?TT^# zb=MiU6PG`jaqRW(n;#F{`E>05ms5`r=;-|~2kv~@ee>h=W3LmIKX93G%c%dla@!TP zc6fq;bUJPrOnK@u^Uls2gzH%{Jd(5V87M7*wwgn%1ChGmZHJJ(PfD#o+rTuy8=v5@3E5l(>b*|5o41kXTQxl9Jv5m77}QL{)>+d9 zZ*$TH@7vUZk=k8Xb-HnFaJmjk?UNsQ&Lg3QB_r_BwAfF*tv~6Z!K4T9Q7`21B#Pa8 zLw^$J-~fAUrZ~9KjAKD_ysh$gmq&ND5Zh6Huc^F6^s+^ z>Vr04-40oJf8t>*lPR=tEgm!5_r36$bH{4ZP4FI`hoC(?Q=b|lA%m$;!FzZf>h@f> znsmc=&YjME*!$pkY@v@-)2?S#Tc4I~290tQZ+r|vWt*Q=ZF$;4VjGM;4jx!rAR7ko zk`KVwB!V`@fc6>u|G@ycXY>GQ$IJi!pnVLWixI(l8({Z_+W&{#4a$$W$rN0;u>XhL z|Hus12EGRr;(gd%pRjvA>ml1F7+`mL+JkmNFd**lgx%vQ585rkz`y{zo0A`G4Fdx^ zy=ioJ;Bqfa9O^%~f5E}WzyRJG0^Z62+PDGQ*aV}&9%4s?C)gl)=>3@T{~-Ygx~vj* zyX*td?xg?VhyY(u`440|D59b931a^L585XJ+7^<)fVgjxK^hV%qvXg8f%x8S{$2ar zx{f$^A9wCL=G=A6t?MwIgCeJYokzz3)830VbMFW3`jm9~d*;ROxmTem^V0XE)87Mk zezci;&!qPvP2HB*v%#|SjP1f_F-N|X-2T?`8gzRcWPR`C-+!n4`8)adU(gcYUw?W& z|7v;jv*h--=)+%Z7e1xBt4b!VvFbYGu=Hi}$xk(pze4W$057@!+57od|2NQL`-$Ks z_sEOYJKlqqjMhH-nsoA${SvCx+7T1>8%@3wvHyM9olgzm%O09ug079}{P3ga)33g- zzbF3u4OztvzCa7Ic>5RV7PmLx3uC}5=gaPV3g7qMh|s7e{*YXvQ%}9E zxC^b9rMcE%vd`{-7P<{t=y$a~wDR6vsya%nC z?gQPV1zImX8NA|-SYvo`ynWzhiPKsT4 z(|!r))b;dJZ!*tM>@+xxAbF*25i-OC~zZv!4@Lm4|yio9E@^R4mwCwY5^Dn ztJde*Ctn($eQg4z>hJCEL2Jb!Ypuc87l9WigHtkSL(1c?RS!QymQ@#kmi2FTc7%G04*_cUIK2B!m|^MG3Ue^(`gS}mfZ7L@xTYX_AeB+0yg3BOK7Z} zdz*I&z5*HKs`5LawXfj&TA&Q@?JS_>i?EfVpyhKJr$IN(Bpe1`-~?V>9JmP-5gsc+ zE456fV{uaAiU$_69yl%pEeiEo1-f=6XbUu9$AT9kLYxFy&YFK2daY6M4e+AeTcEX| zrC_r7#s|<6%B!FSx49R=Ap>#@I2j)REoTbb0a`!iw;r@w)pZ$Y&7Q?9boYGx{>Ogm zEsGhTv%;MgfmTR@4k+L7IC$%mupOWkJFy2qYa^47gBC_+o`Eg0y#!ir3ce)^d}YX0 z(9&7(ts$U$$g7IHBjXmKFqs-&C?plePbBxp4$>dhsP)v%F! zKp8w3ya?Q9E$A8ymnHY?=ijxSb=wSM+-A+i_xk;}j3{IZiQJ1T3zX|@UAU*b)xa48{vykmR2r0{T6arg~{ZbmNRbK&H=X2+*Qm zP_hACRbn<3bfmam&o$@iC`&it?$PT3ExJQEX(8yI5|0&-JDk94?Y4jyJ#GgbtPfsj z_bhtvvuN0L0?~Ux%d;bQKa1G;6mp9IB*B30t^i+h17F!?HS0FWF%zMq&`zjHXyK{1 zpmlVRMMU5gXkaJZvYm4WeBljf?HQ;L057W!+62810J?T=CuntC1dI&d0d~pOCn1}k z1Z{d8xZ$zi+J|1N9=a}ru7$Rp16o%JcFcA7dK(YaD;ZXve+L>BL>i|xoNyhyM)$Tg zcsZHN;(Ol9!AIV&eH64Fw2&-h6ejfz~#gO}S|_0pS?Ep6h}0Q6|3*-1!7r)YOYIL}}Q6-DEQ8 zni>1qx4jnM^I3M^54Nx>coIB73VErf->GfVuUyX7i=gUvOEhpW;90Atvy=FG)hUdIHzKibpFS#GM?0(RS z2O+B-hOK@Wz6P{JDgwMj3bZT=d=7i$`o|IL9*3`c6t)JmI4We-!=M!p0+-$QUvl4f z(LJwucg!b)PA)?qRqjP!hxYsLKhS*)80+YCd#*XpxaBwhZotBOK}+t1EW01N;z9Vz z2NA0tMy`GswHCU@DQ4ZHnDvihV9TGP);@|{4O;0GzVboniU%Rf?guToAF%MA-~7AI zGj74Br{S*B??=h(kQ%jn{|o(zh?yhET!Z<<8zBqshAg-ny6|4ul6w)$?nkb85WVt2 z%&Ld6s~^U#0i6sU4?Y$gbQ<`&NAc@GB5`XT#jbuBv+7~=$_G&^9z-m=AGYLP=)!v; z3qeL*|!sy-;Y}cMe)n;CqUNrtOlLvodR04^C)#4 zDgp~8uX&gRI>q}z!iop+NG2pMzwa^YHe~G(G<-ldVp(_n^UuGa`FD`72GQ@i7QN(N z&f14rYcSB-N7-v1Wv>IR&&gT;2y`qp|hnOGixu!n> zy)uQw7Xt&s@^kNyqs*Z9TI%YD6f*!m=8)kEa#5U@rT#7Uoi`~fd51FebD z1D$4gHF3p*j=e8hc0Z>U>e%}tam53jZs;sCp1^@PY3ucmpn@6{r=UYWJ!apYa^%(I zBd;bMrUIIL`0h#>w|9}4a$NH0?w+`rbUoGAIWYzh1 z3s1kH9Id?Yu4MBQMBq$9DFcz6fy{pO<+uB+JCN!gvVx`ezzfLQiA`7DlZUokd%x$_ z$L{^lP5Pk=R1C1?ab#y8v(G&KYB}W&DB{3JMjH2BZ`<>H{4>37WZ{aMx-wmNF384QT8m_rI7$my{$OYg6{ z^#10n?~mXAy#4yejaQ(fIj=nbcJ&1c0*idV@#_2S*FPSA_<8fy_jQ-vM=u2(r3y(l z`V;S&ljs`M>=_OzwaA z`RB>UpBJBfn|0!K!ixL);OTX68F<}b@-`Ah=SicXnxKXG3 zs!BU(rrT=rjo<}$n|D8(bK=d?vu{^jcn3jC&c2;<;!V@;XF&_@T1~zIQ4C4I`u(@` zr#uc{OzF~&kKg}v?tf|6chdmmD$qRyy4}|_!6%R^v|LtbxvbI#nra6fNZN5lrR@qt zP_5&NChVYFeXw4`KJ-c)YX}f2c;@lfob``&yRREeeF947NDC2l!6$LUNocLqb4{=J zhW>=R22-Et^<2+ekG+#lr0uwroqYJUX8Tj8>7aAT4W~UbnDh`d-8=zQ>**s%P?9s8 z_Drw;uJerBHQNafI^nX8Nb&dI{%pJcapIwu3CkZiPrqe1<)+PKD6*S!(|P)>gyjz= z9U^DYl1K;8QyFBo40cu_GW`L3K->TSpvgK02GBGqXc7-J{|Pz(4s^5|=zuuTG%53c z1_sdiZJL&T%QG;5=M`ZzKlFS)7|jmlvokP&kEKJWnW5sO z(n#ijM=+4=0rUBx?t;dzeuL(#zW(a`_^bNazwiTJohO_k-j<@7dmI)%%Des> za%@4%E70LzyaYes#PD&m24l&1B?W{|(YIbvr>@$`_w*$8Uwx%GVj^ zKIB|@TX^k5`JGR-kH3J%_uqo2WWN0ZokI2Fci*?)-JgE8zx&bj;#=+GFBNw`6<+(0 zd+}}Nxerb&@LjQDH|Jse(GRI7US*zrlYa#?YG3`}bHlT*kRa;*^t0y+C@#Qf;($&D zX#mghl->SVa0NU@f8urg(GL#uu%C;cvhqQ|&QG!XpC=vx%~j-Hd{=z^L&e=swctak zT3&r`dkdPA0H3@DI&G@)Iq1NVihG}mZ+ytT_%8kQo5UlpV)s7}-1!OXt^k{b&w{r- z3*YrD?%<1*siRQXEqDa*W~4|f8@UQo&SbMq1&ED?|YtbN_atm}E zMm6{#3HSx?kYW1LTOSLqf(|T5JM|{<$jj)xFG9D2M#J6LzRO>a5=u7HZn>^_;=TG| z;AYSP7BTxlm$9dxev@+ne0s}u(BN|U9nf4O_#6$;yb)+N0yI?v3Yny%uVTSd5kZ@u zc&~Zry5flq>c#2iv!6OFyyv$3zVABdh=1$>kQHg*;eOCA`YZ1Xue~q24j!|<2D%0u zGG?823UtUq+<_MnyPgGa1zjTTzWjmX!h2@35EC#{kGwLQ^TK-eZO28Ru~)zKkAk;6 z0Zl6Ge~}0p!3PbkW}XF&O+#)-&N}xt^X!}SQ=qN*iAO+Jo`MYD^2BdFXtdX9(LI~l zx6S4trsZmPJTsp0%xvmS+c|ff7vJ+-`M`JGBgmjU^nioI;0xZ5gQn%+*AYWTlcV-N z58L@HXbZ^Yo-08|LfC=_n~Y~XYuE{m<%%s&4W~UdoB$d`wwrs$c?rlDklC70@Odav zd!EPa1MQ%WgA9Wn0B!M&+5TMwN zAtRm^({I^=_ei@f1D#qDu;Eeg=EtD(CU!gp-7LBbyd8JvQ_ybVZBK$XKMvUN$a~F0 z$k3|o+&dt{!9$sb(?GjcAZ11Cp67$da4yFM!(_^*B#wC+&| zWS8b<@J3VccGIv;k3%*-4qErfe>Lc?OXr1mt!9C4g9MERf(Jtlr# zsMFPZ-D=uR??re0mfjCs0lLC5bnTW2|4AA~KxAH3v#;KF;Jvq5`VA=*Jk^`VSA`^>owS~&_{xobP+X56y- z(M#^fEWIDQ{C@n(2Z^g6Carmty!H{~*0|)gkCN6tN?iRge&vJMTsw`1?~hMk}UOg!1K_jxe* zmJEZ5cdaL*1P&Zu6Sxvg3)pgBq2F@0I z;);hxGhV2*Ux{9Nf7`VW+pc|Bd+8lPwC(zbt=B$8ExD)Ge#L0Ui{zE~Mnin(KQNs3 zOtt-Tau7AAo5_B8P=|^8rJos`P37vTG<@BSkm!5sQ{_^{_>mMVR+*574Y&h+i z{{no5Ljo#b(IdkdFIC#FnoYP~x$VjBTc7T~{qg?$@6SK~eEI=GpMU;&|NZyYWCdLpYp_T>eB!s!UWA^WN!Al$97Y1>rc3AI2B|Xc$F}yt86#*b`B8>3y_VX z1sl>|04;mu|Ns90qzmzffdRCB6trd(v|bdnMijI@lpWLsf#C)Q24>L8Nn{L@gVJC< zA0TT@`9Z5-LFR&2RW>mG{|{YN3F@Z^FfcHH`YP~#3NzJxTD0VF){YxFM;_)JeUP<- zzz9g(zUQr9{!jV;e>NCR`TxK5^Z!_+>Hyh!$>;vmKKtGD;%nE(pOe5xpmu%y+4SOT z?X%y>=YAurWME(j*!DL2;>W_P?`s}?X?^`2a^!C7>+dy>z7$@2pMCLT;P!WLExDVY zL>~N_aOg$$`M0IFKGr-0wM9WEkUsoedh28M`L_v&UPK=Hn!6d=6tSCg$8Q5@7BlJS ztL*b{3$KA%u#iP0+2`LTAA1$C>zUuir*^On$>y`4IxoKGw;ptGUi=}*VP~K-Yf?_U zjz9D=eAhF-^^cqv-!q>L%~^(1pIS`6<+SLY_nL>nTR|-x$b2NI^|BSz?s8gm&tm#5 z!>LgBK<=b9opRH2@x8#+4?@>J0!@i+d>p#|QQ+zao{R69P6pjxVlWBZM`mC!pLj#3 z@3!;wTMrEXkcJCaNq#Lfjb8nKAc*{z@Xs3z@U)8z@X5;z@V^zfkEK_1B1c?$bf@`0t17C z0|SFY0t16X0|SG@0tN<$0}Kof4;UCgjz~~oU`TLaU`R+{U`S|SU`SZNz>si&fg#}m z)LsP!h6V=)hK2+N29U)K3m6z04lpn@JYZm0z`($;K!Jf_fdd1>f&>PJ1q}=g3l=ai zEI7cxu;2m2g9j8C7!EivFdRr=U^oDB_yUmQ85j;cfD8aVP+(wq;K0D}Ac2A5K?4KB zg9Qu>4-POeJa_;eFL7W{U~mA#1O^9&1_lR)1q==h2N)a}9x#Btrl7#!py0sZppd}e zpwPhJps;|!LE!*{gTe!dw;dE192^`N92^oD92^=L92^!fI5-?&aBz4436cZ_28RR( z28V~xrf(8bM1q&D)793!3SnvQ6%m)-091b`zI2=e|a5&Jw;Ba68gTsLX z3=Rh#fTO_SfdYfW0|y3&2MG)g4;mO89xPyRcyNHh;lTrFd@F!`-N2B*0FHZx1q=-g z2N)U{9xyb3qDDc1p+Uicp+O;mp+TX6p+R8*LxaKrh6aTPkZ5yIU}$h~U}$hiU}$h? zU}$hyz|i1ufT6+R0VGNj6c`#392goB5*Qj18WZFf<%UU}!kdz|e4D0Yk%q0}KrZ9)Ocj!vh6|h6fG|4G$6+8Xhz-G(1?q(D2{@ zL&Jjy;BmnN3<}`bKERLw_VodV1q=tk@BsrjX(=c$98hpzIG~Wga6qAf;ef&dh64%* z7!D{rfFwHy1%?9-4h#nz5*Q9RG%y@+Sio?=;Q+${hX;@(nV`UMAi;s*Ktck;frJKz z0|^Tl4kR34IFRrFl3W`U7!EWzFdS$|U^vjwz;K{p0mFfY0}KZm9xxmLCFKPQ3)E_Xzw{PE%0=935+Ch;G5Hq%+nGLgO`!=xrI&%F0)}4p$a+v8L8s-af zYygMM_U-tL-@hLu4{`?SegNqL=_YJG#1o`>0p$2?5aV$KJ}7whLp%VnfD|tv9FO1m zF!Lcc5bK5Sd3kwdP{$K%J~+7&m*GHR12>&$^TA#qCXCRG#~=LQ1O#(TUS1wy3($=x z!F*5{5wsvLFAwG(2n|grI4Fo37@3!sM<9|hj3*EQFq5G)Aq%h=k2ipz#v&;E7UbpS z!EzNs3yzQh2_qE2SfC;gXArH!W<0(Cf|-g$Z_CTWd5IBL=i@2ikc@>h@pu4aJZA8K zbb`VH3kFG{<83%C0Qqd&Hmnw4F&kdCp<1wQ8^{8zAp~|lcJr~OAyk8*Jc#+&aseoE zL9$SV=oE$*&=o-VAQQG>Ehj*QCRi4t5Q9Xu07Dug05$+?41mg=Jg_uGB^DB40~Se$ z5ZHh+Yy};tN`aVdB09jECF&+~7AhVD? z0OCV1L=_npKs7>40g*`N!-EG}M&Kxh2nWtKg!7S$X^?d=3=JU?eE@YmlJUq{0A@Cr zCdUG(@sL~uHU*`kgo!|Cm|}dvfhq^n0nra5;Sm68SHJ{8G)y_FA-H)^^(cXZ?0)3v z1(}~mS`gtd9udJ9=EE%@B9@`1Bc~j&8<8pjC?A=E`2a_K1`jKk=~#?MG)9pPhO^;1 z@%RCu20iRS#=uJm5C;Pze1Ove{Kg|P0EXER0fcsJp@b|8QIA2w5-5fQQ~=2f5Yr&R z4q+omY+(a7fspyI`UYVXHWt_@tOQ~6p%of7V_{;Li5qSg5#|%L0FUwT^n*uD-nw-# zhhn3#4cx$;PmKBCF(qs!gT%m+aN{r-aPv`%RTOn#Bi3Q_1WX1+ISL2S%0&@I;lND6 zumLWCq8x<-i(Uo>6k%iz+!PQ46eJJ~;=wVpdK5N6^WjDiV4#?a;2_M$nt%uxiXx3L z6v2W=F9QR%2u9IQkb^K5&O$^lMg$Nv4yyvV$q)u2cxZ1vY5-w%9T9>McSA|!;6d{M z5k_HE0yP;zAqNlb%|~tmVRai?F^63Z#N}WT)%hqMKr;%GWr-n?vk|)aNHI(e^D$Qj zgM9@dh;b`6H4xok65aU>3`jA6vq1u>-*J*)lfeY0@yIbiruj(0kIj6fQW~cV@k)SQ z4koY~&w#L>EDs=32vW(3ViVYIFoD;dI3&Ru!32t-$Q-aNnApxiB0x$W$R?t)5njwA z-+0u54b=j$+aUyL7C`iXNL+yru?VCBib)6}q`<*8GzKvmLP8A(Q^a}!tQbl_Ou<7! z)q$yX#MppH*2sNE+%|wsh7%m$@B$9FLNEijsYo&?4$8}0htmoUbd^Yk;A0{sQ?RS@ z^0r~v!GT2)J~L6}pvIz7h&l^Z9LhsAfdCK9=TIZ?Q23KQ7TfTcg+&UB0fdAw0~m|B z5Fva;0v>CK3?!0+24N);HjwFdm>t{kTConZodDBFJdMi=su&J)2AVf02y>W;LxYB| z2c`xCw9Xf54rm=PlnL3=2;o4sJ3`n$Kp`X#VS|^1Le9|zDF>f?3z7jTfo>*+o(Ky& zV;3X?)(qAPJ;a; z{HScGwP1^()`BfYW`h<}f;BV#hxiJ_VMJbag~A304oC?D1MJ*e5D$e74F!-m?Cf6* zHaK8GqKNZ=K|Ijgauj0J*e2E`U_b-G2uo;_@l%ZXh|J3 zfKcNX9`DT1^PEAdn4xDAgV?ZhilJ)=DpavCNAYrHqq9~AhP;rC^8_0YnNSu^`evo>w{Ro3V zTu2BJRyLNdQ?!7=w)gg$}3?hB*jo40M$bVMDfW zM>Yl#^)PcF4kE&9U}F&DhUo5r1T|)AM0X*YF|aBPVK8w9fsKKN4cIGC_kgNBFdsyK z72)+7Lt?Rpm3OjRWphp!U!-6W)6yfb~NOXfQLN zcnqgbGzq8~APO;t58^>Enrb{;h(!s{S7Zxgj-*ampAM>PPt zaRe-q^Yin;V>Wr~wh`?ibQ_Q|KiOuWn~9$fpMC&e9tq_U&wjuFnmd80ZvdTS3z~L; zOvKcK=Y$|rBm7V{XugFV$_CBDfX`WC01JR7AwlLqre5s9=0Mn><8T>3=i-9y>jaBK zrfNXPzk<(!WdKb!g7kun1Wh)A*pMk7(2=nW&^bm38yXz-AT>yA=qwKdNE~7<1A{#S z^gLPy2pcx-B+mdnw-$7O#WHuz=K*uGcrW1(cAn6BUF(h3< zECwAH%mAIz11CYqL?kSIf_x8SgA9^~ssXzS#y-FRng9f)CD6PdXwnbDhGZlL$azDc zvxh;+5q{nf=%6o4*S0DrP^723va!6y@ENKWHshw0eCWw7?0%TRfF>rhYfz|apd7D{eI z?1hEezYW>-AXVrFfW#0O%XtClBh{z|Ahd#5pixz*#SjWS9|V#?!pH_734@p*{V1sb zGJp?~Lc$0GkOVeLSR`8JxBsz1yI++%K?a9FbS4NQjf+2NyBx+ z%R;bDC;^H^^qc@Q1f(03a-mAG>W584!1N$!h;DdTfenE~Aead!ATGd&2Z(lL$78o2 zH17vd3nD?*gJ>v*TLNWZvmey}s743{)rFvN=!XRYL>HVy=!3Cv=|>u_hU!(`z!v)HWz1z3LM%kfBAFLHZKz)EbqK=IXwFjaHnS|y70$bo9 zw&Wp)J=_qe9LgX%suQ4gz!ng|bwU_0S;*u7s?KlUz9FUtVEGQB4T*%h0J=X7G!uX{ zB>;gKilB(V!a$ zV0(99`*!Rh!|$LyI^Z!<*!~K3#O?*qz$9qk9^x&~HEJLhY;R3HWZ0AewxQ=7cbgBs~16p+pGXEQl2cp5sQ3;SR z6oZsA{D-6mkPxauI1eNR#$fgE)tYd5Oa@prB={K^U>?9!1{Xn54|Nb+5*q`o0pc9k zky7{uQ6OG~sfUCRotM-HYO<^xdL#eq?r!vGCZoH-tH<_p4j1_p?WaE$U`0jda@f*O>Uw{F{Z zkWaR6hp#3Cr(CrsDqH$4Toxn1T{nDG|lf*hmOCopvMx7KiW?n?Wd0RQ%C!$u=0RB8q$cv zwfqNu(-PLsAY2yIr@&AF?(%_TAQ-f!1G)Nx^r|3oAQIGC$wyKE>2!f)AQ&W%)HMV5 zCy}~{U}=OK)@_HiXpnSo-@a`-)CQzZ6i5M7H@qjbE+2cRW?LD=iQoxbm?i`bp1B6a z1E~5&Z|#HoWsn&`&?+NP10SIi!~*Ni19c`Lts+qS93&3Guzn6`Mjt8j$-epwf_5CrAyb)d8YG7}T5vDFD$RJ_y77hdBugl7%#+!7Pv_ zR16jd=?4YCx@{0inEC70fxHFsK4i8NOB)&FNRW0028Mi;ZZjl^w&#IE53FKcejdg& z*Sb7N?12@4x*(|YPe`VNRIJMf%`rjtuzceHHO`Q9gA{qgZbb(5>m55 z_@F^7NTUbLhtxq}0S1O``C!+9YovUTlk(PcfER0UaIA+6QsjX~3phA9;A7+K^44$P Vz8-n4==OE6zBp(j3nlky0|0)vb(8=A literal 0 HcmV?d00001 diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.png b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.png new file mode 100644 index 0000000000000000000000000000000000000000..7e8ccba0ee332bb37b2c047bdf5d5513d9412474 GIT binary patch literal 7668 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 J%Q~loCIDEZvHk!6 literal 0 HcmV?d00001 diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.rc b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.rc new file mode 100644 index 000000000..d60d3136d --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.rc @@ -0,0 +1,72 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource1.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource1.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "Jooleem.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.sln b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.sln new file mode 100644 index 000000000..7276559f1 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Jooleem", "Jooleem.vcproj", "{BF0C4EBF-38B1-47E4-A576-1CF34F82C283}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {BF0C4EBF-38B1-47E4-A576-1CF34F82C283}.Debug.ActiveCfg = Debug|Win32 + {BF0C4EBF-38B1-47E4-A576-1CF34F82C283}.Debug.Build.0 = Debug|Win32 + {BF0C4EBF-38B1-47E4-A576-1CF34F82C283}.Release.ActiveCfg = Release|Win32 + {BF0C4EBF-38B1-47E4-A576-1CF34F82C283}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.vcproj b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.vcproj new file mode 100644 index 000000000..d3b20879e --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/Jooleem.vcproj @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/changelog.txt b/alienblaster/project/jni/application/jooleem_0.1.4/changelog.txt new file mode 100644 index 000000000..0e03cdf01 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/changelog.txt @@ -0,0 +1,170 @@ +Jooleem changelog +================= + +Changes relevant to developers are marked with * +Changes relevant to users are marked with ** + +0.1.0 (Beta 1) [2005-08-08] +** First public release + +0.1.1 +[2005-08-08] +* Added PushUserEvent() to event.h +** Clicking a selected marble deselects it +** Executable installer +** Added link to website in the about window +** Fixed button behavior when clicking and dragging +----- + +0.1.2 +[2005-08-27] +** All new original sound effects by Dale North +** All new music track by Ryan Reilly +** When completing a rectangle, the points earned are shown +** Improved sound and music support +** Improved resource loading +** Minor fixes so the game compiles on OS X (GCC 4.0) +** Browser can now be launched on OS X +** Exceptions are shown in an OS specific message dialog + + +[2005-08-09] +* Fixed Level messages during game + +[2005-08-10] +* Add redraw to label's text change, button's align etc +* Add to events.h - MakeUserEvent(&event, EVENT_CODE) + +[2005-08-11] +** Minor fixes so it compiles on OS X (GCC 4.0) + +[2005-08-12] +** Browser can now be launched on OS X + +[2005-08-13] +** Exceptions are shown in an OS specific message dialog, and not in stderr +* Switched from strstream (deprecated) to sstream in trap.h + +[2005-08-14] +* Added support for data fields to PushUserEvent +* Revised about window's layout + +[2005-08-15] +* Renamed events: EVENT_SCORE -> EVENT_RECT_COMPLETE, EVENT_GAMEOVER -> EVENT_GAME_OVER, EVENT_LEVELOVER -> EVENT_NEW_LEVEL, EVENT_HISCORES -> EVENT_HIGH_SCORES +* Added CoordToPixels(), PixelsToCoord() and CoordToSDLRect() to Board +* On rectangle completion, the rectangle's screen location is pushed as data for EVENT_RECT_COMPLETE +** When completing a rectangle, the points earned are shown +* Added TextEffect and EffectManager classes +** Fixed: Two or more sounds can now play simultaneously + +[2005-08-19] +* Added HandleUserEvents() to IntroState, GameOnState, gets called from HandleEvents +* Renamed: ChunkManager -> SoundManager +* Added events: EVENT_SELECTION_ADD, EVENT_SELECTION_CANCEL, EVENT_SELECTION_INVALID + +[2005-08-20] +** The game can now handle music +* Added MusicManager class +* Added events: EVENT_TRACK_OVER +* Added folder: data/music +* Renamed folder: data/tiles -> data/marbles +* Added music loading and playing to various classes +* Removed Mix_Chunk member from all game classes (not UI), replaced with SoundManager::PlaySound() + +[2005-08-24] +** All new original sound effects by Dale North +* Added Engine::LoadSounds() + + +[2005-08-26] +** Improved resource loading +* Replaced Engine::LoadSounds() with Engine::LoadResources() +* Moved all resource loading to Engine::LoadResources() +* Add Engine::InitStates() +* Added common/filenames.h - contains all resource file names +* Fixed Trap macro +* Removed AddResources() from all windows +* Changed all reference to "tiles" to "marbles" +* Added SetVolume() to music and sound manager + +[2005-08-27] +** All new music track by Ryan Reilly + +--- + +0.1.3 +[2005-08-27] +* Fixed - music now loops properly in game mode + +--- + +0.1.4 +[2005-09-25] +New features: +* New Music track by Ryan Reily +* 4 new sound effects by Dale North +* When time is low, the time bar begins to flash and an alarm is sounded +* Pressing F12 takes a screenshot +* Upgraded to SDL 1.2.9 +Fixes: +* When right clicking, the marble deselect sound is only played if any marbles are actually selected +* Fixed sound corruption issue that appeared on some systems (thanks to Malte Thiesen) + + +[2005-08-28] +** Upgraded to SDL 1.2.9 +* Moved Blit from Font to SurfaceManager +* SoundManager assigns a channel to each new sound, and keeps track of it +* Added SoundManager::StopSound() +* Added events: EVENT_TIME_LOW, EVENT_TIME_OK +** Fixed: When right clicking, the marble deselect sound is only played if marbles are selected + +[2005-08-30] +* Fixed TextEffect::Update so transparency will not underflow and make the effects opaque again +* Minor compile-pleasing warning-stomping + +[2005-08-31] +* Minor fixes so it compiles on linux (case sensitivy, files end with a newline). Thanks to Jani Huhtanen. + +[2005-09-01] +* Removed FULLSCREEN flag +* Changed post-increment to pre-increment for all loops (i++ to ++i) +* Moved all board related consts from common.h to board.h +* Converted sound effect files from WAV to Ogg + +[2005-09-02] +** Fixed: The computer can keep playing indefinitely in the intro demo (thanks to mein@stare.nl) + +[2005-09-03] +* Added UIProgressBar class +* Added SoundManager::StopAll() +** When time is low, the time bar begins to flash and an alert is sounded +* When restarting via the Game Over window, the music is restarted as well +* Changed audio buffer size to 2048, this may fix audio corruption +* Added DEFAULT_VOLUME to SoundManager and MusicManager +* Added Engine::GetMute() + +[2005-09-04] +* Added visibility array to Board (bool m_isVisible[][]) + +[2005-09-05] +* Added new music track (track_01.ogg) + +[2005-09-08] +* Added ScreenShot() to common.h +** Pressing F12 takes a screenshot +* Added EffectManager::AddGameOverEffect() + +[2005-09-10] +* Added __FILE__ and __LINE__ to TRAP + +[2005-10-10] +* Added game over effect to GameOverState::Enter +* Removed font objects from EffectManager, they are now loaded into the font manager +* Fixed in Engine::InitSDL(): Allocated audio channels to required number of effects +* Added Board::DropRectLogic, Board::ChangeVisibility, Board::RenderDroppingRect +* Added marble dropping effect to Board, currently diabled. define MARBLE_DROP to try it out + +[2005-10-11] +* UIButton no longer contains a Mix_chunk, and uses the sound manager to play the click sound +* Added SoundManager::SetVolume(string, float) - set a sample's volume diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/gpl.txt b/alienblaster/project/jni/application/jooleem_0.1.4/gpl.txt new file mode 100644 index 000000000..b8602677e --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/gpl.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/makefile b/alienblaster/project/jni/application/jooleem_0.1.4/makefile new file mode 100644 index 000000000..3f4cbabf5 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/makefile @@ -0,0 +1,3 @@ +SRCS=$(shell find . -type f -name "*.cpp") +jooleem: $(SRCS) makefile + g++ -o $@ `sdl-config --cflags` $(SRCS) `sdl-config --libs` -lSDL_mixer -lSDL_ttf -lSDL_image diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/readme.txt b/alienblaster/project/jni/application/jooleem_0.1.4/readme.txt new file mode 100644 index 000000000..ffbbb8e58 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/readme.txt @@ -0,0 +1,78 @@ +Jooleem 0.1.3+ +============= + +http://jooleem.sourceforge.net/ + + +== Introduction == + Jooleem is a simple yet extremely addictive puzzle game. There is only one +rule: click on four marbles of the same color that form a rectangle. Time is +constantly running out, but you can earn time (and points) by forming +rectangles. The larger the rectangle, the more time and points are won. + Jooleem is free and open source software. + +== Controls == +Left click - Selects a marble. Selecting an already selected marble deselects it. +Right click - Deselects the currently selected marbles. +P - Pauses the game. +H - Hint. +F12 - Takes a screenshot. The file can be found in the "data/screenshot" folder. +Esc - Quits the game. + +== Tips == +* When stuck, click the hint button. But beware - you will pay a time penalty. +* Fill up the time bar to advance to the next level. The higher the level, the +more points you get per marble. +* The higher the level, the tougher the game. You earn less and less time per +marble as the game progresses. + +== License == + Jooleem is free and open source software. The code is released under the GNU +General Public License. The full license can be found in GPL.txt in the game's +folder. + All of the game's assets (music, sound effects, images) are original and +released under a Creative Commons deed. The relevant deed can by found at http://creativecommons.org/licenses/by-nc/2.5/. + +== Development == + Jooleem is developed using C++ and SDL, with cross platform compatibility in +mind. Currently, Windows and Linux versions of the game are available for +download. Mac OS X and RISC OS ports are planned. + You can follow the development process, submit bug reports and make feature +requests on the game's project page - http://sourceforge.net/projects/jooleem/. + +== Credits == +Project lead, code & graphics: Chai Braudo (braudo@users.sourceforge.net) +Music: Ryan Reilly (http://www.allacrost.org/) +Sound design: Dale North (http://www.dalenorth.com/northmedia) +Linux port: Jani Huhtanen +Beta testing: Iddo Braudo, Uri Grupel, Shany Tcshernichov and Ma'ayan Zigdon +The game was inspired by Nick Kouvaris' ZNAX +(http://www.freestuff.gr/lightforce/znax.php) + +== Changelog == + +0.1.3 +[2005-08-27] +* Fixed - music now loops properly in game mode + +0.1.2 +[2005-08-27] +* All new original sound effects by Dale North +* All new music track by Ryan Reilly +* When completing a rectangle, the points earned are shown +* Improved sound and music support +* Improved resource loading +* Minor fixes so the game compiles on OS X (GCC 4.0) +* Browser can now be launched on OS X +* Exceptions are shown in an OS specific message dialog + +0.1.1 [2005-08-08] +* Clicking a selected marble deselects it +* Executable installer +* Added link to website in the about window +* Fixed button behavior when clicking and dragging + +0.1.0 [2005-08-07] +* First public release + +[2005-08-27] diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/resource1.h b/alienblaster/project/jni/application/jooleem_0.1.4/resource1.h new file mode 100644 index 000000000..84e8a5eed --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/resource1.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Jooleem.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 204 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 201 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.cpp new file mode 100644 index 000000000..655ad8646 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.cpp @@ -0,0 +1,141 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/aboutwindow.h" +#include "../common/trap.h" +#include "../common/events.h" +#include "../common/common.h" + +#include "../common/surfacemanager.h" +#include "../common/fontmanager.h" +#include "../common/soundmanager.h" + +#include "../UI/uibutton.h" +#include "../UI/uilabel.h" +#include "../UI/uitextbox.h" + + +AboutWindow::AboutWindow(SDL_Surface *background): +UIWindow(background) +{ + InitControls(); +} + +AboutWindow::~AboutWindow() +{ + +} + + +// Initializes the window's controls, and adds them to the +// control collection +void AboutWindow::InitControls() +{ + SurfaceManager *surfaceMgr = SurfaceManager::GetInstance(); + FontManager *fontMgr = FontManager::GetInstance(); + SoundManager *sndMgr = SoundManager::GetInstance(); + + { + /////// Buttons /////// + SDL_Color buttonTextColor = {0, 0, 0, 0}; + + // Link: + // This is an unusual button. To simulate the graphical beahvior of a HTML link + // as viewed in a web broweser, the text is rendered several times (normal, hover, + // click) and these surfaces are passed to the button *as surfaces*. The button + // itself has no text. + SDL_Color linkNormalColor = {66, 128, 221, 0}; + SDL_Color linkHoverColor = {75, 147, 255, 0}; + SDL_Color linkClickColor = {131, 194, 255, 0}; + Font *linkFont = fontMgr->GetFont("LinkFont"); + linkFont->SetStyle(Font::STYLE_UNDERLINE); // Make the font underline + SDL_Surface *linkNormalSurface = surfaceMgr->AddSurface("LinkNormal", + linkFont->RenderPlain(Font::ALN_LEFT, linkNormalColor, APP_URL)); + SDL_Surface *linkHoverSurface = surfaceMgr->AddSurface("LinkHover", + linkFont->RenderPlain(Font::ALN_LEFT, linkHoverColor, APP_URL)); + SDL_Surface *linkClickSurface = surfaceMgr->AddSurface("LinkClick", + linkFont->RenderPlain(Font::ALN_LEFT, linkClickColor, APP_URL)); + + UIButton *linkButton = new UIButton(); + linkButton->Set(0, 0, "ButtonClick", + linkNormalSurface, linkNormalSurface, linkHoverSurface, linkClickSurface, + linkNormalSurface, NULL); + linkButton->AddState(EVENT_WEBSITE, fontMgr->GetFont("MediumButtonFont"), " ", buttonTextColor); + linkButton->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 241); + linkButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_LINK, linkButton); + + // Close: + UIButton *closeButton = new UIButton(); + closeButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + closeButton->AddState(EVENT_CLOSE, fontMgr->GetFont("MediumButtonFont"), "Close", buttonTextColor); + closeButton->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 355); + closeButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_CLOSE, closeButton); + + /////// Labels /////// + SDL_Color titleColor = {64, 64, 64, 0}; + SDL_Color labelTextColor = {0, 0, 0, 0}; + + // Title: + UILabel *titleLabel = new UILabel(); + titleLabel->Set(0, 0, NULL, fontMgr->GetFont("WindowTitleFont"), titleColor); + titleLabel->SetText(UIControl::HALN_LEFT, "About"); + titleLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_TOP, 320, 125); + AddControl(LBL_TITLE, titleLabel); + + // Logo: + UILabel *logoLabel = new UILabel(); + logoLabel->Set(0, 0, surfaceMgr->GetSurface("Logo"), NULL, labelTextColor); + logoLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_TOP, 320, 153); + AddControl(LBL_LOGO, logoLabel); + + // Application name and version: + UILabel *appVersionLabel = new UILabel(); + appVersionLabel->Set(0, 0, NULL, fontMgr->GetFont("AppVersionFont"), labelTextColor); + appVersionLabel->SetText(UIControl::HALN_LEFT, "%s %s", APP_NAME.c_str(), APP_VERSION.c_str()); + appVersionLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 219); + AddControl(LBL_APP, appVersionLabel); + + // Credits: + UILabel *creditsLabel = new UILabel(); + creditsLabel->Set(0, 0, NULL, fontMgr->GetFont("CreditsFont"), labelTextColor); + creditsLabel->SetText( UIControl::HALN_CENTER, + "Developed by Chai Braudo\n" + "Music by Ryan Reilly\n" + "Sound design by Dale North"); + creditsLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 289); + AddControl(LBL_CREDITS, creditsLabel); + + // License: + UILabel *licenseLabel = new UILabel(); + licenseLabel->Set(0, 0, NULL, fontMgr->GetFont("LicenseFont"), labelTextColor); + licenseLabel->SetText( UIControl::HALN_LEFT, + "This program is free, open source software\n" + "released under the GNU General Public License."); + licenseLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 318); + AddControl(LBL_LICENSE, licenseLabel); + + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.h new file mode 100644 index 000000000..ca7d1883f --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/aboutwindow.h @@ -0,0 +1,55 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ABOUTWINDOW_H_ +#define _ABOUTWINDOW_H_ + +// The about window. + +#include "../UI/uiwindow.h" +#include "SDL.h" + +class AboutWindow: public UIWindow +{ + public: + + enum Controls { + // Buttons: + BTN_LINK, // Website link + BTN_CLOSE, // Close + + // Labels: + LBL_TITLE, // Window title + LBL_LOGO, // Logo + LBL_APP, // Application name and version + LBL_CREDITS, // Game credits + LBL_LICENSE, // License info + }; + + // Constructor / destructor: + AboutWindow(SDL_Surface *background); + ~AboutWindow(); + + private: + void InitControls(); // Initializes the window's controls, and adds them to the control collection +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.cpp new file mode 100644 index 000000000..5a9878861 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.cpp @@ -0,0 +1,152 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/gameoverwindow.h" +#include "../common/trap.h" +#include "../common/events.h" + +#include "../common/surfacemanager.h" +#include "../common/fontmanager.h" +#include "../common/soundmanager.h" + +#include "../UI/uibutton.h" +#include "../UI/uilabel.h" +#include "../UI/uitextbox.h" + +#include "../game/highscores.h" + + +GameOverWindow::GameOverWindow(SDL_Surface *background): +UIWindow(background) +{ + InitControls(); +} + +GameOverWindow::~GameOverWindow() +{ + +} + + +// Initializes the window's controls, and adds them to the +// control collection +void GameOverWindow::InitControls() +{ + SurfaceManager *surfaceMgr = SurfaceManager::GetInstance(); + FontManager *fontMgr = FontManager::GetInstance(); + SoundManager *sndMgr = SoundManager::GetInstance(); + + { + /////// Buttons /////// + SDL_Color buttonTextColor = {0, 0, 0, 0}; + + // OK: + UIButton *okButton = new UIButton(); + okButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + okButton->AddState(EVENT_CLOSE, fontMgr->GetFont("MediumButtonFont"), "OK", buttonTextColor); + okButton->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 373); + okButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_OK, okButton); + + // Quit: + UIButton *quitButton = new UIButton(); + quitButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + SDL_Event event; + event.type = SDL_QUIT; + quitButton->AddState(event, fontMgr->GetFont("MediumButtonFont"), "Quit", buttonTextColor); + quitButton->Align(UIControl::HALN_RIGHT, UIControl::VALN_BOTTOM, 435, 373); + quitButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_QUIT, quitButton); + + // Restart: + UIButton *restartButton = new UIButton(); + restartButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + restartButton->AddState(EVENT_RESTART, fontMgr->GetFont("MediumButtonFont"), "Restart", buttonTextColor); + restartButton->Align(UIControl::HALN_LEFT, UIControl::VALN_BOTTOM, 205, 373); + restartButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_RESTART, restartButton); + + /////// Labels /////// + SDL_Color titleColor = {64, 64, 64, 0}; + SDL_Color labelTextColor = {0, 0, 0, 0}; + + // Title: + UILabel *titleLabel = new UILabel(); + titleLabel->Set(0, 0, NULL, fontMgr->GetFont("WindowTitleFont"), titleColor); + titleLabel->SetText(UIControl::HALN_LEFT, "Game Over"); + titleLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_TOP, 320, 108); + AddControl(LBL_TITLE, titleLabel); + + // Congratulations message: + UILabel *congratsLabel = new UILabel(); + congratsLabel->Set(0, 0, NULL, fontMgr->GetFont("GameOverCongratsFont"), labelTextColor); + congratsLabel->SetText(UIControl::HALN_LEFT, + "Congratulations, you got a\n" + "high score!\n" + "Please enter your name."); + congratsLabel->Align(UIControl::HALN_LEFT, UIControl::VALN_TOP, 204, 133); + AddControl(LBL_CONGRATS, congratsLabel); + + // Final score: + UILabel *scoreLabel = new UILabel(); + scoreLabel->Set(0, 0, NULL, fontMgr->GetFont("GameOverScoreFont"), labelTextColor); + AddControl(LBL_SCORE, scoreLabel); + + // Statistics description: + UILabel *statsDescLabel = new UILabel(); + statsDescLabel->Set(0, 0, NULL, fontMgr->GetFont("GameOverStatsFont"), labelTextColor); + statsDescLabel->SetText(UIControl::HALN_LEFT, + "Level reached:\n" + "Total game time:\n" + "Marbles cleared:\n" + "Rectangles cleared:\n" + "Avg. rectangle size:\n" + "Best move:\n" + "Perfect moves:"); + statsDescLabel->Align(UIControl::HALN_LEFT, UIControl::VALN_BOTTOM, + 203, 337); + AddControl(LBL_STATS_DESC, statsDescLabel); + + // Statistics values: + UILabel *statsValLabel = new UILabel(); + statsValLabel->Set(0, 0, NULL, fontMgr->GetFont("GameOverStatsFont"), labelTextColor); + AddControl(LBL_STATS_VAL, statsValLabel); + + // Text box: + UITextBox *textBox = new UITextBox(); + textBox->Set(205, 188, + 16, 6, + surfaceMgr->GetSurface("TextBoxBackground"), + surfaceMgr->GetSurface("TextBoxCursor"), + fontMgr->GetFont("TextBoxFont"), + titleColor); + AddControl(TXT_NAME, textBox); + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.h new file mode 100644 index 000000000..d1afcf956 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/gameoverwindow.h @@ -0,0 +1,60 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _GAMEOVERWINDOW_H_ +#define _GAMEOVERWINDOW_H_ + +// This window is displayed when the game is over. +// It shows the final score and various game statitics. + +#include "../UI/uiwindow.h" +#include "SDL.h" + +class GameOverWindow: public UIWindow +{ + public: + + enum Controls { + // Buttons: + BTN_OK, // OK + BTN_QUIT, // Quit + BTN_RESTART, // Restart + + // Labels: + LBL_TITLE, // Window title + LBL_CONGRATS, // Congratulations message + LBL_SCORE, // Final score + LBL_STATS_DESC, // Statistics description + LBL_STATS_VAL, // Statistics values + + // Text box: + TXT_NAME, // Enter the player's name + }; + + // Constructor / destructor: + GameOverWindow(SDL_Surface *background); + ~GameOverWindow(); + + private: + void InitControls(); // Initializes the window's controls, and adds them to the control collection +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.cpp new file mode 100644 index 000000000..912ff84d6 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.cpp @@ -0,0 +1,152 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/highscoreswindow.h" +#include "../common/trap.h" +#include "../common/events.h" + +#include "../common/surfacemanager.h" +#include "../common/fontmanager.h" +#include "../common/soundmanager.h" + +#include "../UI/uibutton.h" +#include "../UI/uilabel.h" + +#include "../game/highscores.h" + + +HighScoresWindow::HighScoresWindow(SDL_Surface *background): +UIWindow(background) +{ + InitControls(); +} + +HighScoresWindow::~HighScoresWindow() +{ + +} + + +// Initializes the window's controls, and adds them to the +// control collection +void HighScoresWindow::InitControls() +{ + SurfaceManager *surfaceMgr = SurfaceManager::GetInstance(); + FontManager *fontMgr = FontManager::GetInstance(); + SoundManager *sndMgr = SoundManager::GetInstance(); + + { + /////// Buttons /////// + SDL_Color buttonTextColor = {0, 0, 0, 0}; + + // Close: + UIButton *closeButton = new UIButton(); + closeButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + closeButton->AddState(EVENT_CLOSE, fontMgr->GetFont("MediumButtonFont"), "Close", buttonTextColor); + closeButton->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 375); + closeButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_CLOSE, closeButton); + + // Restart: + UIButton *restartButton = new UIButton(); + restartButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + restartButton->AddState(EVENT_RESTART, fontMgr->GetFont("MediumButtonFont"), "Restart", buttonTextColor); + restartButton->Align(UIControl::HALN_LEFT, UIControl::VALN_BOTTOM, + m_x + 29, m_y + m_h - 34); + restartButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_RESTART, restartButton); + + // Quit: + UIButton *quitButton = new UIButton(); + quitButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + SDL_Event event; + event.type = SDL_QUIT; + quitButton->AddState(event, fontMgr->GetFont("MediumButtonFont"), "Quit", buttonTextColor); + quitButton->Align(UIControl::HALN_RIGHT, UIControl::VALN_BOTTOM, + m_x + m_w - 40 + 13, m_y + m_h - 34); + quitButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_QUIT, quitButton); + + + /////// Vectors /////// + SDL_Color tableTextColor = {0, 0, 0, 0}; + + vector indexVec; // Index + vector namesVec; // Names + vector scoresVec; // Scores + + for (Uint16 i = 0 ; i < NUM_OF_HIGH_SCORES ; ++i) + { + // Index: + UILabel *index = new UILabel(); + + index->Set(0, 0, NULL, fontMgr->GetFont("HighScoresFont"), tableTextColor); + index->SetText(UIControl::HALN_LEFT, "%d", i + 1); + index->Align(UIControl::HALN_LEFT, UIControl::VALN_TOP, 207, 136 + 20 * i); + + indexVec.push_back(index); + + + // Names: + UILabel *name = new UILabel(); + + name->Set(0, 0, NULL, fontMgr->GetFont("HighScoresFont"), tableTextColor); + name->SetText(UIControl::HALN_LEFT, "-"); + name->Align(UIControl::HALN_LEFT, UIControl::VALN_TOP, 233, 136 + 20 * i); + + namesVec.push_back(name); + + + // Scores: + UILabel *score = new UILabel(); + + score->Set(0, 0, NULL, fontMgr->GetFont("HighScoresFont"), tableTextColor); + score->SetText(UIControl::HALN_LEFT, "-"); + score->Align(UIControl::HALN_RIGHT, UIControl::VALN_TOP, 435, 136 + 20 * i); + + scoresVec.push_back(score); + } + + AddControlVector(VEC_INDEX, indexVec); + AddControlVector(VEC_NAMES, namesVec); + AddControlVector(VEC_SCORES, scoresVec); + + /////// Labels /////// + SDL_Color titleColor = {64, 64, 64, 0}; + + // Title: + UILabel *titleLabel = new UILabel(); + titleLabel->Set(0, 0, NULL, fontMgr->GetFont("WindowTitleFont"), titleColor); + titleLabel->SetText(UIControl::HALN_LEFT, "High Scores"); + titleLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_TOP, 320, 106); + AddControl(LBL_TITLE, titleLabel); + + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.h new file mode 100644 index 000000000..91f1c1916 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/highscoreswindow.h @@ -0,0 +1,57 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _HIGHSCORESWINDOW_H_ +#define _HIGHSCORESWINDOW_H_ + +// The high scores window. + +#include "../UI/uiwindow.h" +#include "SDL.h" + +class HighScoresWindow: public UIWindow +{ + public: + + enum Controls { + // Buttons: + BTN_CLOSE, // Close + BTN_RESTART, // Restart + BTN_QUIT, // Quit + + // Vectors (the names and scores are a vector of labels): + VEC_INDEX, // Scores index (1st place, 2nd...) + VEC_NAMES, // Player names + VEC_SCORES, // Scores + + // Labels: + LBL_TITLE, // Window title + }; + + // Constructor / destructor: + HighScoresWindow(SDL_Surface *background); + ~HighScoresWindow(); + + private: + void InitControls(); // Initializes the window's controls, and adds them to the control collection +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.cpp new file mode 100644 index 000000000..6ab560255 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.cpp @@ -0,0 +1,172 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/mainwindow.h" +#include "../common/trap.h" +#include "../common/events.h" + +#include "../common/surfacemanager.h" +#include "../common/fontmanager.h" +#include "../common/soundmanager.h" + +#include "../UI/uibutton.h" +#include "../UI/uilabel.h" +#include "../UI/uiprogress.h" + + +MainWindow::MainWindow(SDL_Surface *background): +UIWindow(background) +{ + InitControls(); +} + +MainWindow::~MainWindow() +{ + +} + + +// Initializes the window's controls, and adds them to the +// control collection +void MainWindow::InitControls() +{ + SurfaceManager *surfaceMgr = SurfaceManager::GetInstance(); + FontManager *fontMgr = FontManager::GetInstance(); + SoundManager *sndMgr = SoundManager::GetInstance(); + + { + /////// Buttons /////// + SDL_Color buttonTextColor = {0, 0, 0, 0}; + SDL_Event event; + + // Start / restart: + UIButton *startButton = new UIButton(); + startButton->Set(20, 344, "ButtonClick", + surfaceMgr->GetSurface("LargeButtonNormal"), surfaceMgr->GetSurface("LargeButtonDisabled"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonClicked"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonMask")); + startButton->AddState(EVENT_START, fontMgr->GetFont("LargeButtonFont"), "Start", buttonTextColor); + startButton->AddState(EVENT_RESTART, fontMgr->GetFont("LargeButtonFont"), "Restart", buttonTextColor); + startButton->SetState(EVENT_START); + startButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_START, startButton); + + // Pause / resume: + UIButton *pauseButton = new UIButton(); + pauseButton->Set(20, 276, "ButtonClick", + surfaceMgr->GetSurface("LargeButtonNormal"), surfaceMgr->GetSurface("LargeButtonDisabled"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonClicked"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonMask")); + pauseButton->AddState(EVENT_PAUSE, fontMgr->GetFont("LargeButtonFont"), "Pause", buttonTextColor); + pauseButton->AddState(EVENT_RESUME, fontMgr->GetFont("LargeButtonFont"), "Resume", buttonTextColor); + pauseButton->SetState(EVENT_PAUSE); + pauseButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_PAUSE, pauseButton); + + // Quit: + UIButton *quitButton = new UIButton(); + quitButton->Set(20, 412, "ButtonClick", + surfaceMgr->GetSurface("LargeButtonNormal"), surfaceMgr->GetSurface("LargeButtonDisabled"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonClicked"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonMask")); + event.type = SDL_QUIT; + quitButton->AddState(event, fontMgr->GetFont("LargeButtonFont"), "Quit", buttonTextColor); + quitButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_QUIT, quitButton); + + // Hint: + UIButton *hintButton = new UIButton(); + hintButton->Set(20, 208, "ButtonClick", + surfaceMgr->GetSurface("LargeButtonNormal"), surfaceMgr->GetSurface("LargeButtonDisabled"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonClicked"), + surfaceMgr->GetSurface("LargeButtonHover"), surfaceMgr->GetSurface("LargeButtonMask")); + hintButton->AddState(EVENT_HINT, fontMgr->GetFont("LargeButtonFont"), "Hint", buttonTextColor); + hintButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_HINT, hintButton); + + + // Mute / unmute: + UIButton *muteButton = new UIButton(); + muteButton->Set(20, 140, "ButtonClick", + surfaceMgr->GetSurface("SmallButtonNormal"), surfaceMgr->GetSurface("SmallButtonDisabled"), + surfaceMgr->GetSurface("SmallButtonHover"), surfaceMgr->GetSurface("SmallButtonClicked"), + surfaceMgr->GetSurface("SmallButtonHover"), surfaceMgr->GetSurface("SmallButtonMask")); + muteButton->AddState(EVENT_MUTE, surfaceMgr->GetSurface("MuteButton"), + fontMgr->GetFont("TooltipFont"), "Mute"); + muteButton->AddState(EVENT_UNMUTE, surfaceMgr->GetSurface("UnmuteButton"), + fontMgr->GetFont("TooltipFont"), "Unmute"); + muteButton->SetState(EVENT_MUTE); + muteButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_MUTE, muteButton); + + // About: + UIButton *aboutButton = new UIButton(); + aboutButton->Set(120, 140, "ButtonClick", + surfaceMgr->GetSurface("SmallButtonNormal"), surfaceMgr->GetSurface("SmallButtonDisabled"), + surfaceMgr->GetSurface("SmallButtonHover"), surfaceMgr->GetSurface("SmallButtonClicked"), + surfaceMgr->GetSurface("SmallButtonHover"), surfaceMgr->GetSurface("SmallButtonMask")); + aboutButton->AddState(EVENT_ABOUT, surfaceMgr->GetSurface("AboutButton"), + fontMgr->GetFont("TooltipFont"), "About"); + aboutButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_ABOUT, aboutButton); + + // High scores: + UIButton *hiscoreButton = new UIButton(); + hiscoreButton->Set(70, 140, "ButtonClick", + surfaceMgr->GetSurface("SmallButtonNormal"), surfaceMgr->GetSurface("SmallButtonDisabled"), + surfaceMgr->GetSurface("SmallButtonHover"), surfaceMgr->GetSurface("SmallButtonClicked"), + surfaceMgr->GetSurface("SmallButtonHover"), surfaceMgr->GetSurface("SmallButtonMask")); + hiscoreButton->AddState(EVENT_HIGH_SCORES, surfaceMgr->GetSurface("HighScoresButton"), + fontMgr->GetFont("TooltipFont"), "High Scores"); + hiscoreButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_HISCORES, hiscoreButton); + + + /////// Labels /////// + SDL_Color scoreTextColor = {64, 64, 64, 0}; + + // Score: + UILabel *scoreLabel = new UILabel(); + scoreLabel->Set(20, 70, surfaceMgr->GetSurface("ScoreLabel"), fontMgr->GetFont("ScoreFont"), + scoreTextColor); + AddControl(LBL_SCORE, scoreLabel); + + // Level: + UILabel *levelLabel = new UILabel(); + levelLabel->Set(20, 55, NULL, fontMgr->GetFont("LevelFont"), + scoreTextColor); + AddControl(LBL_LEVEL, levelLabel); + + /* + // Time bar: + UILabel *timeBarLabel = new UILabel(); + timeBarLabel->Set(192, 454, surfaceMgr->GetSurface("TimeBar"), NULL, scoreTextColor); + AddControl(LBL_TIMEBAR, timeBarLabel); + */ + + /////// Progress bar /////// + UIProgressBar *timeBar = new UIProgressBar(); + timeBar->Set(192, 454, NULL, surfaceMgr->GetSurface("TimeBar"), surfaceMgr->GetSurface("TimeBarFlash"), + surfaceMgr->GetSurface("TimeBarPaused")); + AddControl(PRG_TIMEBAR, timeBar); + + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.h new file mode 100644 index 000000000..c9ad3dad7 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/mainwindow.h @@ -0,0 +1,65 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _MAINWINDOW_H_ +#define _MAINWINDOW_H_ + +// The main window. + +#include "../UI/uiwindow.h" +#include "SDL.h" + +class MainWindow: public UIWindow +{ + public: + + enum Controls { + // Buttons: + BTN_START, // Start / restart + BTN_PAUSE, // Pause / resume + BTN_QUIT, // Quit + BTN_HINT, // Hint + BTN_MUTE, // Mute + BTN_ABOUT, // About + BTN_HISCORES, // High scores + + // Labels: + LBL_SCORE, // Game score + LBL_LEVEL, // Game level + //LBL_TIMEBAR, // The time bar + + // Windows: + WND_ABOUT, // About window + WND_HISCORES, // High scores window + + // Progress bar: + PRG_TIMEBAR, // Time bar + }; + + // Constructor / destructor: + MainWindow(SDL_Surface *background); + ~MainWindow(); + + private: + void InitControls(); // Initializes the window's controls, and adds them to the control collection +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.cpp new file mode 100644 index 000000000..e5d5d6c67 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.cpp @@ -0,0 +1,103 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/quitwindow.h" +#include "../common/trap.h" +#include "../common/events.h" + +#include "../common/surfacemanager.h" +#include "../common/fontmanager.h" +#include "../common/soundmanager.h" + +#include "../UI/uibutton.h" +#include "../UI/uilabel.h" + + +QuitWindow::QuitWindow(SDL_Surface *background): +UIWindow(background) +{ + InitControls(); +} + +QuitWindow::~QuitWindow() +{ + +} + + +// Initializes the window's controls, and adds them to the +// control collection +void QuitWindow::InitControls() +{ + SurfaceManager *surfaceMgr = SurfaceManager::GetInstance(); + FontManager *fontMgr = FontManager::GetInstance(); + SoundManager *sndMgr = SoundManager::GetInstance(); + + { + /////// Buttons /////// + SDL_Color buttonTextColor = {0, 0, 0, 0}; + + // Close: + UIButton *quitButton = new UIButton(); + quitButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + SDL_Event event; + event.type = SDL_QUIT; + quitButton->AddState(event, fontMgr->GetFont("MediumButtonFont"), "Quit", buttonTextColor); + quitButton->Align(UIControl::HALN_LEFT, UIControl::VALN_BOTTOM, 328, 290); + quitButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_QUIT, quitButton); + + // Play: + UIButton *playButton = new UIButton(); + playButton->Set(0, 0, "ButtonClick", + surfaceMgr->GetSurface("MediumButtonNormal"), surfaceMgr->GetSurface("MediumButtonDisabled"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonClicked"), + surfaceMgr->GetSurface("MediumButtonHover"), surfaceMgr->GetSurface("MediumButtonMask")); + playButton->AddState(EVENT_CLOSE, fontMgr->GetFont("MediumButtonFont"), "Play", buttonTextColor); + playButton->Align(UIControl::HALN_RIGHT, UIControl::VALN_BOTTOM, 312, 290); + playButton->SetMode(UIButton::MODE_NORMAL); + AddControl(BTN_PLAY, playButton); + + /////// Labels /////// + SDL_Color titleColor = {64, 64, 64, 0}; + SDL_Color labelTextColor = {0, 0, 0, 0}; + + // Title: + UILabel *titleLabel = new UILabel(); + titleLabel->Set(0, 0, NULL, fontMgr->GetFont("WindowTitleFont"), titleColor); + titleLabel->SetText(UIControl::HALN_LEFT, "Quit"); + titleLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_TOP, 320, 191); + AddControl(LBL_TITLE, titleLabel); + + // Dialog text: + UILabel *textLabel = new UILabel(); + textLabel->Set(0, 0, NULL, fontMgr->GetFont("DialogTextFont"), labelTextColor); + textLabel->SetText( UIControl::HALN_LEFT, + "Are you sure you want to\n" + "quit Jooleem?"); + textLabel->Align(UIControl::HALN_CENTER, UIControl::VALN_BOTTOM, 320, 252); + AddControl(LBL_TEXT, textLabel); + + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.h new file mode 100644 index 000000000..7b0b903e4 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/quitwindow.h @@ -0,0 +1,53 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _QUITWINDOW_H_ +#define _QUITWINDOW_H_ + +// The quit dialog window. + +#include "../UI/uiwindow.h" +#include "SDL.h" + +class QuitWindow: public UIWindow +{ + public: + + enum Controls { + // Buttons: + BTN_QUIT, // Close + BTN_PLAY, // Play + + // Labels: + LBL_TITLE, // Window title + LBL_TEXT, // Dialog text + }; + + // Constructor / destructor: + QuitWindow(SDL_Surface *background); + ~QuitWindow(); + + private: + void InitControls(); // Initializes the window's controls, and adds them to the control collection +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.cpp new file mode 100644 index 000000000..b5a5fd66a --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.cpp @@ -0,0 +1,559 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/uibutton.h" +#include "../common/trap.h" +#include "../common/events.h" +#include "../common/soundmanager.h" +#include "SDL_image.h" +#include + +using namespace std; + + +// Constructor - initialize the data members: +UIButton::UIButton() +{ + m_maskW = m_maskH = 0; + m_clickSoundID = ""; + for (int i = 0 ; i < MODE_MAX ; ++i) + m_surfaces[i] = NULL; + m_currentMode = MODE_DISABLED; + m_enabled = true; + m_visible = true; + m_mask = NULL; + m_showTooltip = false; + m_isFlashing = false; + + // Populate the tooltip callback timer parameter struct: + m_tooltipParam.currentMode = &m_currentMode; + m_tooltipParam.showTooltip = &m_showTooltip; +} + + +// Destructor - Free the tooltip surfaces memory for all the states: +UIButton::~UIButton() +{ + SDL_RemoveTimer(m_timerID); + + map::iterator itr; + for (itr = m_states.begin() ; itr != m_states.end() ; itr++) + { + if ((itr->second).toolTipSurface != NULL) + SDL_FreeSurface((itr->second).toolTipSurface); + } + + delete []m_mask; +} + + + +// Set the button's location, click sounds, surfaces and mask: +void UIButton::Set(Uint16 x, Uint16 y, string clickSoundID, SDL_Surface* normal, + SDL_Surface* disabled, SDL_Surface* hover, SDL_Surface* clicked, + SDL_Surface* flash, SDL_Surface* mask) +{ + SetLocation(x, y); + + m_clickSoundID = clickSoundID; + + m_surfaces[MODE_NORMAL] = normal; + m_surfaces[MODE_DISABLED] = disabled; + m_surfaces[MODE_HOVER] = hover; + m_surfaces[MODE_CLICKED] = clicked; + m_surfaces[MODE_FLASH] = flash; + + if (mask != NULL) + { + m_w = (Sint16) mask->w; + m_h = (Sint16) mask->h; + } + else + { + m_w = (Sint16) normal->w; + m_h = (Sint16) normal->h; + } + + MakeMask(mask); +} + + +// Handle a mouse down event: +bool UIButton::MouseDown(Uint16 x, Uint16 y) +{ + if (m_states.size() == 0 || m_visible == false || m_currentMode == MODE_DISABLED || + m_currentMode == MODE_CLICKED) + return false; + + if (IsInButton(x, y)) + { + m_currentMode = MODE_CLICKED; + return true; + } + else + return false; +} + + +// Handle a mouse down event: +bool UIButton::MouseUp(Uint16 x, Uint16 y) +{ + if (m_states.size() == 0 || m_visible == false || m_currentMode == MODE_DISABLED + || m_currentMode != MODE_CLICKED) + return false; + + if (IsInButton(x, y)) + return Click(); + else + { + m_currentMode = MODE_NORMAL; + return true; + } +} + +// Are the coordinates inside the button (use mask)? +bool UIButton::IsInButton(Uint16 x, Uint16 y) +{ + Sint32 X = x - m_x; + Sint32 Y = y - m_y; + + // If no mask is defined, do a simple boundry check: + if (m_mask == NULL) + return (X > 0 && Y > 0 && X <= m_surfaces[m_currentMode]->w && Y <= m_surfaces[m_currentMode]->h); + + // Otherwise, check the mask: + if (X < 0 || Y < 0 || X >= m_maskW || Y >= m_maskH) + return false; + + return ((m_mask[Y * m_maskW + X] == 0)? false : true); +} + + +// Are the coordinates inside the button? +bool UIButton::IsInRect(Uint16 x, Uint16 y) +{ + return (m_x <= x && m_x + m_w >= x && m_y <= y && m_w + m_h >= y); +} + + +// An unconditional click: +bool UIButton::Click() +{ + if (m_states.size() == 0 || m_visible == false || m_currentMode == MODE_DISABLED) + return false; + + // Play the sound: + if (m_clickSoundID != "") + SoundManager::GetInstance()->PlaySound(m_clickSoundID); + + // Push the event into the even queue: + SDL_PushEvent(&m_currentState.event); + + // Switch to clicked mode: + m_currentMode = MODE_NORMAL; + + return true; +} + +// Clicks the button if the coords are valid: +bool UIButton::Click(Uint16 x, Uint16 y) +{ + if (IsInButton(x, y)) + return Click(); + else + return false; +} + + +// Switch to hover mode. +bool UIButton::Hover() +{ + m_currentMode = MODE_HOVER; + return true; +} + + +// Switch to hover mode, if the cursor is over the button. +bool UIButton::Hover(Uint16 x, Uint16 y) +{ + if (m_states.size() == 0 || m_visible == false || m_currentMode == MODE_DISABLED + || m_currentMode == MODE_CLICKED || m_currentMode == MODE_FLASH) + return false; + + if (IsInButton(x, y)) + { + if (m_currentMode != MODE_HOVER) // We just started hovering + { + m_currentMode = MODE_HOVER; + + // Set the tooltip callback timer: + m_timerID = SDL_AddTimer(TOOLTIP_DELAY, TriggerTooltip, &m_tooltipParam); + + return true; + } + } + else if (m_currentMode == MODE_HOVER) // Restore to normal when no longer over button + { + m_currentMode = MODE_NORMAL; + m_showTooltip = false; + SDL_RemoveTimer(m_timerID); + return true; + } + + return false; +} + + +// Switch to disabled mode. +// Clicks on the button will be ignored. +void UIButton::Disable() +{ + m_enabled = false; + m_currentMode = MODE_DISABLED; + m_showTooltip = false; +} + + +// Sets the button's enabled / disabled state. +// Overrides the base class' method, to make it is compatible +// with the button states. +void UIButton::SetEnabled(bool enabled) +{ + m_enabled = enabled; + m_showTooltip = false; + + if (enabled) + m_currentMode = MODE_NORMAL; + else + m_currentMode = MODE_DISABLED; +} + + +// Switch to flash mode. +// Set the button to flash every a_iInterval ms. +void UIButton::Flash(Uint32 interval) +{ + m_flashStart = SDL_GetTicks(); + m_flashInterval = interval; + m_isFlashing = true; + m_currentMode = MODE_FLASH; +} + + +// Switch to normal (enabled) mode. +void UIButton::Normal() +{ + m_currentMode = MODE_NORMAL; + m_showTooltip = false; +} + + +// Adds a state - User event / Text: +void UIButton::AddState(int eventCode, Font *font, string text, SDL_Color color, + Font *tooltipFont, string tooltipText) +{ + SDL_Event event; + + event.type = SDL_USEREVENT; + event.user.code = eventCode; + + AddState(event, font, text, color, tooltipFont, tooltipText); +} + + +// Adds a state - SDL event / Text. +void UIButton::AddState(SDL_Event event, Font *font, string text, SDL_Color color, + Font *tooltipFont, string tooltipText) +{ + State state; + + // Render the text surface: + if (font != NULL && text != "") + state.textSurface = font->RenderPlain(Font::ALN_LEFT, color, text); + + // Create the tooltip: + if (tooltipFont != NULL && tooltipText != "") + state.toolTipSurface = CreateTooltip(tooltipFont, tooltipText); + else + state.toolTipSurface = NULL; + + // Set the event: + state.event = event; + + // Add the state to the map. The name is the event type. For user events, + // the name is the event code. + if (event.type == SDL_USEREVENT) + m_states.insert(pair(event.user.code, state)); + else + m_states.insert(pair(event.type, state)); + + m_currentState = state; +} + + + +// Adds a state - User event / Image: +void UIButton::AddState(int eventCode, SDL_Surface *surface, Font *tooltipFont, string tooltipText) +{ + SDL_Event event; + + event.type = SDL_USEREVENT; + event.user.code = eventCode; + + AddState(event, surface, tooltipFont, tooltipText); +} + + +// Adds a state - SDL event / Image: +void UIButton::AddState(SDL_Event event, SDL_Surface *surface, Font *tooltipFont, string tooltipText) +{ + State state; + + state.textSurface = surface; + + // Set the event: + state.event = event; + + // Create the tooltip: + if (tooltipFont != NULL && tooltipText != "") + state.toolTipSurface = CreateTooltip(tooltipFont, tooltipText); + else + state.toolTipSurface = NULL; + + // Add the state to the map. The name is the event type. For user events, + // the name is the event code. + if (event.type == SDL_USEREVENT) + m_states.insert(pair(event.user.code, state)); + else + m_states.insert(pair(event.type, state)); + + m_currentState = state; +} + + +// Sets the button's state. +void UIButton::SetState(int state) +{ + map::iterator itr = m_states.find(state); + if (itr != m_states.end()) + m_currentState = itr->second; +} + + +// Sets the button's mode: +void UIButton::SetMode(ButtonMode mode) +{ + m_currentMode = mode; +} + + + +// Updates the button. +// Needed for flashing buttons. +// Return true if a redraw is needed. +bool UIButton::Update() +{ + if (m_enabled != true || m_currentMode != MODE_FLASH) + return false; + + bool redraw = false; + + if (((SDL_GetTicks() - m_flashStart) / m_flashInterval) % 2) // Flashing + { + if (!m_isFlashing) // ... but was not flashing before + redraw = true; + m_isFlashing = true; + } + else // Not flashing + { + if (m_isFlashing) // ... but was flashing before + redraw = true; + + m_isFlashing = false; + } + + return redraw; +} + +// Draws the button: +void UIButton::Draw(SDL_Surface *screen) +{ + if (!m_visible) + return; + + // Draw button: + SDL_Rect rect = {m_x, m_y, 0, 0}; + + // Draw the basic surface: + if (m_currentMode == MODE_FLASH && m_isFlashing) + SDL_BlitSurface(m_surfaces[MODE_NORMAL], NULL, screen, &rect); + else // Not flashing or between flashes + SDL_BlitSurface(m_surfaces[m_currentMode], NULL, screen, &rect); + + // Draw text, centered horizontally and vertically: + rect.x = (Sint16) (m_x + (m_surfaces[m_currentMode]->w - m_currentState.textSurface->w) / 2); + rect.y = (Sint16) (m_y + (m_surfaces[m_currentMode]->h - m_currentState.textSurface->h) / 2); + SDL_BlitSurface(m_currentState.textSurface, NULL, screen, &rect); + + // Draws the tooltip: + if (m_showTooltip && m_currentState.toolTipSurface != NULL && m_currentMode != MODE_DISABLED) + { + rect.x = (Sint16)(m_x + m_w / 2 - m_currentState.toolTipSurface->w / 2); + rect.y = (Sint16)(m_y + m_h); + + SDL_BlitSurface(m_currentState.toolTipSurface, NULL, screen, &rect); + } +} + + +// Creates a mask from a surface. +// http://sdldoc.csn.ul.ie/guidevideo.php#AEN112 +void UIButton::MakeMask(SDL_Surface* maskSurface) +{ + if (maskSurface == NULL) + return; + + m_maskW = (Uint16) maskSurface->w; + m_maskH = (Uint16) maskSurface->h; + + { + m_mask = new Uint8[m_maskW * m_maskH]; + } + + // Lock the surface: + if(SDL_MUSTLOCK(maskSurface)) { + if(SDL_LockSurface(maskSurface) < 0) + return; + } + + // Copy each pixel from the alpha or red channels to the mask: + Uint32 pixel; // Value of the current pixel + Uint8 *pPixel; // Pointer to the current pixel + Uint8 g,b; + for (Uint16 i = 0 ; i < m_maskW ; ++i) + for (Uint16 j = 0 ; j < m_maskH ; ++j) + { + // 32 bit images - the mask is based on the alpha channel: + if (maskSurface->format->BytesPerPixel == 4) + { + pPixel = (Uint8 *) maskSurface->pixels + j * maskSurface->pitch + + i * maskSurface->format->BytesPerPixel; + + SDL_PixelFormat *fmt = maskSurface->format; + pixel = *(Uint32 *)pPixel & fmt->Amask; // Isolate alpha component + pixel = pixel >> fmt->Ashift; // Shift it down to 8-bit + pixel = pixel << fmt->Aloss; // Expand to a full 8-bit number + m_mask[j * m_maskW + i] = (Uint8) pixel; + } + + // 24 bit images - the mask is based on the red channel: + else if (maskSurface->format->BytesPerPixel == 3) + { + pPixel = (Uint8 *) maskSurface->pixels + j * maskSurface->pitch + + i * maskSurface->format->BytesPerPixel; + + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + pixel = pPixel[0] << 16 | pPixel[1] << 8 | pPixel[2]; + else + pixel = pPixel[0] | pPixel[1] << 8 | pPixel[2] << 16; + + SDL_GetRGB(pixel, maskSurface->format, &m_mask[j * m_maskW + i], + &g, &b); + } + } + + // Unlock: + if(SDL_MUSTLOCK(maskSurface)) + SDL_UnlockSurface(maskSurface); +} + + +// Creates a tooltip. +SDL_Surface* UIButton::CreateTooltip(Font *tooltipFont, string tooltipText) +{ + // Render the text on a colored background: + SDL_Surface *shadedText = + tooltipFont->RenderShaded(Font::ALN_LEFT, TOOLTIP_FG, TOOLTIP_BG, tooltipText); + + // Get a pointer to the screen, so we can create surfaces with + // the same pixel format: + SDL_Surface* screen = SDL_GetVideoSurface(); + + // Create a surface the will form the tooltip's background: + SDL_Surface *background = SDL_CreateRGBSurface(screen->flags, + shadedText->w + 8, shadedText->h + 4, // Add some spacing + screen->format->BitsPerPixel, + screen->format->Rmask, + screen->format->Gmask, + screen->format->Bmask, 0); + + TRAP(background == NULL, "UIButton::MakeTooltip - SDL_CreateRGBSurface failed"); + + // Fill the surface with the background color: + SDL_FillRect(background, NULL, SDL_MapRGB(background->format, TOOLTIP_BG.r, TOOLTIP_BG.g, TOOLTIP_BG.b)); + + // Create a surface that will form the tooltip's border. + SDL_Surface *border = SDL_CreateRGBSurface(screen->flags, + background->w + 2, background->h + 2, // Add a 1px border + screen->format->BitsPerPixel, + screen->format->Rmask, + screen->format->Gmask, + screen->format->Bmask, 0); + + TRAP(border == NULL, "UIButton::MakeTooltip - SDL_CreateRGBSurface failed"); + + // Fill the surface with the foreground color: + SDL_FillRect(border, NULL, SDL_MapRGB(border->format, TOOLTIP_FG.r, TOOLTIP_FG.g, TOOLTIP_FG.b)); + + // Blit the text on to the background surface: + SDL_Rect rect = {4, 2, 0, 0}; + SDL_BlitSurface(shadedText, NULL, background, &rect); + + // Blit the background + text on the border surface: + rect.x = rect.y = 1; + SDL_BlitSurface(background, NULL, border, &rect); + + // The text surface is no longer needed: + SDL_FreeSurface(shadedText); + SDL_FreeSurface(background); + + return border; +} + + +// Trigger tooltip timer callback function. +// If by the time this is called the button is still in hover mode, +// then the tooltip should be shown. +Uint32 UIButton::TriggerTooltip(Uint32 interval, void* param) +{ + TooltipParam *tooltipParam = (TooltipParam *) param; + + if (tooltipParam == NULL) + return 0; + + if (*(tooltipParam->currentMode) == UIButton::MODE_HOVER) + *(tooltipParam->showTooltip) = true; + + // Force a redraw: + PushUserEvent(EVENT_REDRAW); + + return 0; +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.h new file mode 100644 index 000000000..cb4c40f7a --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uibutton.h @@ -0,0 +1,166 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _UIBUTTON_H_ +#define _UIBUTTON_H_ + +// User interface button class. +// A button has several modes (normal, hover etc.), and one +// or more user defined states. +// Once a button is clicked, it pushes an event defined by +// its current state. +// The class also supports tooltips. + +#include "../UI/uicontrol.h" +#include "../common/font.h" + +#include "SDL.h" + +#include +#include + +using namespace std; + +// Tooltip related: +static const SDL_Color TOOLTIP_FG = {0, 0, 0, 0}; // Foreground color (text and border) +static const SDL_Color TOOLTIP_BG = {250, 250, 150, 0}; // Background color +static const Uint32 TOOLTIP_DELAY = 750; // Time, in ms, until tooltip is shown + +class UIButton: public UIControl +{ + public: + // Button modes: + enum ButtonMode { MODE_NORMAL, + MODE_DISABLED, + MODE_HOVER, + MODE_CLICKED, + MODE_FLASH, + MODE_MASK, + MODE_MAX}; + + // The button's state: + typedef struct + { + SDL_Event event; // The event to raise once clicked + SDL_Surface *textSurface; // Button text's surface + SDL_Surface *toolTipSurface; // Button's tooltip surface + } State; + + private: + string m_clickSoundID; // Click sound ID + + // Modes: + SDL_Surface *m_surfaces[MODE_MAX]; // A surface for every one of the modes + ButtonMode m_currentMode; // Current mode + ButtonMode m_prevMode; // Previous mode (to return to from hover) + + // Flash: + bool m_isFlashing; // Are we currently flashing? + Uint32 m_flashStart; // Time flashing has started + Uint32 m_flashInterval; // Flash interval + + // States: + map m_states; // Map states to their names + State m_currentState; // Current state + + // Mask: + Uint8* m_mask; // Masks the button's clickable area + Uint16 m_maskW, m_maskH; // Mask's dimensions + + // Tooltip: + bool m_showTooltip; // Should the tooltip be shown? + SDL_TimerID m_timerID; // Tooltip timer ID + typedef struct // Passed to the timer callback fucntion + { + ButtonMode *currentMode; // Current button mode + bool *showTooltip; // Should the tooltip be shown? + } TooltipParam; + TooltipParam m_tooltipParam; + + public: + UIButton(); + ~UIButton(); + + // Set all of the button's properties: + void Set(Uint16 x, Uint16 y, string clickSoundID, SDL_Surface* normal, + SDL_Surface* disabled = NULL, SDL_Surface* hover = NULL, + SDL_Surface* clicked = NULL, SDL_Surface* flash = NULL, + SDL_Surface* mask = NULL); + + bool IsInButton(Uint16 x, Uint16 y); // Are the coordinates inside the button (use mask)? + bool IsInRect(Uint16 x, Uint16 y); // Are the coordinates inside the button? + + // Handle mouse down and up events: + bool MouseDown(Uint16 x, Uint16 y); + bool MouseUp(Uint16 x, Uint16 y); + + // Click the button: + bool Click(); // Click the button + bool Click(Uint16 x, Uint16 y); // Click the button if the coords are valid + + // Hover over the button: + bool Hover(); + bool Hover(Uint16 x, Uint16 y); + + // Disable the button: + void Disable(); + void SetEnabled(bool enabled); // Override the base class' method + + // Set the button to normal (enabled) mode: + void Normal(); + + // Set the button to flash mode: + void Flash(Uint32 interval); + + // Add a state to the button: + void AddState(int eventCode, Font *font, string text, SDL_Color color, + Font *tooltipFont = NULL, string tooltipText = ""); + void AddState(SDL_Event event, Font *font, string text, SDL_Color color, + Font *tooltipFont = NULL, string tooltipText = ""); + void AddState(int eventCode, SDL_Surface *surface, Font *tooltipFont = NULL, string tooltipText = ""); + void AddState(SDL_Event event, SDL_Surface *surface, Font *tooltipFont = NULL, string tooltipText = ""); + + // Set the button's state: + void SetState(int state); + + // Set/Get the button's mode: + void SetMode(ButtonMode mode); + ButtonMode GetMode(){return m_currentMode;} + + // Update the button: + bool Update(); + + // Draw the button: + void Draw(SDL_Surface *screen); + + // Key down, unimplemented: + virtual bool KeyDown(SDL_KeyboardEvent *event){return false;} + + // Button flash interval: + static const int FLASH_INTERVAL = 500; + + protected: + void MakeMask(SDL_Surface* maskSurface); // Creates a mask from a surface + SDL_Surface* CreateTooltip(Font *tooltipFont, string tooltipText); // Creates a tooltip + static Uint32 TriggerTooltip(Uint32 interval, void* param); // Trigger tooltip timer callback func. +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.cpp new file mode 100644 index 000000000..1fd3080e4 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.cpp @@ -0,0 +1,59 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "uicontrol.h" + +void UIControl::Align(HAlign hAlign, VAlign vAlign, Uint16 x, Uint16 y) +{ + switch (hAlign) + { + case HALN_LEFT: + m_x = x; + break; + + case HALN_CENTER: + if (x >= m_w / 2) + m_x = x - m_w / 2; + break; + + case HALN_RIGHT: + if (x >= m_w) + m_x = x - m_w; + break; + } + + switch (vAlign) + { + case VALN_TOP: + m_y = y; + break; + + case VALN_MIDDLE: + if (y >= m_h / 2) + m_y = y - m_h / 2; + break; + + case VALN_BOTTOM: + if (y >= m_h) + m_y = y - m_h; + break; + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.h new file mode 100644 index 000000000..2661dc746 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uicontrol.h @@ -0,0 +1,79 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _UICONTROL_H_ +#define _UICONTROL_H_ + +#include "SDL.h" + +// Abstract base class for user interface controls (buttons, labels, text boxes) +class UIControl +{ + protected: + Uint16 m_x, m_y; // Location + Uint16 m_w, m_h; // Dimensions + bool m_visible; // Visibility flag + bool m_enabled; // Enabled flag + + public: + UIControl():m_x(0), m_y(0), m_w(0), m_h(0), m_visible(true), m_enabled(true){}; + virtual ~UIControl(){}; + + // Set the control's location: + void SetLocation(Uint16 x, Uint16 y){m_x = x; m_y = y;} + + // Align the control, vertically and horizontally: + enum HAlign { HALN_LEFT, HALN_CENTER, HALN_RIGHT}; + enum VAlign { VALN_TOP, VALN_MIDDLE, VALN_BOTTOM}; + void Align(HAlign hAlign, VAlign vAlign, Uint16 x, Uint16 y); + + // Visibility: + void SetVisible(bool visible){m_visible = visible;} + bool GetVisible(){return m_visible;} + + // Enable / disable: + virtual void SetEnabled(bool enabled){m_enabled = enabled;} + bool GetEnabled(){return m_enabled;} + + // Accessors: + Uint16 GetX(){return m_x;} + Uint16 GetY(){return m_y;} + Uint16 GetWidth(){return m_w;} + Uint16 GetHeight(){return m_h;} + + // Mouse events: + virtual bool MouseDown(Uint16 x, Uint16 y) = 0; // Process mouse up events + virtual bool MouseUp(Uint16 x, Uint16 y) = 0; // Process mouse up events + virtual bool Click(Uint16 x, Uint16 y) = 0; // Process user clicks + virtual bool Hover(Uint16 x, Uint16 y) = 0; // Process user mouse hover + + // Kyboard events: + virtual bool KeyDown(SDL_KeyboardEvent *event) = 0; + + // Update: + virtual bool Update() = 0; + + // Draw the control: + virtual void Draw(SDL_Surface *screen) = 0; +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.cpp new file mode 100644 index 000000000..bfb235618 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.cpp @@ -0,0 +1,205 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "uilabel.h" +#include +#include +#include "../common/trap.h" +#include "../common/events.h" + +// Constructor +UILabel::UILabel(): +m_BGSurface(NULL), m_TextSurface(NULL), m_CompSurface(NULL), m_font(NULL), m_Text("") +{ + m_clipRect.x = m_clipRect.y = m_clipRect.w = m_clipRect.h = 0; +} + + +// Destructor - free the SDL surfaces we created. +// Note that the background surface is not freed, since it was +// supplied to the object by the caller. +UILabel::~UILabel() +{ + if (m_TextSurface) + SDL_FreeSurface(m_TextSurface); + + if (m_CompSurface) + SDL_FreeSurface(m_CompSurface); + + SDL_RemoveTimer(m_timerID); +} + +// Sets the label's location and background. +void UILabel::Set(Uint16 x, Uint16 y, SDL_Surface* background, Font* font, SDL_Color textColor, float alpha) +{ + UIControl::SetLocation(x, y); + m_BGSurface = background; + m_textColor = textColor; + m_alpha = alpha; + + if (font != NULL) + m_font = font; + + if (m_BGSurface != NULL) + { + m_w = m_clipRect.w = (Uint16) m_BGSurface->w; + m_h = m_clipRect.h = (Uint16) m_BGSurface->h; + } + + PushUserEvent(EVENT_REDRAW); +} + + +// Returns the label's text. +std::string UILabel::GetText() const +{ + return m_Text; +} + + +// Sets the label's text, using printf-like formatting. +// The alignment is only relevant to multi-line strings. +// The text surface itself is always centered in the +// background surface, if once exists. +void UILabel::SetText(HAlign hAlign, const char *format, ...) +{ + // Format the text: + char formatted[4096]; // Holds the text after formatting + va_list listOfArgs; // Pointer to the list of arguments + + if (format == NULL) // If there's no text, do nothing + { + *formatted = 0; + } + else // Handle the variable-argument list + { + va_start(listOfArgs, format); + vsprintf(formatted, format, listOfArgs); + va_end(listOfArgs); + } + + + SetText(hAlign, std::string(formatted)); +} + +// Sets the lable's text. +void UILabel::SetText(HAlign hAlign, const std::string& text) +{ + m_Text = text; + + if (m_TextSurface != NULL) + SDL_FreeSurface(m_TextSurface); + + if (m_Text == "" && m_font == NULL) + return; + + if (hAlign == HALN_LEFT) + m_TextSurface = m_font->RenderTransparent(Font::ALN_LEFT, m_textColor, m_alpha, text); + else if (hAlign == HALN_CENTER) + m_TextSurface = m_font->RenderTransparent(Font::ALN_CENTER, m_textColor, m_alpha, text); + else + m_TextSurface = m_font->RenderTransparent(Font::ALN_RIGHT, m_textColor, m_alpha, text); + + // If no background surface is defined, the label's dimensions are those of the text surface: + if (m_BGSurface == NULL) + { + m_w = m_clipRect.w = (Uint16) m_TextSurface->w; + m_h = m_clipRect.h = (Uint16) m_TextSurface->h; + } + + PushUserEvent(EVENT_REDRAW); +} + + +// Sets the background surface. +void UILabel::SetBackground(SDL_Surface *background) +{ + m_BGSurface = background; + + if (m_BGSurface != NULL) + { + m_w = (Uint16) m_BGSurface->w; + m_h = (Uint16) m_BGSurface->h; + } +} + + +// Sets the clipping rectangle. +// Setting either dimension to a negative number cancels +// clipping of that dimension. +void UILabel::SetClipping(Sint16 w, Sint16 h) +{ + m_clipRect.w = (w < 0) ? m_w : w; + m_clipRect.h = (h < 0) ? m_h : h; +} + +// Show the label for a set amount of time. +void UILabel::ShowTimed(Uint32 time) +{ + m_visible = true; + + // Remove any existing timers: + SDL_RemoveTimer(m_timerID); + + // Set the tooltip callback timer: + m_timerID = SDL_AddTimer(time, HideLabel, &m_visible); +} + + +// Draws the label. +// The method can use a clipping rectangle to clip the surface. +void UILabel::Draw(SDL_Surface *screen) +{ + if (m_visible == false) + return; + + SDL_Rect rect = {0, 0, 0, 0}; + + if (m_BGSurface != NULL) + { + rect.x = m_x; + rect.y = m_y; + + SDL_BlitSurface(m_BGSurface, &m_clipRect, screen, &rect); + } + + if (m_TextSurface != NULL) + { + rect.x = (Sint16) (m_x + (m_w - m_TextSurface->w) / 2); + rect.y = (Sint16) (m_y + (m_h - m_TextSurface->h) / 2); + + SDL_BlitSurface(m_TextSurface, &m_clipRect, screen, &rect); + } +} + + +// Hides the label. +// This is an SDL_timer callback function. +Uint32 UILabel::HideLabel(Uint32 interval, void* param) +{ + bool *visible = (bool *) param; + *visible = false; + + // Force a redraw: + PushUserEvent(EVENT_REDRAW); + + return 0; +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.h new file mode 100644 index 000000000..1216bd510 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uilabel.h @@ -0,0 +1,83 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _UILABEL_H_ +#define _UILABEL_H_ + +// UI label control +// May contain text and/or a background image. +// The text is always centered in both dimensions. + +#include "../UI/uicontrol.h" +#include "../common/font.h" +#include +#include "SDL.h" + +class UILabel: public UIControl +{ + private: + SDL_Surface *m_BGSurface; // Background surface + SDL_Surface *m_TextSurface; // Text surface + SDL_Surface *m_CompSurface; // The text composited onto the the background + + Font *m_font; // Font used to render the label's text + std::string m_Text; // Label's text + SDL_Color m_textColor; // Label's Text color + float m_alpha; // Text's alpha value (0.0-1.0) + + SDL_Rect m_clipRect; // Clipping rectangle for the label's surface + + public: + UILabel(); + ~UILabel(); + + void Set(Uint16 x, Uint16 y, SDL_Surface* background, // Set location, background, font & color + Font *font, SDL_Color textColor, float alpha = 1.0f); + + void SetEnabled(bool enabled){}; + + std::string GetText() const; // Get the label's text + void SetText(HAlign hAlign, const char *format, ...); // Set the label's text (printf-like formatting) + void SetText(HAlign hAlign, const std::string& text); // Set the label's text + + void SetClipping(Sint16 w, Sint16 h); // Sets the clipping rectangle + + void SetBackground(SDL_Surface *background);// Sets the background surface + + void ShowTimed(Uint32 time); // Show the label for a set amount of time + + bool Update(){return false;} // Update + + void Draw(SDL_Surface *screen); // Draw the label + + // Mouse and keyboard events are irrelevant to a label, but required for polymorphism: + bool MouseDown(Uint16 x, Uint16 y){return false;} // Process mouse up events + bool MouseUp(Uint16 x, Uint16 y){return false;} // Process mouse up events + bool Click(Uint16 x, Uint16 y){return false;} // Process user clicks + bool Hover(Uint16 x, Uint16 y){return false;} // Process user mouse hover + bool KeyDown(SDL_KeyboardEvent *event){return false;} + + private: + SDL_TimerID m_timerID; // Hide timer ID + static Uint32 HideLabel(Uint32 interval, void* param); // Hide label timer callback func. +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.cpp new file mode 100644 index 000000000..54c4e30cd --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.cpp @@ -0,0 +1,141 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/uiprogress.h" +#include "../common/trap.h" +#include "../common/events.h" + +// Constructor +UIProgressBar::UIProgressBar(): +m_BGSurface(NULL), m_normalSurface(NULL), m_flashingSurface(NULL), m_disabledSurface(NULL) +{ + m_flashingMode = false; + m_isFlashing = false; + m_x = m_y = 0; + m_progress = 0; + m_clipRect.x = m_clipRect.y = m_clipRect.w = m_clipRect.h = 0; +} + + +// Sets location and surfaces +void UIProgressBar::Set(Uint16 x, Uint16 y, SDL_Surface* BGSurface, + SDL_Surface *normalSurface, SDL_Surface *flashingSurface, SDL_Surface *disabledSurface) +{ + m_x = x; + m_y = y; + + m_BGSurface = BGSurface; + m_normalSurface = normalSurface; + m_flashingSurface = flashingSurface; + m_disabledSurface = disabledSurface; + + if (normalSurface != NULL) + { + m_w = m_clipRect.w = (Uint16) normalSurface->w; + m_h = m_clipRect.h = (Uint16) normalSurface->h; + } +} + + +// Sets the bar's progress. Valid range is 0.0f - 1.0f. +void UIProgressBar::SetProgress(float progress) +{ + if (progress < 0.0f) + m_progress = 0.0f; + else if (progress > 1.0f) + m_progress = 1.0f; + else + m_progress = progress; + + + // Calculate the progress value in pixels: + Uint16 progressInPixels = (Uint16) (m_progress * m_w); + + // If the pixel value has changed, the bar needs to be redrawn: + if (progressInPixels != m_clipRect.w) + { + m_clipRect.w = progressInPixels; + PushUserEvent(EVENT_REDRAW); + } +} + + +// Starts or stops the bar's flashing +void UIProgressBar::Flash(bool flag) +{ + // Ignore requests to start flashing while already flashing. + if (flag == true && m_flashingMode == true) + return; + + m_flashingMode = m_isFlashing = flag; + m_flashStart = SDL_GetTicks(); + + // Force redraw: + PushUserEvent(EVENT_REDRAW); +} + + +// Updates the progress bar. +bool UIProgressBar::Update() +{ + if (m_enabled != true || m_flashingMode == false) + return false; + + bool redraw = false; + + if (((SDL_GetTicks() - m_flashStart) / FLASH_INTERVAL) % 2) // Flashing + { + if (!m_isFlashing) // ... but was not flashing before + redraw = true; + m_isFlashing = true; + } + else // Not flashing + { + if (m_isFlashing) // ... but was flashing before + redraw = true; + + m_isFlashing = false; + } + + return redraw; + +} + +// Draws the progress bar. +void UIProgressBar::Draw(SDL_Surface *screen) +{ + if (!m_visible || screen == NULL || m_normalSurface == NULL || m_flashingSurface == NULL) + return; + + + SDL_Rect rect = {m_x, m_y, 0, 0}; + + // Blit background: + if (m_BGSurface) + SDL_BlitSurface(m_BGSurface, NULL, screen, &rect); + + // Blit foreground: + if (!m_enabled) + SDL_BlitSurface(m_disabledSurface, &m_clipRect, screen, &rect); + else if (m_isFlashing) + SDL_BlitSurface(m_flashingSurface, &m_clipRect, screen, &rect); + else + SDL_BlitSurface(m_normalSurface, &m_clipRect, screen, &rect); +} \ No newline at end of file diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.h new file mode 100644 index 000000000..8dadbe948 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiprogress.h @@ -0,0 +1,76 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _UIPROGRESS_H_ +#define _UIPROGRESS_H_ + +// UI progress bar control. + +#include "../UI/uicontrol.h" +#include "SDL.h" + +class UIProgressBar: public UIControl +{ + private: + // Surfaces: + SDL_Surface *m_BGSurface; // Background surface + SDL_Surface *m_normalSurface; // Normal foreground surface + SDL_Surface *m_flashingSurface; // Flashing foreground surface + SDL_Surface *m_disabledSurface; // Disabled foreground surface + + SDL_Rect m_clipRect; // Clipping rectangle for the foreground surface + + float m_progress; // Bar's progress, between 0.0f and 1.0f + + // Flash: + bool m_flashingMode; // Are we in flashing mode? + bool m_isFlashing; // Are we currently flashing? + Uint32 m_flashStart; // Time flashing has started + + // Button flash interval: + static const int FLASH_INTERVAL = 500; + + public: + UIProgressBar(); + ~UIProgressBar(){}; + + void Set(Uint16 x, Uint16 y, SDL_Surface* BGSurface, // Sets location and surfaces + SDL_Surface *normalSurface, SDL_Surface *flashingSurface, SDL_Surface *disabledSurface); + + // Set and get the bar's progress: + void SetProgress(float progress); + float GetProgress(){return m_progress;} + + void Flash(bool flag); // Starts or stops the bar's flashing + + bool Update(); // Updates the progress bar + + void Draw(SDL_Surface *screen); // Draws the progress bar + + // Mouse and keyboard events are irrelevant to a progress bar, but required for polymorphism: + bool MouseDown(Uint16 x, Uint16 y){return false;} // Process mouse up events + bool MouseUp(Uint16 x, Uint16 y){return false;} // Process mouse up events + bool Click(Uint16 x, Uint16 y){return false;} // Process user clicks + bool Hover(Uint16 x, Uint16 y){return false;} // Process user mouse hover + bool KeyDown(SDL_KeyboardEvent *event){return false;} // Process key down events +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.cpp new file mode 100644 index 000000000..f51c52a8d --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.cpp @@ -0,0 +1,282 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/uitextbox.h" +#include "../common/trap.h" + +// Constructor +UITextBox::UITextBox(): +m_BGSurface(NULL), m_textSurface(NULL), m_cursorSurface(NULL), m_font(NULL), m_text("") +{ + m_cursorIndex = 0; + m_blinking = true; +} + + +// Destructor - free the SDL surfaces we created. +// Note that the background and cursor surfaces are not freed, +// since they were supplied to the object by the caller. +UITextBox::~UITextBox() +{ + if (m_textSurface) + SDL_FreeSurface(m_textSurface); +} + + +// Sets the label's location and background. +void UITextBox::Set(Uint16 x, Uint16 y, // Box location + Uint16 textX, Uint16 textY, // Text location relative to the box + SDL_Surface* background, SDL_Surface *cursorSurface, // background and cursor surfaces + Font *font, SDL_Color textColor) // Font and text color +{ + UIControl::SetLocation(x, y); + m_textX = textX; + m_textY = textY; + + m_BGSurface = background; + m_cursorSurface = cursorSurface; + m_textColor = textColor; + + m_font = font; +} + + +// Clears the text. +void UITextBox::Clear() +{ + SetText(""); +} + + +// Returns the label's text. +std::string UITextBox::GetText() const +{ + return m_text; +} + + +// Sets the box's text. +void UITextBox::SetText(string text) +{ + m_text = text; + m_cursorIndex = (Uint16) m_text.length(); + Refresh(); +} + + +// Update the cursor blink. +bool UITextBox::Update() +{ + if (m_enabled != true) + return false; + + bool redraw = false; + + if (SDL_GetTicks() % (CURSOR_BLINK * 2) < CURSOR_BLINK) // Blink on + { + if (!m_blinking) // ... but was not flashing before + redraw = true; + m_blinking = true; + } + else // Not flashing + { + if (m_blinking) // ... but was flashing before + redraw = true; + m_blinking = false; + } + + return redraw; +} + +// Draws the text box. +void UITextBox::Draw(SDL_Surface *screen) +{ + if (m_visible == false) + return; + + SDL_Rect rect = {0, 0, 0, 0}; + + // Background: + if (m_BGSurface != NULL) + { + rect.x = m_x; + rect.y = m_y; + + SDL_BlitSurface(m_BGSurface, NULL, screen, &rect); + } + + // Text: + if (m_textSurface != NULL) + { + rect.x = m_textX + m_x; + rect.y = m_textY + m_y; + + SDL_BlitSurface(m_textSurface, NULL, screen, &rect); + } + + // Cursor: + if (m_cursorSurface != NULL && m_blinking) + //SDL_GetTicks() % (CURSOR_BLINK * 2) < CURSOR_BLINK) + { + rect.x = m_x + m_textX + (m_charOffset.empty() ? 0 : m_charOffset[m_cursorIndex]); + rect.y = m_y + m_textY + 1; + + SDL_BlitSurface(m_cursorSurface, NULL, screen, &rect); + } +} + + +// Process mouse down events. +// A click sets the cursor position. +bool UITextBox::MouseDown(Uint16 x, Uint16 y) +{ + // Check if the click in inside the text area: + if (m_textSurface == NULL || x < m_x + m_textX || x > m_x + m_textX + m_textSurface->w + || y < m_y + m_textY || y > m_y + m_textY + m_textSurface->h) + return false; + + // Scan the offset vector to see where to place the cursor: + Uint16 A, B; + + for (Uint16 i = 0 ; i < (Uint16) m_charOffset.size() ; ++i) + { + if (i == 0) + A = m_x + m_textX + m_charOffset[i]; + else + A = (m_x + m_textX + m_charOffset[i - 1] + m_x + m_textX + m_charOffset[i]) / 2; + + if (i == (Uint16) m_charOffset.size()) + B = m_x + m_textX + m_charOffset[i]; + else + B = (m_x + m_textX + m_charOffset[i] + m_x + m_textX + m_charOffset[i + 1]) / 2; + + if (x >= A && x < B) + m_cursorIndex = i; + } + + return true; +} + + +// Handle key down events. +bool UITextBox::KeyDown(SDL_KeyboardEvent *event) +{ + switch (event->keysym.sym) // Get the key symbol + { + // Left arrow: + case SDLK_LEFT: + if (m_cursorIndex > 0) + m_cursorIndex--; + break; + + // Right arrow: + case SDLK_RIGHT: + if (m_cursorIndex < m_text.length()) + m_cursorIndex++; + break; + + // Home: + case SDLK_HOME: + m_cursorIndex = 0; + break; + + // End: + case SDLK_END: + m_cursorIndex = (Uint16) m_text.length(); + break; + + // Backspace: + case SDLK_BACKSPACE: + if (m_cursorIndex > 0) + { + m_text.erase(m_cursorIndex - 1, 1); + m_cursorIndex--; + Refresh(); + } + break; + + // Delete: + case SDLK_DELETE: + if (m_cursorIndex < m_text.length()) + { + m_text.erase(m_cursorIndex, 1); + Refresh(); + } + break; + + // Characters: + default: + { + // Make sure text doesn't graphically overflow the background image: + if (m_textSurface != NULL && + m_textSurface->w >= (m_BGSurface->w - 3 * m_textX)) + break; + + char c = 0; + + // Convert the unicode value into ASCII: + if ((event->keysym.unicode & 0xFF80) == 0) + { + c = (char)(event->keysym.unicode & 0x7F); + + if (c >= ' ' && c <= '~') // Add only displayable chars + { + // Insert the character to the string at the current cursor position: + m_text.insert(m_cursorIndex, string(1,c)); + m_cursorIndex++; + Refresh(); + } + } + else // International char - ignore + return false; + break; + } + } + + return true; +} + + +// Refreshes the text box when changed. +void UITextBox::Refresh() +{ + MeasureOffsets(); + + SDL_FreeSurface(m_textSurface); + m_textSurface = m_font->RenderPlain(Font::ALN_LEFT, m_textColor, m_text); +} + + +// Measure the characters' offset. +// The method populates the offset vector with the offsets +// of the string characters, in pixels, when rendered with +// the object's font. +void UITextBox::MeasureOffsets() +{ + m_charOffset.clear(); + + m_charOffset.push_back(0); + for (size_t i = 0 ; i < m_text.length() ; ++i) + { + Uint16 temp = m_font->GetGlyphAdvance((Uint16) m_text[i]); + m_charOffset.push_back(temp + m_charOffset[i]); + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.h new file mode 100644 index 000000000..12a880f03 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uitextbox.h @@ -0,0 +1,99 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _UITEXTBOX_H_ +#define _UITEXTBOX_H_ + +// UI text box control + +#include "../UI/uicontrol.h" +#include "../common/font.h" +#include +#include +#include "SDL.h" + +using namespace std; + +class UITextBox: public UIControl +{ + private: + SDL_Surface *m_BGSurface; // Background surface + SDL_Surface *m_textSurface; // Text surface + SDL_Surface *m_cursorSurface; // Cursor surface + + string m_text; // The box's text + Font *m_font; // Font used to render the text + SDL_Color m_textColor; // Text color + + Uint16 m_cursorIndex; // Cursor position - as the index of the + // character in the string. The cursor + // is drawn BEFORE the character with + // the same index. + // Use n+1 to indicate the position after + // the last character. + + vector m_charOffset; // A vector of character advance offset. + // E.g. For the string "Hello", the value + // of the second element will be the distance, + // in pixels, from the begining of the rendered + // text until the end of the character 'e' + + Uint16 m_textX, m_textY; // Location of text area within the control + + bool m_blinking; // Current blinking status + static const int CURSOR_BLINK = 500; // Cursor blink rate, in ms + + + public: + UITextBox(); + ~UITextBox(); + + void Set(Uint16 x, Uint16 y, // Box location + Uint16 textX, Uint16 textY, // Text location relative to the box + SDL_Surface* background, SDL_Surface *cursorSurface, // Background and cursor surfaces + Font *font, SDL_Color textColor); // Font and text color + + void SetEnabled(bool enabled){}; + + void Clear(); // Clears the text + + string GetText() const; // Gets the box's text + void SetText(string text); // Sets the box's text + + void SetBackground(SDL_Surface *background);// Sets the background surface + + bool Update(); // Updates the text box + + void Draw(SDL_Surface *screen); // Draws the text box + + // Mouse and keyboard events: + bool MouseDown(Uint16 x, Uint16 y); // Processes mouse down events + bool MouseUp(Uint16 x, Uint16 y){return false;} // Processes mouse up events + bool Click(Uint16 x, Uint16 y){return false;} // Processes user clicks + bool Hover(Uint16 x, Uint16 y){return false;} // Processes user mouse hover + bool KeyDown(SDL_KeyboardEvent *event); // Processes keyboard clicks + + private: + void Refresh(); // Refreshes the text box when changed + void MeasureOffsets(); // Measure the characters' offset +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.cpp new file mode 100644 index 000000000..7c167e482 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.cpp @@ -0,0 +1,307 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../UI/uiwindow.h" +#include "../common/common.h" + +using namespace std; + +// Constructor +UIWindow::UIWindow(SDL_Surface *background) +{ + m_visible = true; + + m_background = background; + + if (m_background != NULL) + { + m_w = (Uint16) m_background->w; + m_h = (Uint16) m_background->h; + } + else + { + m_w = m_h = 0; + } + + // Set the window to be centered relative to the screen: + m_x = (SCREEN_WIDTH - m_w) / 2; + m_y = (SCREEN_HEIGHT - m_h) / 2; +} + +// Destructor - delete the window's controls +UIWindow::~UIWindow() +{ + // Delete the individual controls: + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + delete (itr->second); + + // Delete the controls within the vectors: + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + delete (*itrVec); + } +} + + +// Enables or disables all of the window's controls. +void UIWindow::SetEnabled(bool enabled) +{ + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + itr->second->SetEnabled(enabled); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + (*itrVec)->SetEnabled(enabled); + } +} + + +// Adds a control to the collection. +void UIWindow::AddControl(int ID, UIControl *control) +{ + map::iterator itr = m_controls.find(ID); + + if (itr == m_controls.end()) + m_controls[ID] = control; + +} + +// Adds a vector of controls to the collection. +void UIWindow::AddControlVector(int ID, vector vec) +{ + map >::iterator itr = m_controlsVectors.find(ID); + + if (itr == m_controlsVectors.end()) + m_controlsVectors[ID] = vec; +} + + +// Gets a UI control by its ID. +UIControl *UIWindow::GetControl(int ID) +{ + map::iterator itr = m_controls.find(ID); + + if (itr == m_controls.end()) + return NULL; + else + return m_controls[ID]; +} + +// Gets a UI control vector by its ID. +vector UIWindow::GetControlVector(int ID) +{ + return m_controlsVectors[ID]; +} + +// Gets a UI control, cast to a button, by its ID. +UIButton *UIWindow::GetButton(int ID) +{ + return (static_cast(GetControl(ID))); +} + +// Gets a UI control, cast to a label, by its ID. +UILabel *UIWindow::GetLabel(int ID) +{ + return (static_cast(GetControl(ID))); +} + + +// Gets a UI control, cast to a progress bar, by its ID. +UIProgressBar *UIWindow::GetProgressBar(int ID) +{ + return (static_cast(GetControl(ID))); +} + +// Processes mouse down events. +bool UIWindow::MouseDown(Uint16 x, Uint16 y) +{ + bool redraw = false; + + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + redraw |= itr->second->MouseDown(x, y); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + redraw |= (*itrVec)->MouseDown(x, y); + } + + return redraw; +} + + +// Processes mouse up events. +bool UIWindow::MouseUp(Uint16 x, Uint16 y) +{ + bool redraw = false; + + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + redraw |= itr->second->MouseUp(x, y); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + redraw |= (*itrVec)->MouseUp(x, y); + } + + return redraw; +} + +// Processes user clicks. +bool UIWindow::Click(Uint16 x, Uint16 y) +{ + bool redraw = false; + + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + redraw |= itr->second->Click(x, y); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + redraw |= (*itrVec)->Click(x, y); + } + + return redraw; +} + + +// Processes mouse hover. +bool UIWindow::Hover(Uint16 x, Uint16 y) +{ + bool redraw = false; + + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + redraw |= itr->second->Hover(x, y); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + redraw |= (*itrVec)->Hover(x, y); + } + + return redraw; +} + + +// Proces key down events: +bool UIWindow::KeyDown(SDL_KeyboardEvent *event) +{ + bool redraw = false; + + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + redraw |= itr->second->KeyDown(event); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + redraw |= (*itrVec)->KeyDown(event); + } + + return redraw; +} + + +// Update the window. +bool UIWindow::Update() +{ + bool redraw = false; + + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + redraw |= itr->second->Update(); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + redraw |= (*itrVec)->Update(); + } + + return redraw; +} + + +// Draws the window. +void UIWindow::Draw(SDL_Surface *screen) +{ + if (m_visible == false) + return; + + DrawBackground(screen); + + DrawControls(screen); +} + + +// Draws the window's background. +void UIWindow::DrawBackground(SDL_Surface *screen) +{ + if (m_visible == false) + return; + + // Draw the background: + SDL_Rect rect = {m_x, m_y, m_w, m_h}; + SDL_BlitSurface(m_background, NULL, screen, &rect); +} + +// Draws the window's controls. +void UIWindow::DrawControls(SDL_Surface *screen) +{ + if (m_visible == false) + return; + + // Draw the controls: + map::iterator itr; + for (itr = m_controls.begin() ; itr != m_controls.end() ; itr++) + itr->second->Draw(screen); + + map >::iterator itrCtlVec; + for (itrCtlVec = m_controlsVectors.begin() ; itrCtlVec != m_controlsVectors.end() ; itrCtlVec++) + { + vector::iterator itrVec; + for (itrVec = itrCtlVec->second.begin() ; itrVec != itrCtlVec->second.end() ; itrVec++) + (*itrVec)->Draw(screen); + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.h new file mode 100644 index 000000000..91ae250ef --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/UI/uiwindow.h @@ -0,0 +1,86 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _UIWINDOW_H_ +#define _UIWINDOW_H_ + +// A base class for windows. +// The window is composed of a background and a collection of +// controls - labels, buttons or other windows. +// The class supports vectors of controls. + +#include "../UI/uicontrol.h" +#include "../UI/uibutton.h" +#include "../UI/uilabel.h" +#include "../UI/uiprogress.h" + +#include +#include +#include "SDL.h" + +using namespace std; + +class UIWindow: public UIControl +{ + protected: + SDL_Surface *m_background; // Window background + map m_controls; // Window controls + map > m_controlsVectors; // Window controls vectors + + public: + UIWindow(SDL_Surface *background); + virtual ~UIWindow(); + + // Enable / Disbable the windows' controls: + void SetEnabled(bool enabled); + + // Add and get a control: + void AddControl(int ID, UIControl *control); + void AddControlVector(int ID, vector vec); + UIControl *GetControl(int ID); + vector GetControlVector(int ID); + + // Accessors: + UIButton *GetButton(int ID); + UILabel *GetLabel(int ID); + UIProgressBar *GetProgressBar(int ID); + SDL_Surface *GetBackground(){return m_background;} + + + // Mouse events: + bool MouseDown(Uint16 x, Uint16 y); // Process mouse up events + bool MouseUp(Uint16 x, Uint16 y); // Process mouse up events + bool Click(Uint16 x, Uint16 y); // Process user clicks + bool Hover(Uint16 x, Uint16 y); // Process user mouse hover + + // Key down: + bool KeyDown(SDL_KeyboardEvent *event); + + // Update the window: + bool Update(); + + // Draw the window: + void Draw(SDL_Surface *screen); + void DrawBackground(SDL_Surface *screen); + void DrawControls(SDL_Surface *screen); +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/common.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/common.h new file mode 100644 index 000000000..72444e780 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/common.h @@ -0,0 +1,62 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include "SDL.h" + +#include +#include +using namespace std; + + +// Application name, version and website: +static const string APP_NAME = "Jooleem"; +static const string APP_VERSION = "0.1.4 (20050925)"; +static const string APP_URL = "http://jooleem.sourceforge.net"; + + +// Window: +static const string CAPTION = "Jooleem"; // Window caption +static const string ICON = "data/interface/icon.png"; // Window icon + + +// Screen dimensions: +static const int SCREEN_WIDTH = 640; +static const int SCREEN_HEIGHT = 480; + +// Takes a screenshot. +// The file is saved as a Windows bitmap. +inline void ScreenShot(char* fileName = NULL) +{ + // If no file name is supplied, create one from the current time: + if (!fileName) + { + char buf[128]; + sprintf(buf, "data/screenshots/%ld.bmp", time(NULL)); + SDL_SaveBMP(SDL_GetVideoSurface(), buf); + } + else + SDL_SaveBMP(SDL_GetVideoSurface(), fileName); +} + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.cpp new file mode 100644 index 000000000..d4a4c6389 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.cpp @@ -0,0 +1,211 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../common/effectmanager.h" +#include "../common/fontmanager.h" +#include "../common/trap.h" +#include + +EffectManager* EffectManager::m_instance = NULL; + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +EffectManager* EffectManager::GetInstance() +{ + if (m_instance == NULL) + { + { + m_instance = new EffectManager(); + } + } + + return m_instance; +} + + +// Initialize the manager - load fonts. +void EffectManager::Init() +{ + m_initialized = true; +} + + +// Adds a score effect +void EffectManager::AddScoreEffect(SDL_Event* event) +{ + TRAP(m_initialized == false, "EffectManager::AddScoreEffect() - Manager has not been initialized"); + + if (event == NULL) + return; + + SDL_Color color = {255, 255, 255, 0}; + + // Get the score and coordinates: + Uint32 *score = (Uint32 *) event->user.data1; + SDL_Rect *rect = (SDL_Rect *) event->user.data2; + + if (score == NULL || rect == NULL) + return; + + // Create the string: + ostringstream temp; + temp << *score; + + // Add the effect: + Add(rect->x + rect->w / 2, + rect->y + rect->h / 2, + temp.str(), + FontManager::GetInstance()->GetFont("ScoreEffect"), + color, + 0.8f, + 0.0f, + 1500, + 0.5f); +} + + +// Adds a new level effect +void EffectManager::AddLevelEffect(int level) +{ + TRAP(m_initialized == false, "EffectManager::AddLevelEffect() - Manager has not been initialized"); + + SDL_Color color = {255, 255, 255, 0}; + + // Create the string: + ostringstream temp; + temp << "Level " << level; + + // Add the effect: + Add(412, + 228, + temp.str(), + FontManager::GetInstance()->GetFont("LevelEffect"), + color, + 0.8f, + 0.0f, + 2000, + -0.3f); +} + + +// Adds a game over effect. +void EffectManager::AddGameOverEffect() +{ + TRAP(m_initialized == false, "EffectManager::AddGameOverEffect() - Manager has not been initialized"); + + SDL_Color color = {255, 255, 255, 0}; + + // Add the effect: + Add(412, + 50, + "Game Over", + FontManager::GetInstance()->GetFont("GameOverEffect"), + color, + 0.8f, + 0.0f, + 4000, + -0.01f); +} + + +// Adds a perfect rectangle effect. +void EffectManager::AddPerfectEffect() +{ + TRAP(m_initialized == false, "EffectManager::AddLevelEffect() - Manager has not been initialized"); + + SDL_Color color = {255, 255, 255, 0}; + + // Add the effect: + Add(412, + 300, + "Perfect!", + FontManager::GetInstance()->GetFont("ScoreEffect"), + color, + 0.8f, + 0.0f, + 1500, + 0.5f); +} + +// Adds an effect to the manager. +void EffectManager::Add(Sint16 x, Sint16 y, string text, + Font *font, SDL_Color color, float initialAlpha, + float velocity, Uint32 lifeTime, float gravity) +{ + TRAP(m_initialized == false, "EffectManager::AddScoreEffect() - Manager has not been initialized"); + + { + TextEffect *effect = new TextEffect(x, y, text, font, color, initialAlpha, velocity, lifeTime, gravity); + + // Add the effect to the list: + m_activeEffects.push_back(effect); + } + +} + + +// Updates the effects. +// Returns true if a redraw is required. +bool EffectManager::Update() +{ + TRAP(m_initialized == false, "EffectManager::AddScoreEffect() - Manager has not been initialized"); + + bool redraw = false; + list::iterator itr; + + for (itr = m_activeEffects.begin() ; itr != m_activeEffects.end() ; itr++) + { + redraw |= (*itr)->Update(); + + // Remove inactive effects from the list. + if ( (*itr)->IsActive() == false) + { + delete (*itr); + itr = m_activeEffects.erase(itr); + } + } + + return redraw; + +} + +// Draws the effects. +void EffectManager::Draw(SDL_Surface *screen) +{ + TRAP(m_initialized == false, "EffectManager::AddScoreEffect() - Manager has not been initialized"); + + list::iterator itr; + + for (itr = m_activeEffects.begin() ; itr != m_activeEffects.end() ; itr++) + (*itr)->Draw(screen); +} + +// Clean up - free all the effects. +void EffectManager::Cleanup() +{ + TRAP(m_initialized == false, "EffectManager::AddScoreEffect() - Manager has not been initialized"); + + list::iterator itr; + + for (itr = m_activeEffects.begin() ; itr != m_activeEffects.end() ; itr++) + delete (*itr); +} + + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.h new file mode 100644 index 000000000..e010fdcaa --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/effectmanager.h @@ -0,0 +1,72 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _EFFECTMANAGER_H_ +#define _EFFECTMANAGER_H_ + +// A singleton effect manager class. +// The class holds a list of active effects. The user can add an effect +// to the list. +// Once an effect becomes inactive (or invisible), it is removed from +// the list. + +#include "SDL.h" +#include +#include + +#include "../common/font.h" +#include "../common/texteffect.h" + +using namespace std; + +class EffectManager +{ + private: + list m_activeEffects; // A list of active effects + + public: + // Add effects: + void Add(Sint16 x, Sint16 y, string text, // Adds an effect + Font *font, SDL_Color color, float initialAlpha, + float velocity, Uint32 lifeTime, float gravity); + void AddScoreEffect(SDL_Event *event); // Adds a score effect + void AddLevelEffect(int level); // Adds a new level effect + void AddPerfectEffect(); // Adds a perfect rectangle effect + void AddGameOverEffect(); // Adds a game over effect + + bool Update(); // Updates the effects + + void Draw(SDL_Surface *screen); // Draws the effects + + static EffectManager* GetInstance(); + void Init(); + void Cleanup(); + + private: + static EffectManager* m_instance; + EffectManager(){}; + EffectManager(const EffectManager&){}; + EffectManager& operator= (const EffectManager&){}; + + bool m_initialized; // Has the manager been initialized? +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/events.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/events.h new file mode 100644 index 000000000..4e6f13b14 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/events.h @@ -0,0 +1,67 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _EVENTS_H_ +#define _EVENTS_H_ + +// User event codes. + +#include "SDL_events.h" + +enum Events + { + EVENT_HINT = SDL_NUMEVENTS + 1, // This ensures there are no collisions with the standard SDL events + EVENT_PAUSE, // Pause the game + EVENT_RESUME, // Resume the game + EVENT_START, // Start a new game + EVENT_RESTART, // Restart the game + EVENT_SELECTION_ADD, // A marble was added to the selection + EVENT_SELECTION_CANCEL, // The user cancelled the current selection + EVENT_SELECTION_INVALID, // The user selected an invalid marble + EVENT_RECT_COMPLETE, // Rectangle was completed + EVENT_PERFECT, // A perfect rectangle was complete + EVENT_NEW_LEVEL, // Level over, advanced to next level + EVENT_TIME_LOW, // Time is running low + EVENT_TIME_OK, // Time increased, and is over the low threshold + EVENT_GAME_OVER, // Game over + EVENT_MUTE, // Mute + EVENT_UNMUTE, // Unmute + EVENT_ABOUT, // Show about window + EVENT_HIGH_SCORES, // Show high scores window + EVENT_CLOSE, // Close the window + EVENT_REDRAW, // Force a screen redraw + EVENT_TRACK_OVER, // A music track has ended + EVENT_WEBSITE, // Visit the website + }; + +// Pushes a user event on to the SDL queue. +inline void PushUserEvent(Events eventCode, void *data1 = NULL, void *data2 = NULL) +{ + SDL_Event event; + event.type = SDL_USEREVENT; + event.user.code = eventCode; + event.user.data1 = data1; + event.user.data2 = data2; + + SDL_PushEvent(&event); +} + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/filenames.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/filenames.h new file mode 100644 index 000000000..b1115a578 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/filenames.h @@ -0,0 +1,168 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _FILENAMES_H_ +#define _FILENAMES_H_ + + +/* + All of the game's resource files are listed here. + + See +*/ + +#include + +// Graphics: +const std::string GRAPHIC_RESOURCES[] = { + // ID Filename + + // Window backgrounds: + "MainWindowBackground", "data/interface/background.png", + "AboutWindowBackground", "data/interface/about_window.png", + "GameOverWindowBackground", "data/interface/gameover_window.png", + "HighScoresWindowBackground","data/interface/hs_window.png", + "QuitWindowBackground", "data/interface/quit_window.png", + + // Small button: + "SmallButtonNormal", "data/interface/btn_small_normal.png", + "SmallButtonDisabled", "data/interface/btn_small_disabled.png", + "SmallButtonHover", "data/interface/btn_small_hover.png", + "SmallButtonClicked", "data/interface/btn_small_clicked.png", + "SmallButtonMask", "data/interface/btn_small_mask.png", + + // Medium button: + "MediumButtonNormal", "data/interface/btn_medium_normal.png", + "MediumButtonDisabled", "data/interface/btn_medium_disabled.png", + "MediumButtonHover", "data/interface/btn_medium_hover.png", + "MediumButtonClicked", "data/interface/btn_medium_clicked.png", + "MediumButtonMask", "data/interface/btn_medium_mask.png", + + // Large: + "LargeButtonNormal", "data/interface/btn_large_normal.png", + "LargeButtonDisabled", "data/interface/btn_large_disabled.png", + "LargeButtonHover", "data/interface/btn_large_hover.png", + "LargeButtonClicked", "data/interface/btn_large_clicked.png", + "LargeButtonMask", "data/interface/btn_large_mask.png", + + // Text box: + "TextBoxBackground", "data/interface/textbox_bg.png", + "TextBoxCursor", "data/interface/cursor.png", + + // Picture button foregrounds: + "MuteButton", "data/interface/mute.png", + "UnmuteButton", "data/interface/unmute.png", + "AboutButton", "data/interface/info.png", + "HighScoresButton", "data/interface/cup.png", + + // Time bar label: + "TimeBar", "data/interface/time_bar.png", + "TimeBarFlash", "data/interface/time_bar_flash.png", + "TimeBarPaused", "data/interface/time_bar_paused.png", + + // Score label: + "ScoreLabel", "data/interface/label.png", + + // Marbles: + "MarbleNormalBlue", "data/marbles/blue.png", + "MarbleNormalGreen", "data/marbles/green.png", + "MarbleNormalRed", "data/marbles/red.png", + "MarbleNormalYellow", "data/marbles/yellow.png", + + "MarbleSelectedBlue", "data/marbles/blue_s.png", + "MarbleSelectedGreen", "data/marbles/green_s.png", + "MarbleSelectedRed", "data/marbles/red_s.png", + "MarbleSelectedYellow", "data/marbles/yellow_s.png", + + "MarblePaused", "data/marbles/grey.png", + + // Misc.: + "Logo", "data/interface/logo.png", + }; + + +// Sound: +const std::string SOUND_RESOURCES[] = { + // ID Filename + "RectangleComplete", "data/sounds/rectangle_complete.ogg", + "NewLevel", "data/sounds/new_level.ogg", + "GameOver", "data/sounds/game_over.ogg", + "TimeAlert", "data/sounds/time_alert.ogg", + "ButtonClick", "data/sounds/button_click.ogg", + "SelectionCancelled", "data/sounds/selection_cancelled.ogg", + "MarbleClick", "data/sounds/marble_click.ogg", + "SelectionInvalid", "data/sounds/selection_invalid.ogg", + "PerfectRectangle", "data/sounds/perfect_rectangle.ogg", + "HighScore", "data/sounds/high_score.ogg", + }; + + +// Music: +const std::string MUSIC_RESOURCES[] = { + // ID Filename + "MusicTrack0", "data/music/track_00.ogg", + "MusicTrack1", "data/music/track_01.ogg", + }; + + +// Fonts: +const std::string FONT_RESOURCES[] = { + // ID Filename Size + // Window: + "WindowTitleFont", "data/fonts/Vera.ttf", "16", + + // Buttons: + "MediumButtonFont", "data/fonts/Vera.ttf", "16", + "LargeButtonFont", "data/fonts/Vera.ttf", "24", + "TooltipFont", "data/fonts/Vera.ttf", "10", + + // Text box: + "TextBoxFont", "data/fonts/VeraBd.ttf", "16", + + // About window: + "AppVersionFont", "data/fonts/VeraBd.ttf", "16", + "LinkFont", "data/fonts/Vera.ttf", "14", + "CreditsFont", "data/fonts/Vera.ttf", "13", + "LicenseFont", "data/fonts/Vera.ttf", "11", + + // Game over window: + "GameOverScoreFont", "data/fonts/VeraBd.ttf", "16", + "GameOverCongratsFont", "data/fonts/Vera.ttf", "16", + "GameOverStatsFont", "data/fonts/Vera.ttf", "16", + + // High scores window: + "HighScoresFont", "data/fonts/VeraBd.ttf", "16", + + // Main window: + "ScoreFont", "data/fonts/VeraBd.ttf", "32", + "LevelFont", "data/fonts/VeraBd.ttf", "24", + + // Quit window: + "DialogTextFont", "data/fonts/Vera.ttf", "16", + + // Text effects: + "ScoreEffect", "data/fonts/VeraBd.ttf", "64", + "LevelEffect", "data/fonts/VeraBd.ttf", "100", + "GameOverEffect", "data/fonts/VeraBd.ttf", "64", + }; + +#endif + + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.cpp new file mode 100644 index 000000000..5aba93f4b --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.cpp @@ -0,0 +1,318 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../common/font.h" +#include "../common/surfacemanager.h" + +#include +#include +#include "../common/trap.h" + + +// Initializes a font object, using the argument +// TTF file and point size. +Font::Font(string TTFfile, int size) +{ + m_font = TTF_OpenFont(TTFfile.c_str(), size); + + TRAP(m_font == NULL, "Font::Font() - Could not open " << TTFfile); +} + +Font::~Font() +{ + TTF_CloseFont(m_font); +} + + +// Renders a text surface. +SDL_Surface *Font::Render(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, + float alpha, string text) +{ + TRAP(m_font == NULL, "Font::Render() - Font not initialized"); + + if (text == "") + return NULL; + + // Split the text into seperate lines: + std::vector lines; + SplitToLines(text, lines); + + // Determine rendering mode: If the foreground and + // background colors are identical, don't render the + // background. + bool shaded = (BGcolor.r == color.r && BGcolor.g == color.g && BGcolor.b == color.b) ? false : true; + + // Render each line to a surface, and remember the widest line: + std::vector lineSurfaces; + int maxLineWidth = 0; + int combinedHeight = 0; + for (size_t i = 0 ; i < lines.size() ; ++i) + { + SDL_Surface *temp; + + // Determine rendering mode, and render the line: + if (shaded) // Renders with a colored background + { + SDL_Surface *temp1 = TTF_RenderText_Shaded(m_font, lines[i].c_str(), color, BGcolor); + + // The rendered surface must be converted to the display format, otherwise it + // won't show up properly. + temp = SDL_DisplayFormatAlpha(temp1); + + SDL_FreeSurface(temp1); + } + else // Renders blended + temp = TTF_RenderText_Blended(m_font, lines[i].c_str(), color); + + TRAP(temp == NULL, "Font::Render() - TTF_RenderText_Blended() failed"); + + if (temp->w > maxLineWidth) + maxLineWidth = temp->w; + + combinedHeight += temp->h; + + lineSurfaces.push_back(temp); + } + + // Calcaulate the line spacing (in pixels): + // int lineSpacing = (TTF_FontLineSkip(m_font) - TTF_FontAscent(m_font)) / 2; + // FIX: + int lineSpacing = -3; + + // Create a new surface, to hold all the lines combined: + SDL_Surface *textSurface = SDL_CreateRGBSurface( + lineSurfaces[0]->flags, + maxLineWidth, + (int) (combinedHeight + (lines.size() - 1) * lineSpacing), + lineSurfaces[0]->format->BitsPerPixel, + lineSurfaces[0]->format->Rmask, + lineSurfaces[0]->format->Gmask, + lineSurfaces[0]->format->Bmask, + lineSurfaces[0]->format->Amask); + + TRAP(textSurface == NULL, "Font::Render() - SDL_CreateRGBSurface() failed"); + + // Fill the surface with the background color, if applicable: + if (shaded) + SDL_FillRect(textSurface, NULL, + SDL_MapRGB(textSurface->format, BGcolor.r, BGcolor.g, BGcolor.b)); + + // Blit the lines to the new surface, freeing their surfaces as we go along: + SDL_Rect rect = {0,0,0,0}; + SurfaceManager *sfcMgr = SurfaceManager::GetInstance(); + for (size_t i = 0 ; i < lineSurfaces.size() ; ++i) + { + // Horizontal alignment: + switch (alignment) + { + case ALN_LEFT: + rect.x = 0; + break; + case ALN_CENTER: + rect.x = (Sint16)((maxLineWidth - lineSurfaces[i]->w) / 2); + break; + case ALN_RIGHT: + rect.x = (Sint16)(maxLineWidth - lineSurfaces[i]->w); + break; + default: + ERR("Font::Render() - Invalid alignment"); + break; + } + + // Vertical placing: + if (i == 0) + rect.y = 0; + else + { + rect.y = (Sint16)(i * (lineSurfaces[i - 1]->h + lineSpacing)); + SDL_FreeSurface(lineSurfaces[i - 1]); + } + + sfcMgr->Blit(lineSurfaces[i], textSurface, alpha, &rect); + } + SDL_FreeSurface(lineSurfaces[lineSurfaces.size() - 1]); + + return textSurface; +} + +SDL_Surface *Font::Render(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, + float alpha, const char *format, ...) +{ + // Format the text: + char formatted[MAX_TEXT_LEN]; // Holds the text after formatting + va_list listOfArgs; // Pointer to the list of arguments + + if (format == NULL) // If there's no text, do nothing + { + *formatted = 0; + } + else // Handle the variable-argument list + { + va_start(listOfArgs, format); + vsprintf(formatted, format, listOfArgs); + va_end(listOfArgs); + } + + return Render(alignment, color, BGcolor, alpha, string(formatted)); +} + +// Renders transparent text. +SDL_Surface *Font::RenderTransparent(Font::Alignment alignment, SDL_Color color, float alpha, string text) +{ + return Render(alignment, color, color, alpha, text); +} + +// Renders transparent text, with printf-like formatting. +SDL_Surface *Font::RenderTransparent(Font::Alignment alignment, SDL_Color color, float alpha, + const char *format, ...) +{ + // Format the text: + char formatted[MAX_TEXT_LEN]; // Holds the text after formatting + va_list listOfArgs; // Pointer to the list of arguments + + if (format == NULL) // If there's no text, do nothing + { + *formatted = 0; + } + else // Handle the variable-argument list + { + va_start(listOfArgs, format); + vsprintf(formatted, format, listOfArgs); + va_end(listOfArgs); + } + + return Render(alignment, color, color, alpha, string(formatted)); +} + + +// Renders a string +SDL_Surface *Font::RenderPlain(Font::Alignment alignment, SDL_Color color, string text) +{ + return Render(alignment, color, color, 1.0f, text); +} + +SDL_Surface *Font::RenderPlain(Font::Alignment alignment, SDL_Color color, const char *format, ...) +{ + // Format the text: + char formatted[MAX_TEXT_LEN]; // Holds the text after formatting + va_list listOfArgs; // Pointer to the list of arguments + + if (format == NULL) // If there's no text, do nothing + { + *formatted = 0; + } + else // Handle the variable-argument list + { + va_start(listOfArgs, format); + vsprintf(formatted, format, listOfArgs); + va_end(listOfArgs); + } + + return Render(alignment, color, color, 1.0f, string(formatted)); +} + +// Renders shaded text (text on a colored background): +SDL_Surface *Font::RenderShaded(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, string text) +{ + return Render(alignment, color, BGcolor, 1.0f, text); +} + +SDL_Surface *Font::RenderShaded(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, + const char *format, ...) +{ + // Format the text: + char formatted[MAX_TEXT_LEN]; // Holds the text after formatting + va_list listOfArgs; // Pointer to the list of arguments + + if (format == NULL) // If there's no text, do nothing + { + *formatted = 0; + } + else // Handle the variable-argument list + { + va_start(listOfArgs, format); + vsprintf(formatted, format, listOfArgs); + va_end(listOfArgs); + } + + return Render(alignment, color, BGcolor, 1.0f, string(formatted)); +} + + +// Gets the advance value of a glyph. +// The advance is the total horizontal space the +// rendered glyph occupies, including the spacing +// between it and the following glyph. +// See http://jcatki.no-ip.org/SDL_ttf/metrics.png +Uint16 Font::GetGlyphAdvance(Uint16 c) +{ + int ret = 0; + + TTF_GlyphMetrics(m_font, c, NULL, NULL, NULL, NULL, &ret); + + return (Uint16) ret; +} + + +// Sets the font style: +void Font::SetStyle(Style style) +{ + if (m_font == NULL) + return; + + switch (style) + { + case STYLE_NORMAL: + TTF_SetFontStyle(m_font, TTF_STYLE_NORMAL); + break; + case STYLE_BOLD: + TTF_SetFontStyle(m_font, TTF_STYLE_BOLD); + break; + case STYLE_ITALIC: + TTF_SetFontStyle(m_font, TTF_STYLE_ITALIC); + break; + case STYLE_UNDERLINE: + TTF_SetFontStyle(m_font, TTF_STYLE_UNDERLINE); + break; + default: + return; + } +} + + +// Splits the text into lines. +// The result is stored in a vector of strings. +void Font::SplitToLines(std::string text, std::vector& lines) +{ + lines.empty(); + + size_t nextNewLine = 0; + size_t lastNewLine = 0; + + while ((nextNewLine = text.find('\n', lastNewLine)) != text.npos) + { + lines.push_back(text.substr(lastNewLine, nextNewLine - lastNewLine)); + lastNewLine = nextNewLine + 1; + } + + lines.push_back(text.substr(lastNewLine, text.length() - lastNewLine)); +} + + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.h new file mode 100644 index 000000000..2c38e8e8e --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/font.h @@ -0,0 +1,84 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _FONT_H_ +#define _FONT_H_ + +// Font wrapper class. +// A font is defined as a face (e.g. Times New Roman) of a specific +// point size (e.g. 16). +// The class supports multi-line strings and text alignment. + +#include "SDL.h" +#include "SDL_ttf.h" +#include +#include + +using namespace std; + +class Font +{ + public: + enum Alignment {ALN_LEFT, ALN_CENTER, ALN_RIGHT}; // Text alignment + enum Style {STYLE_NORMAL, STYLE_BOLD, STYLE_ITALIC, STYLE_UNDERLINE}; // Font styles + + private: + TTF_Font *m_font; // The SDL_ttf font + + public: + Font(string TTFfile, int size); + ~Font(); + + // Renders plain text: + SDL_Surface *RenderPlain(Font::Alignment alignment, SDL_Color color, string text); + SDL_Surface *RenderPlain(Font::Alignment alignment, SDL_Color color, const char *format, ...); + + // Renders transparent text: + SDL_Surface *RenderTransparent(Font::Alignment alignment, SDL_Color color, float alpha, string text); + SDL_Surface *RenderTransparent(Font::Alignment alignment, SDL_Color color, float alpha, + const char *format, ...); + + // Renders shaded text (text on a colored background): + SDL_Surface *RenderShaded(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, string text); + SDL_Surface *RenderShaded(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, + const char *format, ...); + + // Gets the advance value of a glyph: + Uint16 GetGlyphAdvance(Uint16 c); + + // Sets the font style: + void SetStyle(Style style); + + private: + static const int MAX_TEXT_LEN = 4096; // Maximum text length + + // Full control of text's appearance - color, transparency & background. + // Used by the various Render* methods. + SDL_Surface *Render(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, + float alpha, string text); + SDL_Surface *Render(Font::Alignment alignment, SDL_Color color, SDL_Color BGcolor, + float alpha, const char *format, ...); + + void SplitToLines(string text, vector& lines); // Splits the text into lines +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.cpp new file mode 100644 index 000000000..9d26902c6 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.cpp @@ -0,0 +1,83 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../common/fontmanager.h" +#include "../common/trap.h" + + +FontManager* FontManager::m_instance = NULL; + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +FontManager* FontManager::GetInstance() +{ + if (m_instance == NULL) + { + { + m_instance = new FontManager(); + } + } + + return m_instance; +} + +// Adds a new font to the manager. +// If a resource with the same ID exists, a pointer to it is returned. +// Otherwise, the method returns a pointer to the new font. +Font* FontManager::AddFont(string ID, string fileName, int size) +{ + // Make sure the ID does not already exist in the map: + map::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + return itr->second; + + Font *font; + { + font = new Font(fileName, size); + } + + m_map.insert(pair(ID, font)); + + return font; +} + + +// Gets a font by its ID. +// If the ID does not exist, NULL is returned. +Font *FontManager::GetFont(string ID) +{ + map::iterator itr = m_map.find(ID); + if (itr == m_map.end()) + return NULL; + + return itr->second; +} + + +// Releases all the loaded fonts. +void FontManager::Cleanup() +{ + map::iterator itr; + for (itr = m_map.begin() ; itr != m_map.end() ; itr++) + delete itr->second; + + m_map.clear(); +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.h new file mode 100644 index 000000000..dd5d5c02d --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/fontmanager.h @@ -0,0 +1,59 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _FONTMANAGER_H_ +#define _FONTMANAGER_H_ + +// A singleton font manager class. +// The user can load fonts into the manager. On loading, the user defines +// a unique string identifier that is associated with the font. The user can +// then access the stored fonts using that ID. +// +// Example: +// FontManager::GetInstance()->AddFont("MainFont", "arial.ttf", 16); +// Font *font = FontManager::GetInstance()->GetFont("MainFont"); + +#include +#include +#include "../common/font.h" + +using namespace std; + +class FontManager +{ + private: + map m_map; // Map string IDs to font objects + + public: + Font *AddFont(string ID, string fileName, int size); + Font *GetFont(string ID); + + static FontManager* GetInstance(); + void Cleanup(); + + private: + static FontManager* m_instance; + FontManager(){}; + FontManager(const FontManager&){}; + FontManager& operator= (const FontManager&){}; +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.cpp new file mode 100644 index 000000000..706104bf9 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.cpp @@ -0,0 +1,183 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../common/musicmanager.h" +#include "../common/events.h" +#include "../common/trap.h" + +#include +#include + +MusicManager* MusicManager::m_instance = NULL; +const float MusicManager::DEFAULT_VOLUME = 0.25f; + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +MusicManager* MusicManager::GetInstance() +{ + if (m_instance == NULL) + { + { + m_instance = new MusicManager(); + srand((unsigned)time(NULL)); + } + } + + return m_instance; +} + + +// Adds a new track to the manager. +// If a resource with the same ID exists, a pointer to it is returned. +// Otherwise, the method returns a pointer to the new surface. +Mix_Music *MusicManager::AddTrack(string ID, string fileName) +{ + // Make sure the ID does not already exist in the map: + map::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + return itr->second; + + Mix_Music *track = Mix_LoadMUS(fileName.c_str()); + + TRAP(track == NULL, "MusicManager::AddTrack() - Could not open " << fileName); + + m_map.insert(pair(ID, track)); + + m_currentTrack = m_map.find(ID); + + return track; +} + + +// Gets a chunk by its ID. +// If the ID does not exist, NULL is returned. +Mix_Music *MusicManager::GetTrack(string ID) +{ + map::iterator itr = m_map.find(ID); + if (itr == m_map.end()) + return NULL; + + return itr->second; +} + + +// Plays a track. +void MusicManager::PlayTrack(string ID) +{ + map::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + { + Mix_PlayMusic(itr->second, 0); + Mix_HookMusicFinished(TrackOver); + } + + m_currentTrack = itr; +} + +// Plays a random track +void MusicManager::PlayRandomTrack() +{ + int i = rand() % (int) m_map.size(); // NOTE: We assume the RNG has already been seeded + + map::iterator itr = m_map.begin(); + + for (int j = 0 ; j < i ; ++j) + itr++; + + m_currentTrack = itr; + + Mix_PlayMusic(itr->second, 0); + Mix_HookMusicFinished(TrackOver); +} + + +// Plays the next track. +// The track order is set by their order in the map. +void MusicManager::PlayNextTrack() +{ + m_currentTrack++; + + if (m_currentTrack == m_map.end()) + m_currentTrack = m_map.begin(); + + Mix_PlayMusic(m_currentTrack->second, 0); + Mix_HookMusicFinished(TrackOver); +} + + +// Pauses the currently playing track. +void MusicManager::Pause() +{ + Mix_PauseMusic(); +} + + +// Resumes playing. +void MusicManager::Resume() +{ + Mix_ResumeMusic(); +} + +// Is a track currently playing? +// Note: Does not check if the track has been paused. +bool MusicManager::IsPlaying() +{ + return (Mix_PlayingMusic() == 1); +} + + +// Sets the music volume. +// 0.0f - Silence, 1.0f - Max volume +void MusicManager::SetVolume(float volume) +{ + if (volume < 0.0f || volume > 1.0f) + return; + + Mix_VolumeMusic((int)(MIX_MAX_VOLUME * volume)); +} + + +// Releases all the loaded tracks. +void MusicManager::Cleanup() +{ + // FIX: This causes an exception on UIButton::TriggerTooltip + // Add a nice fadeout: + // Mix_FadeOutMusic(500); + // SDL_Delay(500); + /////// + + Mix_HaltMusic(); + + // Free the tracks: + map::iterator itr; + for (itr = m_map.begin() ; itr != m_map.end() ; itr++) + Mix_FreeMusic(itr->second); + + m_map.clear(); +} + + +// Automatically called when a track is over. +// This is a callback function for Mix_HookMusicFinished. +void MusicManager::TrackOver() +{ + PushUserEvent(EVENT_TRACK_OVER); +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.h new file mode 100644 index 000000000..c7a0952f6 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/musicmanager.h @@ -0,0 +1,72 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _MUSICMANAGER_H_ +#define _MUSICMANAGER_H_ + +// A singleton music manager class. + + +#include "SDL.h" +#include "SDL_mixer.h" +#include +#include + +using namespace std; + +class MusicManager +{ + private: + map m_map; // Map string IDs to music tracks + map::iterator m_currentTrack; // Currently playing track + + public: + Mix_Music *AddTrack(string ID, string fileName); // Adds a track to the manager + + Mix_Music *GetTrack(string ID); // Gets a track by its ID + + void PlayTrack(string ID); // Plays a track + void PlayRandomTrack(); // Plays a random track + void PlayNextTrack(); // Plays the next track + + void Pause(); // Pauses the currently playing track + void Resume(); // Resumes playing + + bool IsPlaying(); // Is a track currently playing? + + void SetVolume(float volume); // Sets the music volume + + static MusicManager* GetInstance(); + void Cleanup(); + + static const float DEFAULT_VOLUME; // Music default volume + + private: + static MusicManager* m_instance; + MusicManager(){}; + MusicManager(const MusicManager&){}; + MusicManager& operator= (const MusicManager&){}; + + // Callback function, called when a track is over: + static void TrackOver(); +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.cpp new file mode 100644 index 000000000..af988ff12 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.cpp @@ -0,0 +1,146 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../common/soundmanager.h" +#include "../common/trap.h" + +SoundManager* SoundManager::m_instance = NULL; +Uint32 SoundManager::m_lastChannel = 0; +const float SoundManager::DEFAULT_VOLUME = 1.0f; + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +SoundManager* SoundManager::GetInstance() +{ + if (m_instance == NULL) + { + { + m_instance = new SoundManager(); + } + } + + return m_instance; +} + + +// Adds a new chunk to the manager. +// If a resource with the same ID exists, a pointer to it is returned. +// Otherwise, the method returns a pointer to the new surface. +Mix_Chunk *SoundManager::AddSound(string ID, string fileName) +{ + // Make sure the ID does not already exist in the map: + map >::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + return (itr->second).first; + + Mix_Chunk *chunk = Mix_LoadWAV(fileName.c_str()); + + TRAP(chunk == NULL, "SoundManager::AddSound() - Could not open " << fileName); + + pair chunkChannel = pair(chunk, ++m_lastChannel); + pair > IDChunkChannel = + pair > (ID, chunkChannel); + + m_map.insert(IDChunkChannel); + //m_map.insert(pair >(ID, chunkChannel)); + + return chunk; +} + + +// Gets a chunk by its ID. +// If the ID does not exist, NULL is returned. +Mix_Chunk *SoundManager::GetSound(string ID) +{ + map >::iterator itr = m_map.find(ID); + if (itr == m_map.end()) + return NULL; + + return (itr->second).first; +} + + +// Plays a sound. +void SoundManager::PlaySound(string ID, bool loop) +{ + map >::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + Mix_PlayChannel((itr->second).second, (itr->second).first, loop ? -1 : 0); +} + + +// Stops a playing sound. +void SoundManager::StopSound(string ID) +{ + map >::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + Mix_HaltChannel((itr->second).second); +} + + +// Stops all sounds. +void SoundManager::StopAll() +{ + /* + map >::iterator itr; + for (itr = m_map.begin() ; itr != m_map.end() ; itr++) + Mix_HaltChannel((itr->second).second); + */ + + Mix_HaltChannel(-1); +} + + +// Sets the sound volume. +// 0.0f - Silence, 1.0f - Max volume +void SoundManager::SetVolume(float volume) +{ + if (volume < 0.0f || volume > 1.0f) + return; + + Mix_Volume(-1, (int)(MIX_MAX_VOLUME * volume)); +} + + +// Sets the a sample's volume. +// 0.0f - Silence, 1.0f - Max volume +void SoundManager::SetVolume(string ID, float volume) +{ + if (volume < 0.0f || volume > 1.0f) + return; + + map >::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + Mix_Volume((itr->second).second, (int)(MIX_MAX_VOLUME * volume)); +} + + +// Releases all the loaded chunks. +void SoundManager::Cleanup() +{ + StopAll(); + + map >::iterator itr; + for (itr = m_map.begin() ; itr != m_map.end() ; itr++) + Mix_FreeChunk((itr->second).first); + + m_map.clear(); +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.h new file mode 100644 index 000000000..27e199499 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/soundmanager.h @@ -0,0 +1,73 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _SOUNDMANAGER_H_ +#define _SOUNDMANAGER_H_ + +// A singleton SDL mixer chunks manager class. +// The user can use the class to load mixer chunks from sound files. On loading, the +// user defines a unique string identifier that is associated with the chunk. The user +// can then access the stored chunks using that ID. +// +// Example: +// SoundManager::GetInstance()->AddSound("ButtonClick", "click.wav"); +// Mix_Chunk *chunk = SoundManager::GetInstance()->GetSound("ButtonClick"); + +#include "SDL.h" +#include "SDL_mixer.h" +#include +#include + +using namespace std; + +class SoundManager +{ + private: + map > m_map; // Map string IDs to (sound chunks / channels) + + public: + Mix_Chunk *AddSound(string ID, string fileName); + Mix_Chunk *GetSound(string ID); + + void PlaySound(string ID, bool loop = false); // Plays a sound + + void StopSound(string ID); // Stops a playing sound + + void StopAll(); // Stops all sounds + + void SetVolume(float volume); // Sets the sound's volume + void SetVolume(string ID, float volume); // Sets a sample's volume + + static SoundManager* GetInstance(); + void Cleanup(); + + static const float DEFAULT_VOLUME; // Sound effects volume + + private: + static SoundManager* m_instance; + SoundManager(){}; + SoundManager(const SoundManager&){}; + SoundManager& operator= (const SoundManager&){}; + + static Uint32 m_lastChannel; // Number of last mixing channel allocated to a chunk +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.cpp new file mode 100644 index 000000000..273a2dfb7 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.cpp @@ -0,0 +1,182 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../common/surfacemanager.h" +#include "../common/trap.h" +#include "SDL_image.h" + +SurfaceManager* SurfaceManager::m_instance = NULL; + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +SurfaceManager* SurfaceManager::GetInstance() +{ + if (m_instance == NULL) + { + { + m_instance = new SurfaceManager(); + } + } + + return m_instance; +} + + +// Adds a new surface to the manager. +// If a resource with the same ID already exists, a pointer +// to it is returned. Otherwise, the method returns a pointer +// to the new surface. +SDL_Surface* SurfaceManager::AddSurface(string ID, string fileName) +{ + // Check whether the ID already exists in the map: + map::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + itr->second; + + // Load the image: + SDL_Surface *surface = IMG_Load(fileName.c_str()); + + TRAP(surface == NULL, "SurfaceManager::AddSurface() - Could not open " << fileName); + + // Convert it to the framebuffer's display format: + SDL_Surface *converted = SDL_DisplayFormatAlpha(surface); + SDL_FreeSurface(surface); + + m_map[ID] = converted; + + return converted; +} + + +// Adds a new surface to the manager. +// If a resource with the same ID exists, it is overwritten. +// The method returns a pointer to the new surface. +SDL_Surface* SurfaceManager::AddSurface(string ID, SDL_Surface *surface) +{ + // Check whether the ID already exists in the map: + map::iterator itr = m_map.find(ID); + if (itr != m_map.end()) + SDL_FreeSurface(itr->second); + + TRAP(surface == NULL, "SurfaceManager::AddSurface() - adding an NULL surface"); + + m_map[ID] = surface; + + return surface; +} + + +// Gets a surface by its ID. +// If the ID does not exist, NULL is returned. +SDL_Surface *SurfaceManager::GetSurface(string ID) +{ + map::iterator itr = m_map.find(ID); + if (itr == m_map.end()) + return NULL; + + return itr->second; +} + + +// Releases all the loaded surfaces. +void SurfaceManager::Cleanup() +{ + map::iterator itr; + for (itr = m_map.begin() ; itr != m_map.end() ; itr++) + SDL_FreeSurface(itr->second); + + m_map.clear(); +} + + +// Blits the source surface onto the destination surface, while +// combining their alpha values. This allows to blit onto a +// transparent surface, which SDL_BlitSurface does not support. +// The user can also specify the source alpha value to create +// transparent text (0.0f = transparent, 1.0 = opaque). +// Bledning equation: +// result(r,g,b) = source(r,g,b) * source(a) + dest(r,g,b) * (1 - source(a)) +// TO DO: Alpha should loook better. Review blending equation. +void SurfaceManager::Blit(SDL_Surface* source, SDL_Surface* dest, float srcAlpha, SDL_Rect *rect) +{ + if (source == NULL || dest == NULL || source->format->BitsPerPixel != 32 + || source->format->BitsPerPixel != 32 || rect->x > dest->w || rect->y > dest->h) + return; + + // Result, source and destination RGBA values: + Uint8 rr, rg, rb, ra; + Uint8 sr, sg, sb, sa; + Uint8 dr, dg, db, da; + + // Lock both surfaces: + if(SDL_MUSTLOCK(source)) + if(SDL_LockSurface(source) < 0) + return; + + if(SDL_MUSTLOCK(dest)) + if(SDL_LockSurface(dest) < 0) + { + if SDL_MUSTLOCK(source) + SDL_UnlockSurface(source); + return; + } + + // Make sure we stay in bounds: + int maxX = (rect->x + source->w >= dest->w) ? dest->w - rect->x : source->w; + int maxY = (rect->y + source->h >= dest->h) ? dest->h - rect->y : source->h; + + Uint8 *sourcePixel, *destPixel; + float alpha; + for (int x = 0 ; x < maxX ; x++) + for (int y = 0 ; y < maxY ; y++) + { + // Get the source and destaination pixels: + sourcePixel = (Uint8 *) source->pixels + y * source->pitch + x * source->format->BytesPerPixel; + destPixel = (Uint8 *) dest->pixels + (y + rect->y) * dest->pitch + + (x + rect->x) * dest->format->BytesPerPixel; + + // Extract the pixels' RGBA components: + SDL_GetRGBA(*(Uint32*)sourcePixel, source->format, &sr, &sg, &sb, &sa); + SDL_GetRGBA(*(Uint32*)destPixel, dest->format, &dr, &dg, &db, &da); + + // Blend and write the result back to the destination pixel: + alpha = sa / 255.0f; // Convert from 0..255 to 0.0..1.0 + rr = (Uint8) (sr * alpha + dr * (1.0f - alpha)); + rg = (Uint8) (sg * alpha + dg * (1.0f - alpha)); + rb = (Uint8) (sb * alpha + db * (1.0f - alpha)); + ra = (Uint8) (sa * alpha + da * (1.0f - alpha)); + + // A = A1 (1 - A2) + A2 A2 + //float A1 = sa / 255.0f; + //float A2 = da / 255.0f; + //ra = (Uint8) (A2 * (1.0f - A1) + (A1 * A1)); + + + *(Uint32 *)destPixel = SDL_MapRGBA(source->format, rr, rg, rb, (Uint8) (ra * srcAlpha)); + + } + + if SDL_MUSTLOCK(source) + SDL_UnlockSurface(source); + + if SDL_MUSTLOCK(dest) + SDL_UnlockSurface(dest); +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.h new file mode 100644 index 000000000..83147c186 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/surfacemanager.h @@ -0,0 +1,62 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _SURFACEMANAGER_H_ +#define _SURFACEMANAGER_H_ + +// A singleton SDL surface manager class. +// The user can use the class to load surfaces from image files. On loading, the +// user defines a unique string identifier that is associated with the surface. The user +// can then access the stored surfaces using that ID. +// +// Example: +// SurfaceManager::GetInstance()->AddSurface("SmallButton", "small_button.png"); +// SDL_Surface *surface = SurfaceManager::GetInstance()->GetSurface("SmallButton"); + +#include "SDL.h" +#include +#include + +using namespace std; + +class SurfaceManager +{ + private: + map m_map; // Map string IDs to font objects + + public: + SDL_Surface *AddSurface(string ID, string fileName); + SDL_Surface *AddSurface(string ID, SDL_Surface *surface); + SDL_Surface *GetSurface(string ID); + + static SurfaceManager* GetInstance(); + void Cleanup(); + + static void Blit(SDL_Surface *source, SDL_Surface *dest, float alpha, SDL_Rect *rect); // Improved blitting + + private: + static SurfaceManager* m_instance; + SurfaceManager(){}; + SurfaceManager(const SurfaceManager&){}; + SurfaceManager& operator= (const SurfaceManager&){}; +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.cpp new file mode 100644 index 000000000..5d1123d28 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.cpp @@ -0,0 +1,140 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "texteffect.h" +#include "../common/trap.h" +#include "../common/common.h" + +// Constructor. +TextEffect::TextEffect(Sint16 x, Sint16 y, string text, Font *font, SDL_Color color, float initialAlpha, + float velocity, Uint32 lifeTime, float gravity) +{ + m_x = x; + m_y = y; + m_text = text; + m_font = font; + m_color = color; + + if (initialAlpha > 1.0f || initialAlpha < 0.0f) + m_alpha = 255; + else + m_alpha = (Uint8) (255 * initialAlpha); + + m_visible = (m_alpha > 0.0f); + m_velocity = velocity; + m_lifeTime = lifeTime; + m_gravity = gravity; + + m_surface = NULL; + + Render(true); + + m_startTime = SDL_GetTicks(); +} + + +// Destrcutor. +// Free the surface. +TextEffect::~TextEffect() +{ + if (m_surface) + SDL_FreeSurface(m_surface); +} + +// Updates the effect. +// Returns true if a redraw is required. +bool TextEffect::Update() +{ + if (m_visible == false) + return false; + + bool redraw = false; + + // Calculate the alpha value, as a function of the time. + // A signed int is used to prevent underflow (the effect will become opaque again). + Sint16 alpha = 255 - (Sint16) (255 * ((SDL_GetTicks() - m_startTime) / (float) m_lifeTime)); + if (alpha < 0) + alpha = 0; + + if (alpha != (Sint16) m_alpha) + { + m_alpha = (Uint8) alpha; + redraw = true; + + //cerr << alpha << endl; + + // Check if the surface is now fully transparent: + if (alpha == 0) + m_visible = false; + + Render(false); // The surface needs to be re-rendered with each change to its alpha + } + + // Update the velocity, as a function of m_gravity and time: + m_velocity += ((SDL_GetTicks() - m_startTime) / 1000.0f) * m_gravity; + + // Update the location: + Sint16 y = m_y - (Sint16) m_velocity; + + if (y != m_y) + { + m_y = y; + redraw = true; + + // Check if the surface went out of bounds: + if (y + m_h < 0 || y > SCREEN_HEIGHT) + m_visible = false; + } + + return redraw; +} + + +// Draws the effect. +void TextEffect::Draw(SDL_Surface *screen) +{ + SDL_Rect rect; + + rect.x = m_x; + rect.y = m_y; + + SDL_BlitSurface(m_surface, NULL, screen, &rect); +} + + +// Renders the surface. +void TextEffect::Render(bool center) +{ + if (m_surface) + SDL_FreeSurface(m_surface); + + m_surface = m_font->RenderTransparent(Font::ALN_CENTER, m_color, m_alpha / 255.0f, m_text); + + m_w = (Sint16) m_surface->w; + m_h = (Sint16) m_surface->h; + + // Center the text: + if (center) + { + m_x -= m_w / 2; + m_y -= m_h / 2; + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.h new file mode 100644 index 000000000..a03f89ec6 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/texteffect.h @@ -0,0 +1,71 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _TEXTEFFECT_H_ +#define _TEXTEFFECT_H_ + +// Text effect. +// Basically, a surface with a text message that can move and fade out. + +#include "SDL.h" +#include + +#include "../common/font.h" + +using namespace std; + +class TextEffect +{ + private: + string m_text; // The effect's text + SDL_Surface *m_surface; // The current surface + Font *m_font; // Font used to render the text + SDL_Color m_color; // Font color + + Sint16 m_x, m_y, m_w, m_h; // Location and dimensions + Uint8 m_alpha; // Current alpha value + bool m_visible; // Flag indicating the effect's visibilty + + Uint32 m_startTime; // Starting time + float m_velocity; // Effect's current velocity (pixels per second) + Uint32 m_lifeTime; // The effect's lifetime, in ms + float m_gravity; // m_gravity factor (in pixels per second per second) + + public: + + // Constructor / destructor: + TextEffect(Sint16 x, Sint16 y, string text, Font *font, SDL_Color color, float initialAlpha = 1.0f, + float velocity = 0.0f, Uint32 lifeTime = 5000, float gravity = 0.5f); + ~TextEffect(); + + bool IsActive(){return m_visible;} + + bool Update(); // Updates the effect + + void Draw(SDL_Surface *screen); // Draws the effect + + private: + void Render(bool center); // Renders the surface + +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/common/trap.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/trap.h new file mode 100644 index 000000000..d4692f9d5 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/common/trap.h @@ -0,0 +1,67 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _TRAP_H_ +#define _TRAP_H_ + +// Error trapping macros. + +#include +#include +using namespace std; +#ifdef ANDROID +#include + +// Trap - throws a string message if the condition is true. +// A nicer alternative to assert. +#undef TRAP +#define TRAP(cond, msg) \ +{ \ + if(cond) { \ + ostringstream __TRAP_stream; \ + __TRAP_stream << msg << flush; \ + __android_log_print(ANDROID_LOG_FATAL, "Jooleem", "%s:%i: error: %s", __FILE__, __LINE__, __TRAP_stream.str().c_str()); \ + exit(1);\ + } \ +} + +#else + +// Trap - throws a string message if the condition is true. +// A nicer alternative to assert. +#undef TRAP +#define TRAP(cond, msg) \ +{ \ + if(cond) { \ + ostringstream __TRAP_stream; \ + __TRAP_stream << msg << "\n(" << __FILE__ << ", line " << __LINE__ << ")" << endl; \ + throw(__TRAP_stream.str()); \ + } \ +} +#endif + +// Unconditional throw. Best used in places where the program should +// never be, like switch defaults etc. +#undef ERR +#define ERR(msg) TRAP(true, msg) + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.cpp new file mode 100644 index 000000000..1c9ede258 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.cpp @@ -0,0 +1,291 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/aboutstate.h" +#include "../engine/quitstate.h" + +#include "../UI/mainwindow.h" +#include "../common/trap.h" +#include "../common/events.h" + +#include "../common/surfacemanager.h" +#include "../common/soundmanager.h" +#include "../common/musicmanager.h" + +#include "../UI/uitextbox.h" + +// Platform specific includes for lauching the web browser. +// See AboutState::LaunchBrowser(). +#ifdef _WIN32 +#include "windows.h" +#include "SDL_syswm.h" +#endif + +#ifdef __APPLE__ +#include +#include +#include +#endif +////////////////////////// + + +AboutState* AboutState::m_instance = NULL; + + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +AboutState* AboutState::GetInstance() +{ + if (m_instance == NULL) + { + m_instance = new AboutState(); + + if (m_instance == NULL) + { + exit(1); + } + } + + return m_instance; +} + + +// Initializes the state. +// Loads state specific resources, should be called only once. +void AboutState::Init(Engine* engine) +{ + if (m_initialized) + return; + + m_aboutWindow = new AboutWindow(SurfaceManager::GetInstance()->GetSurface("AboutWindowBackground")); + m_aboutWindow->Align(UIControl::HALN_CENTER, UIControl::VALN_MIDDLE, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2); + + m_initialized = true; +} + + +void AboutState::Enter(Engine* engine) +{ + TRAP(m_initialized == false, "AboutState::Enter() - State has not been initialized"); + + MainWindow* mainWindow = engine->GetMainWindow(); + + m_aboutWindow->SetEnabled(true); + + // Set the buttons: + mainWindow->SetEnabled(false); + + // Grey out the time bar: + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetEnabled(false); + + // Pause the game: + engine->GetGame()->SetPaused(true); + + // Mute alert sound: + SoundManager::GetInstance()->SetVolume("TimeAlert", 0.0f); + + engine->Redraw(); +} + +void AboutState::Exit(Engine* engine) +{ + TRAP(m_initialized == false, "AboutState::Exit() - State has not been initialized"); + + // Restore alert sound + if (!engine->GetMute()) + SoundManager::GetInstance()->SetVolume("TimeAlert", 1.0f); + + m_aboutWindow->SetEnabled(false); +} + +void AboutState::HandleEvents(Engine* engine) +{ + TRAP(m_initialized == false, "AboutState::HandleEvents() - State has not been initialized"); + + // This flag determines whether the screen needs to be redrawn. + bool redraw = false; + + SDL_Event event; + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + // Check for user events: + case SDL_USEREVENT: + switch (event.user.code) + { + // Close the about window: + case EVENT_CLOSE: + engine->PopState(); + break; + + // Website link: + case EVENT_WEBSITE: + LaunchBrowser(APP_URL); + break; + + // Music track over: + case EVENT_TRACK_OVER: + MusicManager::GetInstance()->PlayNextTrack(); + break; + + // Forced redraw: + case EVENT_REDRAW: + redraw = true; + break; + } + break; + + // Send mouse clicks to the game object: + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_aboutWindow->MouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_aboutWindow->MouseDown(event.button.x, event.button.y); + } + break; + + // Mouse motion for hover: + case SDL_MOUSEMOTION: + { + redraw |= m_aboutWindow->Hover(event.motion.x, event.motion.y); + } + break; + + + // Handle keyboard input: + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) // Get the key symbol + { + // Take a screenshot: + case SDLK_F12: + ScreenShot(); + break; + + // Enter or escape close the window: + case SDLK_RETURN: + case SDLK_ESCAPE: + engine->PopState(); + return; + + default: + break; + } + } + break; + + case SDL_QUIT: + engine->PushState(QuitState::GetInstance()); + break; + } + } + + if (redraw) + engine->Redraw(); +} + + +// The computer makes another move. +void AboutState::Update(Engine* engine) +{ + TRAP(m_initialized == false, "AboutState::Update() - State has not been initialized"); + + // Redraw if one of the window's controls requires: + if (m_aboutWindow->Update()) + engine->Redraw(); +} + + +void AboutState::Draw(Engine* engine) +{ + TRAP(m_initialized == false, "AboutState::Draw() - State has not been initialized"); + + engine->GetMainWindow()->Draw(engine->GetScreen()); + engine->GetGame()->Draw(engine->GetScreen()); + m_aboutWindow->Draw(engine->GetScreen()); +} + + +// Cleans up any state specific resources loaded in Init(). +void AboutState::Cleanup(Engine* engine) +{ + TRAP(m_initialized == false, "AboutState::Cleanup() - State has not been initialized"); + + delete m_aboutWindow; + + m_initialized = false; +} + + +// Launch the web browser to the specified URL. +// NOTE: This is the only platform specific piece of code +// in the project since it calls the operating system to launch the +// URL. +// Supported platforms: +// * Win32 +// * OS X (Carbon) +// TODO: Linux etc. +void AboutState::LaunchBrowser(string URL) +{ + +#ifdef _WIN32 + // Get the window handle: + SDL_SysWMinfo info; + SDL_GetWMInfo(&info); + + ShellExecute(info.window, // Handle to a parent window + "open", // The action, or "verb", to be performed + URL.c_str(), // The file on which to execute the specified verb + NULL, // Parameters to be passed to the application + NULL, // Default directory + SW_SHOW); // Activates the window and displays it in its current size and position + +#endif // WIN32 + + +#ifdef __APPLE__ + + CFURLRef url = NULL; + + // Create a string ref of the URL: + CFStringRef urlStr = CFStringCreateWithCString( NULL, URL.c_str(), kCFStringEncodingASCII); + + // Create a URL object: + url = CFURLCreateWithString (NULL, urlStr, NULL); + + // Open the URL: + LSOpenCFURLRef(url, NULL); + + // Release the created resources: + CFRelease(url); + CFRelease(urlStr); + +#endif // __APPLE__ + +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.h new file mode 100644 index 000000000..2c4f8fbea --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/aboutstate.h @@ -0,0 +1,58 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ABOUTSTATE_H_ +#define _ABOUTSTATE_H_ + +// About screen engine state. Singleton. + +#include "../engine/enginestate.h" +#include "../UI/aboutwindow.h" + +using namespace std; + +class AboutState: public EngineState +{ + private: + AboutWindow *m_aboutWindow; // The "About" window + + public: + void Init(Engine* engine); + void Enter(Engine* engine); + void Exit(Engine* engine); + void HandleEvents(Engine* engine); + void Update(Engine* engine); + void Draw(Engine* engine); + void Cleanup(Engine* engine); + + static AboutState* GetInstance(); + + private: + static AboutState* m_instance; + AboutState(){}; + AboutState(const AboutState&); + AboutState& operator= (const AboutState&); + + void LaunchBrowser(string URL); // Launch the web browser to the specified URL +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.cpp new file mode 100644 index 000000000..c902c1b1c --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.cpp @@ -0,0 +1,451 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/engine.h" +#include "../engine/enginestate.h" + +#include "../engine/introstate.h" +#include "../engine/gameonstate.h" +#include "../engine/pausedstate.h" +#include "../engine/gameoverstate.h" +#include "../engine/aboutstate.h" +#include "../engine/highscoresstate.h" +#include "../engine/quitstate.h" + +#include "../common/soundmanager.h" +#include "../common/musicmanager.h" +#include "../common/fontmanager.h" +#include "../common/surfacemanager.h" +#include "../common/effectmanager.h" +#include "../common/trap.h" +#include "../common/filenames.h" + +#include "SDL.h" +#include "SDL_mixer.h" +#include "SDL_ttf.h" +#include "SDL_image.h" +#include +#include // For atoi() + + +// Constructor - initialize SDL and allocate the data members. +Engine::Engine() +{ + m_quit = false; + m_mute = false; + m_redraw = true; + m_screen = NULL; + m_game = NULL; + m_highScores = NULL; + m_mainWindow = NULL; + + // Initialize SDL: + InitSDL(); + + // Show the loading screen: + ShowLoadingScreen(); + + // Setup progress bar: + SDL_Color color = {0, 0, 0, 0}; + SurfaceManager::GetInstance()->AddSurface("TimeBar", "data/interface/time_bar.png"); + m_progessBar.Set(111, 285, SurfaceManager::GetInstance()->GetSurface("TimeBar"), NULL, color); + UpdateProgressBar(0.0f); + + // Load resources: + LoadResources(0.0f, 0.9f); + + // Allocate the game and the main window: + { + m_game = new Game(); + + m_highScores = new HighScores(); + + m_mainWindow = new MainWindow(SurfaceManager::GetInstance()->GetSurface("MainWindowBackground")); + m_mainWindow->SetVisible(true); + } + + + // Initialize the game states while updating the progress bar: + InitStates(0.9f, 0.1f); + + // Initialize effects manager: + EffectManager::GetInstance()->Init(); + + // Show the loading screen for a little while more + SDL_Delay(500); + + // Set initial audio levels: + MusicManager::GetInstance()->SetVolume(0.25f); + SoundManager::GetInstance()->SetVolume(1.0f); + + // Set the initial engine state: + PushState(IntroState::GetInstance()); +} + +// Destructor - deallocate and clean up. +Engine::~Engine() +{ + // Cleanup the game states: + IntroState::GetInstance()->Cleanup(this); + GameOnState::GetInstance()->Cleanup(this); + PausedState::GetInstance()->Cleanup(this); + GameOverState::GetInstance()->Cleanup(this); + AboutState::GetInstance()->Cleanup(this); + HighScoresState::GetInstance()->Cleanup(this); + QuitState::GetInstance()->Cleanup(this); + + // Cleanup local objects: + SDL_FreeSurface(m_screen); + delete m_mainWindow; + delete m_game; + delete m_highScores; + + // Free all the resources handled by the managers: + SurfaceManager::GetInstance()->Cleanup(); + FontManager::GetInstance()->Cleanup(); + SoundManager::GetInstance()->Cleanup(); + EffectManager::GetInstance()->Cleanup(); + MusicManager::GetInstance()->Cleanup(); + + // Cleanup SDL: + CleanupSDL(); +} + + +// The main game loop. +// The engine envokes the current state's +// methodes. +void Engine::Run() +{ + Uint32 prevFrame; // Time of previous rendered frame + + while (m_quit == false) + { + prevFrame = SDL_GetTicks(); + + m_stateStack.back()->Update(this); + + // Redraw only if necessary: + if (m_redraw) + m_stateStack.back()->Draw(this); + + m_redraw = false; + + m_stateStack.back()->HandleEvents(this); + + SDL_Flip(m_screen); // Flip the screen buffers + + // Limit framerate: + if (SDL_GetTicks() - prevFrame < FRAME_DELAY) + SDL_Delay(FRAME_DELAY - (SDL_GetTicks() - prevFrame)); + } + m_stateStack.back()->Exit(this); +} + + +// Quit the game: +void Engine::Quit() +{ + m_quit = true; +} + + +// Mute and unmute: +void Engine::Mute(bool flag) +{ + m_mute = flag; + + if (m_mute) + { + MusicManager::GetInstance()->SetVolume(0.0f); + SoundManager::GetInstance()->SetVolume(0.0f); + } + else + { + MusicManager::GetInstance()->SetVolume(MusicManager::DEFAULT_VOLUME); + SoundManager::GetInstance()->SetVolume(SoundManager::DEFAULT_VOLUME); + } +} + + +// Changes the engine state. +void Engine::ChangeState(EngineState* state) +{ + // Exit the current states in the stack: + while (!m_stateStack.empty()) + { + m_stateStack.back()->Exit(this); + m_stateStack.pop_back(); + } + + // Push the current state, and enter it: + m_stateStack.push_back(state); + m_stateStack.back()->Enter(this); + + m_redraw = true; +} + +// Pushes an engine state on to the state stack. +void Engine::PushState(EngineState* state) +{ + m_stateStack.push_back(state); + m_stateStack.back()->Enter(this); + m_redraw = true; +} + +// Pops an engine state from the state stack. +void Engine::PopState() +{ + // Exit the current state: + if (!m_stateStack.empty()) + { + m_stateStack.back()->Exit(this); + m_stateStack.pop_back(); + } + + // Enter the previous state: + TRAP(m_stateStack.empty() == true, "Engine::PopState() - Trying to pop an empty stack"); + + m_stateStack.back()->Enter(this); + + m_redraw = true; +} + +// Initialize SDL and prepare the screen surface for rendering. +// Returns 0 on success. +void Engine::InitSDL() +{ + const SDL_VideoInfo* vidInfo = NULL; // Information about the current video settings + + // Initialize SDL: + if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) != 0) + { + ERR("Engine::InitSDL() - SDL_Init failed (" << SDL_GetError() << ")"); + } + + // Initialize sound mixer: + if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) != 0) + { + ERR("Engine::InitSDL() - Mix_OpenAudio failed (" << SDL_GetError() << ")"); + } + + // Allocate the audio channels. One for each sound chunk plus one for music: + int numOfSounds = (sizeof(SOUND_RESOURCES) / sizeof(std::string)) / 2; + Mix_AllocateChannels(numOfSounds + 1); + + // Initialize font renderer: + if(TTF_Init() != 0) + { + ERR("Engine::InitSDL() - TTF_Init failed (" << SDL_GetError() << ")"); + } + + // Get video settings info: + if((vidInfo = SDL_GetVideoInfo()) == 0) + { + ERR("Engine::InitSDL() - SDL_GetVideoInfo failed (" << SDL_GetError() << ")"); + } + + // Set the key repeat: + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + + // Enable Unicode keyboard translation. This allows us to obtain + // the character codes corresponding to received keyboard events. + SDL_EnableUNICODE(1); + + // Set the window icon: + // FIX: Looks like an 8 bit image. SDL doesn't support 8 bit alpha on icons. + SDL_Surface *icon = IMG_Load(ICON.c_str()); + SDL_WM_SetIcon(icon, NULL); + SDL_FreeSurface(icon); + + // Set the video mode: + if((m_screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, vidInfo->vfmt->BitsPerPixel, + SDL_HWSURFACE|SDL_HWPALETTE|0)) == 0) /* The code does not support SDL_DOUBLEBUF, I wonder how it worked before */ + { + ERR("Engine::InitSDL() - SDL_SetVideoMode failed (" << SDL_GetError() << ")"); + } + + // Set the window caption: + SDL_WM_SetCaption(CAPTION.c_str(), CAPTION.c_str()); +} + + +// Cleanup SDL: +void Engine::CleanupSDL() +{ + // FIX: This causes a crash sometimes. + Mix_CloseAudio(); + + TTF_Quit(); + SDL_Quit(); +} + + +// Show a loading message while the game is initializing. +void Engine::ShowLoadingScreen() +{ + SDL_Surface *surface = IMG_Load("data/interface/loading.png"); + + TRAP(surface == NULL, "Engine::ShowLoadingScreen() - File not found"); + + SDL_FillRect(m_screen, NULL, 0x000000); + + SDL_BlitSurface(surface, NULL, m_screen, NULL); + + SDL_Flip(m_screen); + + SDL_FreeSurface(surface); +} + +// Updates the loading progress bar. +// The input is a value between 0.0 and 1.0, indicating +// the current progress (1.0 = full bar) +void Engine::UpdateProgressBar(float val) +{ + m_progessBar.SetClipping((Sint16)(SurfaceManager::GetInstance()->GetSurface("TimeBar")->w * val), -1); + m_progessBar.Draw(m_screen); + SDL_Flip(m_screen); +} + + +// Loads game resources while updating the progress bar. +// basePercentage - Initial progress bar position (0.0..1.0) +// prgBarPercentage - What percentage of the progress bar is to be filled +// by the method (0.0..1.0) +void Engine::LoadResources(float basePercentage, float prgBarPercentage) +{ + int numOfGraphics = (sizeof(GRAPHIC_RESOURCES) / sizeof(std::string)) / 2; + int numOfSounds = (sizeof(SOUND_RESOURCES) / sizeof(std::string)) / 2; + int numOfMusic = (sizeof(MUSIC_RESOURCES) / sizeof(std::string)) / 2; + int numOfFonts = (sizeof(FONT_RESOURCES) / sizeof(std::string)) / 3; + + int totalResources = numOfGraphics + numOfSounds + numOfMusic + numOfFonts; + + int resourceIndex = 0; + + // Load graphics: + SurfaceManager *sfcMgr = SurfaceManager::GetInstance(); + for (int i = 0 ; i < numOfGraphics ; ++i) + { + sfcMgr->AddSurface(GRAPHIC_RESOURCES[2 * i], GRAPHIC_RESOURCES [2 * i + 1]); + resourceIndex++; + + //Update progress bar: + UpdateProgressBar(basePercentage + (resourceIndex / (float) totalResources) * prgBarPercentage); + } + + // Load sounds: + SoundManager *sndMgr = SoundManager::GetInstance(); + for (int i = 0 ; i < numOfSounds ; ++i) + { + sndMgr->AddSound(SOUND_RESOURCES[2 * i], SOUND_RESOURCES [2 * i + 1]); + resourceIndex++; + + //Update progress bar: + UpdateProgressBar(basePercentage + (resourceIndex / (float) totalResources) * prgBarPercentage); + } + + // Load music: + MusicManager *musicMgr = MusicManager::GetInstance(); + for (int i = 0 ; i < numOfMusic ; ++i) + { + musicMgr->AddTrack(MUSIC_RESOURCES[2 * i], MUSIC_RESOURCES [2 * i + 1]); + resourceIndex++; + + //Update progress bar: + UpdateProgressBar(basePercentage + (resourceIndex / (float) totalResources) * prgBarPercentage); + } + + // Load fonts: + FontManager *fontMgr = FontManager::GetInstance(); + for (int i = 0 ; i < numOfFonts ; ++i) + { + fontMgr->AddFont(FONT_RESOURCES[3 * i], + FONT_RESOURCES [3 * i + 1], + atoi((FONT_RESOURCES [3 * i + 2]).c_str())); + resourceIndex++; + + //Update progress bar: + UpdateProgressBar(basePercentage + (resourceIndex / (float) totalResources) * prgBarPercentage); + } + + + +} + +// Initializes the game states while updating the progress bar. +// basePercentage - Initial progress bar position (0.0..1.0) +// prgBarPercentage - What percentage of the progress bar is to be filled +// by the method (0.0..1.0) +void Engine::InitStates(float basePercentage, float prgBarPercentage) +{ + int numOfStates = 7; + float step = prgBarPercentage / numOfStates; + + IntroState::GetInstance()->Init(this); + UpdateProgressBar(basePercentage + step * 1.0f); + + GameOnState::GetInstance()->Init(this); + UpdateProgressBar(basePercentage + step * 2.0f); + + PausedState::GetInstance()->Init(this); + UpdateProgressBar(basePercentage + step * 3.0f); + + GameOverState::GetInstance()->Init(this); + UpdateProgressBar(basePercentage + step * 4.0f); + + AboutState::GetInstance()->Init(this); + UpdateProgressBar(basePercentage + step * 5.0f); + + HighScoresState::GetInstance()->Init(this); + UpdateProgressBar(basePercentage + step * 6.0f); + + QuitState::GetInstance()->Init(this); + UpdateProgressBar(basePercentage + step * 7.0f); +} + + +#ifdef WIN32 + +void Engine::LoadWinIcon() +{ + +} + +#endif + +//// +/* +HANDLE LoadImage( HINSTANCE hinst, + LPCTSTR lpszName, + UINT uType, + int cxDesired, + int cyDesired, + UINT fuLoad +); + +lResult = SendMessage(// returns LRESULT in lResult + (HWND) hWndControl, // handle to destination control + (UINT) WM_SETICON, // message ID + (WPARAM) wParam, // = (WPARAM) () wParam; + (LPARAM) lParam // = (LPARAM) () lParam; ); +*/ +/// + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.h new file mode 100644 index 000000000..cb3f25ad0 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/engine.h @@ -0,0 +1,111 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ENGINE_H_ +#define _ENGINE_H_ + +// The game engine + +#include "../common/common.h" +#include "../game/game.h" +#include "../game/highscores.h" +#include "../UI/mainwindow.h" +#include "../UI/gameoverwindow.h" +#include "../UI/uilabel.h" +#include "SDL.h" + +class EngineState; + + +class Engine +{ + private: + Game *m_game; // Game object + HighScores *m_highScores; // High scores table + + MainWindow *m_mainWindow; // The user interface's main window + + UILabel m_progessBar; // Loading progress bar + + SDL_Surface *m_screen; // The screen surface + + vector m_stateStack; // Stack of engine states + + bool m_mute; // Mute flag + bool m_quit; // Quit flag + bool m_redraw; // Redraw screen flag + + public: + Engine(); + ~Engine(); + + // The main loop: + void Run(); + + // Quit the game: + void Quit(); + + // Mute and unmute the game: + void Mute(bool flag); + bool GetMute(){return m_mute;} + + // Forces a redraw: + void Redraw(){m_redraw = true;} + + // State stack operations: + void ChangeState(EngineState* state); + void PushState(EngineState* state); + void PopState(); + + // Accessors: + Game* GetGame(){return m_game;} + HighScores* GetHighScores(){return m_highScores;} + MainWindow* GetMainWindow(){return m_mainWindow;} + SDL_Surface* GetScreen(){return m_screen;} + + // Helper methods: + private: + void InitSDL(); // Initialize SDL + void CleanupSDL(); // Clean up SDL + + // Loading screen: + void ShowLoadingScreen(); // Displays the loading screen + void UpdateProgressBar(float val); // Updates the loading progress bar + + // Load resources into managers: + void LoadResources(float basePercentage, float prgBarPercentage); + void LoadSounds(); + + // Initialize the game states: + void InitStates(float basePercentage, float prgBarPercentage); + + + // Frame rate: + static const Uint32 FPS = 60; // Frames per second + static const Uint32 FRAME_DELAY = (Uint32) (1000 / FPS); // Delay between frames, in ms + +#ifdef WIN32 + void LoadWinIcon(); +#endif + +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/enginestate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/enginestate.h new file mode 100644 index 000000000..066937384 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/enginestate.h @@ -0,0 +1,46 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ENGINESTATE_H_ +#define _ENGINESTATE_H_ + +// A base class for engine states. +// Inspired by http://tonyandpaige.com/tutorials/game1.html +#include "../engine/engine.h" + +class EngineState +{ + public: + virtual void Init(Engine* engine) = 0; + virtual void Enter(Engine* engine) = 0; + virtual void Exit(Engine* engine) = 0; + virtual void HandleEvents(Engine* engine) = 0; + virtual void Update(Engine* engine) = 0; + virtual void Draw(Engine* engine) = 0; + virtual void Cleanup(Engine* engine) = 0; + +protected: + EngineState():m_initialized(false){} // Force the derived classes to be singletons + + bool m_initialized; // Has the state been initialized? +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.cpp new file mode 100644 index 000000000..de005838b --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.cpp @@ -0,0 +1,398 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/gameonstate.h" +#include "../engine/gameoverstate.h" +#include "../engine/pausedstate.h" +#include "../engine/aboutstate.h" +#include "../engine/highscoresstate.h" +#include "../engine/quitstate.h" + +#include "../UI/uibutton.h" +#include "../UI/uilabel.h" + +#include "../common/surfacemanager.h" +#include "../common/fontmanager.h" +#include "../common/effectmanager.h" +#include "../common/musicmanager.h" +#include "../common/soundmanager.h" +#include "../common/events.h" +#include "../common/trap.h" + +#include + +GameOnState* GameOnState::m_instance = NULL; + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +GameOnState* GameOnState::GetInstance() +{ + if (m_instance == NULL) + { + m_instance = new GameOnState(); + + if (m_instance == NULL) + { + exit(1); + } + } + + return m_instance; +} + + +// Initializes the state. +// Loads state specific resources, should be called only once. +void GameOnState::Init(Engine* engine) +{ + if (m_initialized) + return; + + m_initialized = true; + +} + + +void GameOnState::Enter(Engine* engine) +{ + TRAP(m_initialized == false, "GameOnState::Enter() - State has not been initialized"); + + Game *game = engine->GetGame(); + + // Set the buttons: + MainWindow *mainWindow = engine->GetMainWindow(); + mainWindow->SetEnabled(true); + mainWindow->GetButton(MainWindow::BTN_START)->SetState(EVENT_RESTART); + mainWindow->GetButton(MainWindow::BTN_PAUSE)->Normal(); + mainWindow->GetButton(MainWindow::BTN_START)->Normal(); + + // Set the time bar: + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetEnabled(true); + + // Set the score and level labels: + mainWindow->GetLabel(MainWindow::LBL_SCORE)->SetText(UIControl::HALN_LEFT, + "%d", engine->GetGame()->GetScore() % 1000000); + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->SetText(UIControl::HALN_LEFT, + "Level %d", game->GetLevel()); + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->Align(UIControl::HALN_CENTER, + UIControl::VALN_TOP, 94, 44); + + engine->GetGame()->SetPaused(false); + + engine->Redraw(); +} + +void GameOnState::Exit(Engine* engine) +{ + TRAP(m_initialized == false, "GameOnState::Exit() - State has not been initialized"); +} + +void GameOnState::HandleEvents(Engine* engine) +{ + TRAP(m_initialized == false, "GameOnState::HandleEvents() - State has not been initialized"); + + // This flag determines whether the screen needs to be redrawn. + bool redraw = false; + + SDL_Event event; + + Game *game = engine->GetGame(); + MainWindow *mainWindow = engine->GetMainWindow(); + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + // Check for user events: + case SDL_USEREVENT: + redraw |= HandleUserEvents(engine, &event); + break; + + // Window was minimised: + case SDL_ACTIVEEVENT: + if (event.active.state & SDL_APPACTIVE) + if (event.active.gain == 0) + mainWindow->GetButton(MainWindow::BTN_PAUSE)->Click(); + break; + + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= game->Click(event.button.x, event.button.y); + redraw |= mainWindow->MouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= game->Hover(event.button.x, event.button.y); + redraw |= mainWindow->MouseDown(event.button.x, event.button.y); + } + else if (event.button.button == SDL_BUTTON_RIGHT) + { + redraw |= game->RightClick(event.button.x, event.button.y); + } + break; + + // Mouse motion for UI hover: + case SDL_MOUSEMOTION: + { + if( event.motion.state ) + redraw |= game->Hover(event.motion.x, event.motion.y); + redraw |= mainWindow->Hover(event.motion.x, event.motion.y); + } + break; + + + // Handle keyboard input: + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) // Get the key symbol + { + // Pause / resume: + case SDLK_p: + mainWindow->GetButton(MainWindow::BTN_PAUSE)->Click(); + redraw = true; + break; + + // Hint: + case SDLK_h: + game->Hint(); + redraw = true; + break; + + // Quit: + case SDLK_ESCAPE: + engine->PushState(QuitState::GetInstance()); + return; + + // Take a screenshot: + case SDLK_F12: + ScreenShot(); + break; + + default: + break; + } + } + + break; + + case SDL_QUIT: + engine->PushState(QuitState::GetInstance()); + break; + } + } + + if (redraw) + engine->Redraw(); +} + + +void GameOnState::Update(Engine* engine) +{ + TRAP(m_initialized == false, "GameOnState::Update() - State has not been initialized"); + + MainWindow *mainWindow = engine->GetMainWindow(); + Game *game = engine->GetGame(); + + // Update the game: + if (game->Update()) + engine->Redraw(); + + // Update time bar: + float progress = ((float) game->GetTimeLeft()) / Game::TIME_MAX; + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetProgress(progress); + + // Redraw if one of the window's controls requires: + if (mainWindow->Update()) + engine->Redraw(); + + // Update the effects: + if (EffectManager::GetInstance()->Update()) + engine->Redraw(); +} + + +void GameOnState::Draw(Engine* engine) +{ + TRAP(m_initialized == false, "GameOnState::Draw() - State has not been initialized"); + + engine->GetMainWindow()->DrawBackground(engine->GetScreen()); + engine->GetGame()->Draw(engine->GetScreen()); + engine->GetMainWindow()->DrawControls(engine->GetScreen()); + EffectManager::GetInstance()->Draw(engine->GetScreen()); +} + + +// Cleans up any state specific resources loaded in Init(). +void GameOnState::Cleanup(Engine* engine) +{ + TRAP(m_initialized == false, "GameOnState::Cleanup() - State has not been initialized"); + + m_initialized = false; +} + +// Handles user events. +// Returns true if a redraw is necessary. +bool GameOnState::HandleUserEvents(Engine *engine, SDL_Event *event) +{ + bool redraw = false; + + MainWindow *mainWindow = engine->GetMainWindow(); + Game *game = engine->GetGame(); + + switch (event->user.code) + { + // Restart the game: + case EVENT_RESTART: + engine->GetGame()->Restart(); + MusicManager::GetInstance()->PlayNextTrack(); + redraw = true; + break; + + // Hint: + case EVENT_HINT: + game->Hint(); + redraw = true; + break; + + // Mute: + case EVENT_MUTE: + engine->Mute(true); + mainWindow->GetButton(MainWindow::BTN_MUTE)->SetState(EVENT_UNMUTE); + redraw = true; + break; + + // Unmute: + case EVENT_UNMUTE: + engine->Mute(false); + mainWindow->GetButton(MainWindow::BTN_MUTE)->SetState(EVENT_MUTE); + redraw = true; + break; + + // Pause: + case EVENT_PAUSE: + engine->PushState(PausedState::GetInstance()); + break; + + // About: + case EVENT_ABOUT: + engine->PushState(AboutState::GetInstance()); + break; + + // High scores: + case EVENT_HIGH_SCORES: + engine->PushState(HighScoresState::GetInstance()); + break; + + // Game over: + case EVENT_GAME_OVER: + engine->ChangeState(GameOverState::GetInstance()); + break; + + // Rectangle complete: + case EVENT_RECT_COMPLETE: + + // Update score label: + mainWindow->GetLabel(MainWindow::LBL_SCORE)->SetText(UIControl::HALN_LEFT, + "%d", engine->GetGame()->GetScore() % 1000000); + + // Add the score effect: + EffectManager::GetInstance()->AddScoreEffect(event); + + break; + + // Level up: + case EVENT_NEW_LEVEL: + // Update level label: + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->SetText(UIControl::HALN_LEFT, + "Level %d", game->GetLevel()); + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->Align(UIControl::HALN_CENTER, + UIControl::VALN_TOP, 94, 44); + + // Add the new level effect: + EffectManager::GetInstance()->AddLevelEffect(game->GetLevel()); + + // Play sound: + if (game->GetLevel() != 1) + SoundManager::GetInstance()->PlaySound("NewLevel"); + + break; + + // Perfect rectangle: + case EVENT_PERFECT: + + // Add the prefect rectangle effect: + EffectManager::GetInstance()->AddPerfectEffect(); + + //SoundManager::GetInstance()->PlaySound("PerfectRectangle"); + + break; + + + // Music track over: + case EVENT_TRACK_OVER: + MusicManager::GetInstance()->PlayNextTrack(); + break; + + // Forced redraw: + case EVENT_REDRAW: + redraw = true; + break; + + // Running low on time: + case EVENT_TIME_LOW: + + // Flash the time bar: + engine->GetMainWindow()->GetProgressBar(MainWindow::PRG_TIMEBAR)->Flash(true); + + // Play the alert sound: + SoundManager::GetInstance()->PlaySound("TimeAlert", true); + + // Disable the hint button: + mainWindow->GetButton(MainWindow::BTN_HINT)->SetEnabled(false); + engine->Redraw(); + + break; + + // Time is no longer running low: + case EVENT_TIME_OK: + + // Stop flashing the time bar: + engine->GetMainWindow()->GetProgressBar(MainWindow::PRG_TIMEBAR)->Flash(false); + + // Stop the alert sound: + SoundManager::GetInstance()->StopSound("TimeAlert"); + + // Enable the hint button: + mainWindow->GetButton(MainWindow::BTN_HINT)->SetEnabled(true); + engine->Redraw(); + + break; + + default: + break; + } + + return redraw; +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.h new file mode 100644 index 000000000..a5dc522d4 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameonstate.h @@ -0,0 +1,54 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _GAMESONTATE_H_ +#define _GAMEONSTATE_H_ + +// Game engine state. Singleton. +#include "../engine/enginestate.h" + +class GameOnState: public EngineState +{ + private: + + public: + void Init(Engine* engine); + void Enter(Engine* engine); + void Exit(Engine* engine); + void HandleEvents(Engine* engine); + void Update(Engine* engine); + void Draw(Engine* engine); + void Cleanup(Engine* engine); + + static GameOnState* GetInstance(); + + private: + static GameOnState* m_instance; + GameOnState(){}; + GameOnState(const GameOnState&); + GameOnState& operator= (const GameOnState&); + + // Handle user events: + bool HandleUserEvents(Engine *engine, SDL_Event *event); +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.cpp new file mode 100644 index 000000000..d0b140542 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.cpp @@ -0,0 +1,327 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/gameoverstate.h" +#include "../engine/gameonstate.h" +#include "../engine/highscoresstate.h" + +#include "../UI/uitextbox.h" + +#include "../game/highscores.h" + +#include "../common/musicmanager.h" +#include "../common/soundmanager.h" +#include "../common/surfacemanager.h" +#include "../common/effectmanager.h" + +#include "../common/events.h" +#include "../common/trap.h" + +#include "SDL_ttf.h" + +#include +using namespace std; + +GameOverState* GameOverState::m_instance = NULL; + + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +GameOverState* GameOverState::GetInstance() +{ + if (m_instance == NULL) + { + m_instance = new GameOverState(); + + if (m_instance == NULL) + { + exit(1); + } + } + + return m_instance; +} + + +// Initializes the state. +// Loads state specific resources, should be called only once. +void GameOverState::Init(Engine* engine) +{ + if (m_initialized) + return; + + m_gameOverWindow = new GameOverWindow(SurfaceManager::GetInstance()->GetSurface("GameOverWindowBackground")); + m_gameOverWindow->Align(UIControl::HALN_CENTER, UIControl::VALN_MIDDLE, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2); + + m_initialized = true; +} + + +// Set the button modes: +void GameOverState::Enter(Engine* engine) +{ + TRAP(m_initialized == false, "GameOverState::Enter() - State has not been initialized"); + + engine->GetGame()->SetPaused(true); + m_stats = engine->GetGame()->GetStats(); + + // Disable main window: + MainWindow *mainWindow = engine->GetMainWindow(); + mainWindow->SetEnabled(false); + + // Grey out the time bar: + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetEnabled(false); + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->Flash(false); + + // Stop the alert sound: + SoundManager::GetInstance()->StopSound("TimeAlert"); + + // Play the game over sound: + SoundManager::GetInstance()->PlaySound("GameOver"); + + // Add the text effect: + EffectManager::GetInstance()->AddGameOverEffect(); + + // Enable the main controls: (WHY?) + m_gameOverWindow->SetEnabled(true); + + // Check if the current game's score qualifies for the high score table: + if (engine->GetHighScores()->Qualifies(engine->GetGame()->GetScore())) + { + m_gameOverWindow->GetControl(GameOverWindow::LBL_SCORE)->SetVisible(false); + m_gameOverWindow->GetControl(GameOverWindow::LBL_CONGRATS)->SetVisible(true); + m_gameOverWindow->GetControl(GameOverWindow::TXT_NAME)->SetVisible(true); + m_gameOverWindow->GetControl(GameOverWindow::BTN_OK)->SetVisible(true); + m_gameOverWindow->GetControl(GameOverWindow::BTN_QUIT)->SetVisible(false); + m_gameOverWindow->GetControl(GameOverWindow::BTN_RESTART)->SetVisible(false); + + // Clear the text box: + UITextBox *temp = (UITextBox*) m_gameOverWindow->GetControl(GameOverWindow::TXT_NAME); + temp->Clear(); + + // Play the high score sound: + SoundManager::GetInstance()->PlaySound("HighScore"); + } + else // Score does NOT qualify + { + m_gameOverWindow->GetControl(GameOverWindow::LBL_SCORE)->SetVisible(true); + m_gameOverWindow->GetControl(GameOverWindow::LBL_CONGRATS)->SetVisible(false); + m_gameOverWindow->GetControl(GameOverWindow::TXT_NAME)->SetVisible(false); + m_gameOverWindow->GetControl(GameOverWindow::BTN_OK)->SetVisible(false); + m_gameOverWindow->GetControl(GameOverWindow::BTN_QUIT)->SetVisible(true); + m_gameOverWindow->GetControl(GameOverWindow::BTN_RESTART)->SetVisible(true); + + // Update the score label: + m_gameOverWindow->GetLabel(GameOverWindow::LBL_SCORE)->SetText( + UIControl::HALN_LEFT, + "Your final score is %s", + (HighScores::AddCommas(engine->GetGame()->GetScore())).c_str()); + m_gameOverWindow->GetLabel(GameOverWindow::LBL_SCORE)->Align(UIControl::HALN_CENTER, UIControl::VALN_MIDDLE, + 320, 170); + } + + // Render stats: + m_gameOverWindow->GetLabel(GameOverWindow::LBL_STATS_VAL)->SetText( + UIControl::HALN_RIGHT, + "%d\n%02d:%02d\n%d\n%d\n%.1f\n%d\n%d", + engine->GetGame()->GetLevel(), // Final level + (m_stats.TotalTime % 3600000) / 60000, // Minutes + (m_stats.TotalTime % 60000) / 1000, // Seconds + m_stats.MarblesCleared, // Marbles cleared + m_stats.RectCleared, // Rectangles cleared + (m_stats.RectCleared == 0) ? 0.0f : m_stats.MarblesCleared / (float) m_stats.RectCleared, // Avg. rect size + m_stats.BestMove, // Best move + m_stats.NumOfPerfect); // Number of perfect moves + m_gameOverWindow->GetLabel(GameOverWindow::LBL_STATS_VAL)->Align(UIControl::HALN_RIGHT, UIControl::VALN_BOTTOM, + 436, 337); + + engine->Redraw(); +} + +void GameOverState::Exit(Engine* engine) +{ + TRAP(m_initialized == false, "GameOverState::Exit() - State has not been initialized"); + + m_gameOverWindow->SetEnabled(false); +} + +void GameOverState::HandleEvents(Engine* engine) +{ + TRAP(m_initialized == false, "GameOverState::HandleEvents() - State has not been initialized"); + + // This flag determines whether the screen needs to be redrawn. + bool redraw = false; + + SDL_Event event; + + Game *game = engine->GetGame(); + UITextBox *textBox = (UITextBox *) m_gameOverWindow->GetControl(GameOverWindow::TXT_NAME); + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + // Check for user events: + case SDL_USEREVENT: + switch (event.user.code) + { + // OK - show high scores + case EVENT_CLOSE: + // Add the current game to the high scores table: + engine->GetHighScores()->Add(textBox->GetText(), game->GetScore()); + + engine->ChangeState(HighScoresState::GetInstance()); + break; + + case EVENT_RESTART: + + // Stop the time bar from flashing: + engine->GetMainWindow()->GetProgressBar(MainWindow::PRG_TIMEBAR)->Flash(false); + + // Restart the music: + MusicManager::GetInstance()->PlayNextTrack(); + + engine->GetGame()->Restart(); + + EffectManager::GetInstance()->AddLevelEffect(1); + + engine->ChangeState(GameOnState::GetInstance()); + + break; + + // Music track over: + case EVENT_TRACK_OVER: + MusicManager::GetInstance()->PlayNextTrack(); + break; + + // Forced redraw: + case EVENT_REDRAW: + redraw = true; + break; + } + break; + + // Send mouse clicks to the game object: + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_gameOverWindow->MouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_gameOverWindow->MouseDown(event.button.x, event.button.y); + } + break; + + // Mouse motion for hover: + case SDL_MOUSEMOTION: + { + redraw |= m_gameOverWindow->Hover(event.motion.x, event.motion.y); + } + break; + + // Handle keyboard input: + case SDL_KEYDOWN: + { + redraw |= m_gameOverWindow->KeyDown(&event.key); + + switch (event.key.keysym.sym) // Get the key symbol + { + // Take a screenshot: + case SDLK_F12: + ScreenShot(); + break; + + // Enter or escape close the window: + case SDLK_RETURN: + case SDLK_ESCAPE: + if (engine->GetHighScores()->Qualifies(engine->GetGame()->GetScore())) + { + // Add the current game to the high scores table: + engine->GetHighScores()->Add(textBox->GetText(), game->GetScore()); + + engine->ChangeState(HighScoresState::GetInstance()); + return; + } + else + { + MusicManager::GetInstance()->PlayNextTrack(); + engine->GetGame()->Restart(); + EffectManager::GetInstance()->AddLevelEffect(1); + engine->ChangeState(GameOnState::GetInstance()); + break; + } + + default: + break; + } + } + break; + + case SDL_QUIT: + engine->Quit(); + break; + } + } + + if (redraw) + engine->Redraw(); +} + + +void GameOverState::Update(Engine* engine) +{ + TRAP(m_initialized == false, "GameOverState::Update() - State has not been initialized"); + + // Redraw if one of the window's controls requires: + bool redraw = EffectManager::GetInstance()->Update(); + redraw |= m_gameOverWindow->Update(); + + if (redraw) + engine->Redraw(); +} + + +void GameOverState::Draw(Engine* engine) +{ + TRAP(m_initialized == false, "GameOverState::Draw() - State has not been initialized"); + + SDL_Surface *screen = engine->GetScreen(); + + engine->GetMainWindow()->Draw(screen); + engine->GetGame()->Draw(screen); + EffectManager::GetInstance()->Draw(screen); + m_gameOverWindow->Draw(screen); +} + + +// Cleans up any state specific resources loaded in Init(). +void GameOverState::Cleanup(Engine* engine) +{ + TRAP(m_initialized == false, "GameOverState::Cleanup() - State has not been initialized"); + + delete m_gameOverWindow; + + m_initialized = false; +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.h new file mode 100644 index 000000000..b9b1dc13f --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/gameoverstate.h @@ -0,0 +1,55 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _GAMEOVERSTATE_H_ +#define _GAMEOVERSTATE_H_ + +// Intro engine state. Singleton. +#include "../engine/enginestate.h" +#include "../UI/gameoverwindow.h" +#include "../game/game.h" +#include "SDL.h" + +class GameOverState: public EngineState +{ + private: + Statistics m_stats; // Game statistics + GameOverWindow *m_gameOverWindow; // Game over window + + public: + void Init(Engine* engine); + void Enter(Engine* engine); + void Exit(Engine* engine); + void HandleEvents(Engine* engine); + void Update(Engine* engine); + void Draw(Engine* engine); + void Cleanup(Engine* engine); + + static GameOverState* GetInstance(); + + private: + static GameOverState* m_instance; + GameOverState(){}; + GameOverState(const GameOverState&); + GameOverState& operator= (const GameOverState&); +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.cpp new file mode 100644 index 000000000..817c380ee --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.cpp @@ -0,0 +1,282 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/highscoresstate.h" +#include "../engine/gameonstate.h" + +#include "../common/fontmanager.h" +#include "../common/surfacemanager.h" +#include "../common/soundmanager.h" + +#include "../UI/mainwindow.h" + +#include "../common/trap.h" +#include "../common/events.h" + + +HighScoresState* HighScoresState::m_instance = NULL; + + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +HighScoresState* HighScoresState::GetInstance() +{ + if (m_instance == NULL) + { + m_instance = new HighScoresState(); + + if (m_instance == NULL) + { + exit(1); + } + } + + return m_instance; +} + + +// Initializes the state. +// Loads state specific resources, should be called only once. +void HighScoresState::Init(Engine* engine) +{ + if (m_initialized) + return; + + m_highScoresWindow = new HighScoresWindow(SurfaceManager::GetInstance()->GetSurface("HighScoresWindowBackground")); + m_highScoresWindow->Align(UIControl::HALN_CENTER, UIControl::VALN_MIDDLE, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2); + + m_initialized = true; +} + + +void HighScoresState::Enter(Engine* engine) +{ + TRAP(m_initialized == false, "HighScoresState::Enter() - State has not been initialized"); + + MainWindow* mainWindow = engine->GetMainWindow(); + + m_highScoresWindow->SetEnabled(true); + + // Set the buttons: + mainWindow->SetEnabled(false); + + if (engine->GetGame()->GetTimeLeft() > 0) // Game on + { + m_highScoresWindow->GetControl(HighScoresWindow::BTN_CLOSE)->SetVisible(true); + m_highScoresWindow->GetControl(HighScoresWindow::BTN_QUIT)->SetVisible(false); + m_highScoresWindow->GetControl(HighScoresWindow::BTN_RESTART)->SetVisible(false); + } + else // Game over + { + m_highScoresWindow->GetControl(HighScoresWindow::BTN_CLOSE)->SetVisible(false); + m_highScoresWindow->GetControl(HighScoresWindow::BTN_QUIT)->SetVisible(true); + m_highScoresWindow->GetControl(HighScoresWindow::BTN_RESTART)->SetVisible(true); + } + + // Grey out the time bar: + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetEnabled(false); + + // Pause the game: + engine->GetGame()->SetPaused(true); + + // Populate the table labels: + PopulateLabels(engine); + + // Mute alert sound: + SoundManager::GetInstance()->SetVolume("TimeAlert", 0.0f); + + engine->Redraw(); +} + +void HighScoresState::Exit(Engine* engine) +{ + TRAP(m_initialized == false, "HighScoresState::Exit() - State has not been initialized"); + + // Restore alert sound: + if (!engine->GetMute()) + SoundManager::GetInstance()->SetVolume("TimeAlert", 1.0f); + + m_highScoresWindow->SetEnabled(false); +} + +void HighScoresState::HandleEvents(Engine* engine) +{ + TRAP(m_initialized == false, "HighScoresState::HandleEvents() - State has not been initialized"); + + // This flag determines whether the screen needs to be redrawn. + bool redraw = false; + + SDL_Event event; + Game *game = engine->GetGame(); + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + // Check for user events: + case SDL_USEREVENT: + switch (event.user.code) + { + // Close the about window: + case EVENT_CLOSE: + engine->PopState(); + break; + + case EVENT_RESTART: + engine->GetGame()->Restart(); + engine->ChangeState(GameOnState::GetInstance()); + break; + + // Forced redraw: + case EVENT_REDRAW: + redraw = true; + break; + } + break; + + // Send mouse clicks to the game object: + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_highScoresWindow->MouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_highScoresWindow->MouseDown(event.button.x, event.button.y); + } + break; + + // Mouse motion for hover: + case SDL_MOUSEMOTION: + { + redraw |= m_highScoresWindow->Hover(event.motion.x, event.motion.y); + } + break; + + + // Handle keyboard input: + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) // Get the key symbol + { + // Take a screenshot: + case SDLK_F12: + ScreenShot(); + break; + + // Enter or escape close the window: + case SDLK_RETURN: + case SDLK_ESCAPE: + if (game->GetTimeLeft() > 0) + { + engine->PopState(); + return; + } + else // Game over + { + engine->GetGame()->Restart(); + engine->ChangeState(GameOnState::GetInstance()); + } + + default: + break; + } + } + break; + + case SDL_QUIT: + engine->Quit(); + break; + } + } + + if (redraw) + engine->Redraw(); +} + + +// The computer makes another move. +void HighScoresState::Update(Engine* engine) +{ + TRAP(m_initialized == false, "HighScoresState::Update() - State has not been initialized"); + + // Redraw if one of the window's controls requires: + if (m_highScoresWindow->Update()) + engine->Redraw(); +} + + +void HighScoresState::Draw(Engine* engine) +{ + TRAP(m_initialized == false, "HighScoresState::Draw() - State has not been initialized"); + + engine->GetMainWindow()->Draw(engine->GetScreen()); + engine->GetGame()->Draw(engine->GetScreen()); + m_highScoresWindow->Draw(engine->GetScreen()); +} + + +// Cleans up any state specific resources loaded in Init(). +void HighScoresState::Cleanup(Engine* engine) +{ + TRAP(m_initialized == false, "HighScoresState::Cleanup() - State has not been initialized"); + + delete m_highScoresWindow; + + m_initialized = false; +} + + +// Populates the labels making up the high scores table. +void HighScoresState::PopulateLabels(Engine* engine) +{ + HighScores *highScores = engine->GetHighScores(); + + // Name labels vector: + vector namesVec = + m_highScoresWindow->GetControlVector(HighScoresWindow::VEC_NAMES); + + // Scores labels vector: + vector scoresVec = + m_highScoresWindow->GetControlVector(HighScoresWindow::VEC_SCORES); + + UILabel *nameLabel, *scoreLabel; + for (Uint16 i = 0 ; i < highScores->GetSize() ; ++i) + { + scoreLabel = static_cast(scoresVec[i]); + scoreLabel->SetText(UILabel::HALN_LEFT, highScores->GetScore(i)); + scoreLabel->Align(UIControl::HALN_RIGHT, UIControl::VALN_TOP, 435, 136 + 20 * i); + + nameLabel = static_cast(namesVec[i]); + string name = highScores->GetName(i); + nameLabel->SetText(UILabel::HALN_LEFT, name); + + // If the name is too long to fit, trim it and add ellipsis and try again. + while (nameLabel->GetX() + nameLabel->GetWidth() >= scoreLabel->GetX() - 8) + { + name = name.substr(0, name.length() - 1); + nameLabel->SetText(UILabel::HALN_LEFT, "%s...", name.c_str()); + } + } +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.h new file mode 100644 index 000000000..f54ac2a2a --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/highscoresstate.h @@ -0,0 +1,55 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _HIGHSCORESSTATE_H_ +#define _HIGHSCORESSTATE_H_ + +// About screen engine state. Singleton. + +#include "../engine/enginestate.h" +#include "../UI/highscoreswindow.h" + +class HighScoresState: public EngineState +{ + private: + HighScoresWindow *m_highScoresWindow; // The high scores window + + public: + void Init(Engine* engine); + void Enter(Engine* engine); + void Exit(Engine* engine); + void HandleEvents(Engine* engine); + void Update(Engine* engine); + void Draw(Engine* engine); + void Cleanup(Engine* engine); + + static HighScoresState* GetInstance(); + + private: + static HighScoresState* m_instance; + HighScoresState(){}; + HighScoresState(const HighScoresState&); + HighScoresState& operator= (const HighScoresState&); + + void PopulateLabels(Engine* engine); // Populates the labels making up the high scores table +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.cpp new file mode 100644 index 000000000..aebcd8609 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.cpp @@ -0,0 +1,394 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/introstate.h" +#include "../engine/gameonstate.h" +#include "../engine/aboutstate.h" +#include "../engine/highscoresstate.h" +#include "../engine/quitstate.h" + +#include "../UI/mainwindow.h" + +#include "../common/surfacemanager.h" +#include "../common/effectmanager.h" +#include "../common/musicmanager.h" +#include "../common/soundmanager.h" + +#include "../common/trap.h" +#include "../common/events.h" + +IntroState* IntroState::m_instance = NULL; + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +IntroState* IntroState::GetInstance() +{ + if (m_instance == NULL) + { + m_instance = new IntroState(); + + if (m_instance == NULL) + { + exit(1); + } + } + + return m_instance; +} + + +// Initializes the state. +// Loads state specific resources, should be called only once. +void IntroState::Init(Engine* engine) +{ + if (m_initialized) + return; + + m_initialized = true; + + // Restart the game: + engine->GetGame()->Restart(); +} + + +void IntroState::Enter(Engine* engine) +{ + TRAP(m_initialized == false, "IntroState::Enter() - State has not been initialized"); + + m_iLastMove = SDL_GetTicks(); + Game *game = engine->GetGame(); + + MainWindow *mainWindow = engine->GetMainWindow(); + mainWindow->SetEnabled(true); + mainWindow->GetButton(MainWindow::BTN_START)->SetState(EVENT_START); + mainWindow->GetButton(MainWindow::BTN_PAUSE)->Disable(); + mainWindow->GetButton(MainWindow::BTN_HINT)->Disable(); + mainWindow->GetButton(MainWindow::BTN_START)->Flash(UIButton::FLASH_INTERVAL); + + // Set the time bar: + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetEnabled(true); + + // Set the score and level labels: + mainWindow->GetLabel(MainWindow::LBL_SCORE)->SetText(UIControl::HALN_LEFT, + "%d", engine->GetGame()->GetScore() % 1000000); + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->SetText(UIControl::HALN_LEFT, + "Level %d", game->GetLevel()); + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->Align(UIControl::HALN_CENTER, + UIControl::VALN_TOP, 94, 44); + + engine->GetGame()->SetPaused(false); + + game->ClearSelection(); + m_selection.Clear(); + m_iMarbleIndex = 0; + + if (MusicManager::GetInstance()->IsPlaying() == false) + MusicManager::GetInstance()->PlayRandomTrack(); + + engine->Redraw(); +} + +void IntroState::Exit(Engine* engine) +{ + TRAP(m_initialized == false, "IntroState::Exit() - State has not been initialized"); + + // Restart the game: + engine->GetGame()->Restart(); + +} + + +void IntroState::HandleEvents(Engine* engine) +{ + TRAP(m_initialized == false, "IntroState::HandleEvents() - State has not been initialized"); + + // This flag determines whether the screen needs to be redrawn. + bool redraw = false; + + SDL_Event event; + MainWindow *mainWindow = engine->GetMainWindow(); + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + // Check for user events: + case SDL_USEREVENT: + redraw |= HandleUserEvents(engine, &event); + break; + + // Send mouse clicks to the game object: + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= mainWindow->MouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= mainWindow->MouseDown(event.button.x, event.button.y); + } + break; + + // Mouse motion for hover: + case SDL_MOUSEMOTION: + { + redraw |= mainWindow->Hover(event.motion.x, event.motion.y); + } + break; + + + // Handle keyboard input: + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) // Get the key symbol + { + // Quit: + case SDLK_ESCAPE: + engine->PushState(QuitState::GetInstance()); + return; + + // Take a screenshot: + case SDLK_F12: + ScreenShot(); + break; + + // Any other key starts the game: + default: + engine->ChangeState(GameOnState::GetInstance()); + break; + } + } + break; + + case SDL_QUIT: + engine->PushState(QuitState::GetInstance()); + break; + } + } + + if (redraw) + engine->Redraw(); +} + + +// The computer makes another move. +void IntroState::Update(Engine* engine) +{ + TRAP(m_initialized == false, "IntroState::Update() - State has not been initialized"); + + MainWindow *mainWindow = engine->GetMainWindow(); + Game *game = engine->GetGame(); + + // Update the game: + if (game->Update()) + engine->Redraw(); + + if (m_selection.GetSize() == 0) + game->GetRectangle(&m_selection); + + // Update time bar: + float progress = ((float) game->GetTimeLeft()) / Game::TIME_MAX; + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetProgress(progress); + + // If enough time has passed since the last move, make aother one: + if (SDL_GetTicks() - m_iLastMove >= INTRO_DELAY && game->CanMove()) + { + // Translate to screen coordinates to simulate a user's click: + game->Click(m_selection[m_iMarbleIndex].x * MARBLE_IMAGE_SIZE + BOARD_X, + m_selection[m_iMarbleIndex].y * MARBLE_IMAGE_SIZE + BOARD_Y); + + m_iLastMove = SDL_GetTicks(); + + m_iMarbleIndex++; + + if (m_iMarbleIndex > 3) + { + m_iMarbleIndex = 0; + + // Get a new rectangle: + game->GetRectangle(&m_selection); + } + + engine->Redraw(); + } + + // Redraw if one of the window's controls requires: + if (mainWindow->Update()) + engine->Redraw(); + + // Update the effects: + if (EffectManager::GetInstance()->Update()) + engine->Redraw(); +} + + +void IntroState::Draw(Engine* engine) +{ + TRAP(m_initialized == false, "IntroState::Draw() - State has not been initialized"); + + engine->GetMainWindow()->DrawBackground(engine->GetScreen()); + engine->GetGame()->Draw(engine->GetScreen()); + engine->GetMainWindow()->DrawControls(engine->GetScreen()); + EffectManager::GetInstance()->Draw(engine->GetScreen()); +} + + +// Cleans up any state specific resources loaded in Init(). +void IntroState::Cleanup(Engine* engine) +{ + TRAP(m_initialized == false, "IntroState::Cleanup() - State has not been initialized"); + + m_initialized = false; +} + + +// Handles user events. +// Returns true if a redraw is necessary. +bool IntroState::HandleUserEvents(Engine *engine, SDL_Event *event) +{ + bool redraw = false; + + MainWindow *mainWindow = engine->GetMainWindow(); + Game *game = engine->GetGame(); + + switch (event->user.code) + { + // Start the game: + case EVENT_START: + MusicManager::GetInstance()->PlayNextTrack(); + engine->ChangeState(GameOnState::GetInstance()); + break; + + // Mute: + case EVENT_MUTE: + engine->Mute(true); + mainWindow->GetButton(MainWindow::BTN_MUTE)->SetState(EVENT_UNMUTE); + redraw = true; + break; + + // Unmute: + case EVENT_UNMUTE: + engine->Mute(false); + mainWindow->GetButton(MainWindow::BTN_MUTE)->SetState(EVENT_MUTE); + redraw = true; + break; + + // About: + case EVENT_ABOUT: + engine->PushState(AboutState::GetInstance()); + break; + + // High scores: + case EVENT_HIGH_SCORES: + engine->PushState(HighScoresState::GetInstance()); + break; + + // Game over: + case EVENT_GAME_OVER: + m_iLastMove = SDL_GetTicks(); // Time of last move + m_iMarbleIndex = 0; // Index of marble within selection (0..3) + m_selection.Clear(); + game->Restart(); + redraw = true; + break; + + // Score was changed: + case EVENT_RECT_COMPLETE: + // Update score label: + mainWindow->GetLabel(MainWindow::LBL_SCORE)->SetText(UIControl::HALN_LEFT, + "%d", engine->GetGame()->GetScore() % 1000000); + + // Add the score effect: + EffectManager::GetInstance()->AddScoreEffect(event); + + break; + + // Level up: + case EVENT_NEW_LEVEL: + // Update level label: + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->SetText(UIControl::HALN_LEFT, + "Level %d", game->GetLevel()); + mainWindow->GetLabel(MainWindow::LBL_LEVEL)->Align(UIControl::HALN_CENTER, + UIControl::VALN_TOP, 94, 44); + + // Add the new level effect: + EffectManager::GetInstance()->AddLevelEffect(game->GetLevel()); + + // Play sound: + if (game->GetLevel() != 1) + SoundManager::GetInstance()->PlaySound("NewLevel"); + + break; + + // Perfect rectangle: + case EVENT_PERFECT: + + // Add the prefect rectangle effect: + EffectManager::GetInstance()->AddPerfectEffect(); + + break; + + // Music track over: + case EVENT_TRACK_OVER: + MusicManager::GetInstance()->PlayNextTrack(); + break; + + // Running low on time: + case EVENT_TIME_LOW: + + // Flash the time bar: + engine->GetMainWindow()->GetProgressBar(MainWindow::PRG_TIMEBAR)->Flash(true); + + // Play the alert sound: + SoundManager::GetInstance()->PlaySound("TimeAlert", true); + + engine->Redraw(); + + break; + + // Time is no longer running low: + case EVENT_TIME_OK: + + // Stop flashing the time bar: + engine->GetMainWindow()->GetProgressBar(MainWindow::PRG_TIMEBAR)->Flash(false); + + // Stop the alert sound: + SoundManager::GetInstance()->StopSound("TimeAlert"); + + engine->Redraw(); + + break; + + // Forced redraw: + case EVENT_REDRAW: + redraw = true; + break; + + default: + break; + } + + return redraw; +} + + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.h new file mode 100644 index 000000000..644a16875 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/introstate.h @@ -0,0 +1,63 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _INTROSTATE_H_ +#define _INTROSTATE_H_ + +// Intro engine state. Singleton. +// Simulate a game. + +#include "../engine/enginestate.h" +#include "../game/selection.h" +#include "../UI/uilabel.h" +#include "SDL.h" + +class IntroState: public EngineState +{ + private: + Selection m_selection; // Selection for simulated game + Uint32 m_iLastMove; // Time of last move + int m_iMarbleIndex; // Index of marble within selection (0..3) + static const int INTRO_DELAY = 750; // Delay between simulated clicks + + public: + void Init(Engine* engine); + void Enter(Engine* engine); + void Exit(Engine* engine); + void HandleEvents(Engine* engine); + void Update(Engine* engine); + void Draw(Engine* engine); + void Cleanup(Engine* engine); + + static IntroState* GetInstance(); + + private: + static IntroState* m_instance; + IntroState(){}; + IntroState(const IntroState&); + IntroState& operator= (const IntroState&); + + // Handle user events: + bool HandleUserEvents(Engine *engine, SDL_Event *event); +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.cpp new file mode 100644 index 000000000..b1b18cfd2 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.cpp @@ -0,0 +1,255 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/pausedstate.h" +#include "../engine/aboutstate.h" +#include "../engine/highscoresstate.h" +#include "../engine/quitstate.h" + +#include "../common/surfacemanager.h" +#include "../common/musicmanager.h" +#include "../common/soundmanager.h" + +#include "../UI/mainwindow.h" + +#include "../common/trap.h" +#include "../common/events.h" + +PausedState* PausedState::m_instance = NULL; + + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +PausedState* PausedState::GetInstance() +{ + if (m_instance == NULL) + { + m_instance = new PausedState(); + + if (m_instance == NULL) + { + exit(1); + } + } + + return m_instance; +} + + +// Initializes the state. +// Loads state specific resources, should be called only once. +void PausedState::Init(Engine* engine) +{ + if (m_initialized) + return; + + m_initialized = true; +} + + +void PausedState::Enter(Engine* engine) +{ + TRAP(m_initialized == false, "PausedState::Enter() - State has not been initialized"); + + MainWindow* mainWindow = engine->GetMainWindow(); + + // Set the buttons: + mainWindow->SetEnabled(true); + mainWindow->GetButton(MainWindow::BTN_PAUSE)->SetState(EVENT_RESUME); + mainWindow->GetButton(MainWindow::BTN_HINT)->Disable(); + mainWindow->GetButton(MainWindow::BTN_START)->Disable(); + mainWindow->GetButton(MainWindow::BTN_PAUSE)->Flash(UIButton::FLASH_INTERVAL); + + // Grey out the time bar: + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetEnabled(false); + + // Pause the game: + engine->GetGame()->SetPaused(true); + + // Pause the music: + MusicManager::GetInstance()->Pause(); + + // Mute alert sound: + SoundManager::GetInstance()->SetVolume("TimeAlert", 0.0f); + + // Redraw: + engine->Redraw(); +} + +void PausedState::Exit(Engine* engine) +{ + TRAP(m_initialized == false, "PausedState::Exit() - State has not been initialized"); + + // Reset the pause button: + engine->GetMainWindow()->GetButton(MainWindow::BTN_PAUSE)->SetState(EVENT_PAUSE); + + // Resume the music: + MusicManager::GetInstance()->Resume(); + + // Restore alert sound + if (!engine->GetMute()) + SoundManager::GetInstance()->SetVolume("TimeAlert", 1.0f); +} + +void PausedState::HandleEvents(Engine* engine) +{ + TRAP(m_initialized == false, "PausedState::HandleEvents() - State has not been initialized"); + + // This flag determines whether the screen needs to be redrawn. + bool redraw = false; + + SDL_Event event; + MainWindow *mainWindow = engine->GetMainWindow(); + Game *game = engine->GetGame(); + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + // Check for user events: + case SDL_USEREVENT: + switch (event.user.code) + { + // Resume the game: + case EVENT_RESUME: + game->SetPaused(false); + engine->PopState(); + break; + + // About: + case EVENT_ABOUT: + engine->PushState(AboutState::GetInstance()); + break; + + // High scores: + case EVENT_HIGH_SCORES: + engine->PushState(HighScoresState::GetInstance()); + break; + + // Mute: + case EVENT_MUTE: + engine->Mute(true); + mainWindow->GetButton(MainWindow::BTN_MUTE)->SetState(EVENT_UNMUTE); + redraw = true; + break; + + // Unmute: + case EVENT_UNMUTE: + engine->Mute(false); + mainWindow->GetButton(MainWindow::BTN_MUTE)->SetState(EVENT_MUTE); + redraw = true; + break; + + // Forced redraw: + case EVENT_REDRAW: + redraw = true; + break; + } + break; + + // Send mouse clicks to the game object: + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= mainWindow->MouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= mainWindow->MouseDown(event.button.x, event.button.y); + } + break; + + // Mouse motion for hover: + case SDL_MOUSEMOTION: + { + redraw |= mainWindow->Hover(event.motion.x, event.motion.y); + } + break; + + + // Handle keyboard input: + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) // Get the key symbol + { + // Quit: + case SDLK_ESCAPE: + engine->PushState(QuitState::GetInstance()); + return; + + // Take a screenshot: + case SDLK_F12: + ScreenShot(); + break; + + // P - resume the game: + case SDLK_p: + game->SetPaused(false); + engine->PopState(); + break; + + default: + break; + } + } + break; + + case SDL_QUIT: + engine->PushState(QuitState::GetInstance()); + break; + } + } + + if (redraw) + engine->Redraw(); +} + + +// The computer makes another move. +void PausedState::Update(Engine* engine) +{ + TRAP(m_initialized == false, "PausedState::Update() - State has not been initialized"); + + // Redraw if one of the window's controls requires: + if (engine->GetMainWindow()->Update()) + engine->Redraw(); +} + + +void PausedState::Draw(Engine* engine) +{ + TRAP(m_initialized == false, "PausedState::Draw() - State has not been initialized"); + + engine->GetMainWindow()->Draw(engine->GetScreen()); + engine->GetGame()->Draw(engine->GetScreen()); +} + + +// Cleans up any state specific resources loaded in Init(). +void PausedState::Cleanup(Engine* engine) +{ + TRAP(m_initialized == false, "PausedState::Cleanup() - State has not been initialized"); + + m_initialized = false; +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.h new file mode 100644 index 000000000..977762a99 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/pausedstate.h @@ -0,0 +1,53 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _PAUSEDSTATE_H_ +#define _PAUSEDSTATE_H_ + +// Game paused engine state. Singleton. + +#include "../engine/enginestate.h" + +class PausedState: public EngineState +{ + private: + + + public: + void Init(Engine* engine); + void Enter(Engine* engine); + void Exit(Engine* engine); + void HandleEvents(Engine* engine); + void Update(Engine* engine); + void Draw(Engine* engine); + void Cleanup(Engine* engine); + + static PausedState* GetInstance(); + + private: + static PausedState* m_instance; + PausedState(){}; + PausedState(const PausedState&); + PausedState& operator= (const PausedState&); +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.cpp new file mode 100644 index 000000000..521d641de --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.cpp @@ -0,0 +1,214 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../engine/quitstate.h" +#include "../common/fontmanager.h" +#include "../UI/mainwindow.h" +#include "../common/trap.h" +#include "../common/events.h" +#include "../common/surfacemanager.h" +#include "../common/soundmanager.h" + +QuitState* QuitState::m_instance = NULL; + + +// Returns an m_instance of the class. If no m_instance exists, the method +// creates a new one. +QuitState* QuitState::GetInstance() +{ + if (m_instance == NULL) + { + m_instance = new QuitState(); + + if (m_instance == NULL) + { + exit(1); + } + } + + return m_instance; +} + + +// Initializes the state. +// Loads state specific resources, should be called only once. +void QuitState::Init(Engine* engine) +{ + if (m_initialized) + return; + + m_quitWindow = new QuitWindow(SurfaceManager::GetInstance()->GetSurface("QuitWindowBackground")); + m_quitWindow->Align(UIControl::HALN_CENTER, UIControl::VALN_MIDDLE, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2); + + m_initialized = true; +} + + +void QuitState::Enter(Engine* engine) +{ + TRAP(m_initialized == false, "QuitState::Enter() - State has not been initialized"); + + MainWindow* mainWindow = engine->GetMainWindow(); + + m_quitWindow->SetEnabled(true); + + // Set the buttons: + mainWindow->SetEnabled(false); + + // Grey out the time bar: + mainWindow->GetProgressBar(MainWindow::PRG_TIMEBAR)->SetEnabled(false); + + // Pause the game: + engine->GetGame()->SetPaused(true); + + // Mute alert sound: + SoundManager::GetInstance()->SetVolume("TimeAlert", 0.0f); + + engine->Redraw(); +} + +void QuitState::Exit(Engine* engine) +{ + TRAP(m_initialized == false, "QuitState::Exit() - State has not been initialized"); + + // Restore alert sound: + if (!engine->GetMute()) + SoundManager::GetInstance()->SetVolume("TimeAlert", 1.0f); + + m_quitWindow->SetEnabled(false); +} + +void QuitState::HandleEvents(Engine* engine) +{ + TRAP(m_initialized == false, "QuitState::HandleEvents() - State has not been initialized"); + + // This flag determines whether the screen needs to be redrawn. + bool redraw = false; + + SDL_Event event; + + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + // Check for user events: + case SDL_USEREVENT: + switch (event.user.code) + { + // Close the about window: + case EVENT_CLOSE: + engine->PopState(); + break; + + // Forced redraw: + case EVENT_REDRAW: + redraw = true; + break; + } + break; + + // Send mouse clicks to the game object: + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_quitWindow->MouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == SDL_BUTTON_LEFT) + { + redraw |= m_quitWindow->MouseDown(event.button.x, event.button.y); + } + break; + + // Mouse motion for hover: + case SDL_MOUSEMOTION: + { + redraw |= m_quitWindow->Hover(event.motion.x, event.motion.y); + } + break; + + + // Handle keyboard input: + case SDL_KEYDOWN: + { + switch (event.key.keysym.sym) // Get the key symbol + { + // Take a screenshot: + case SDLK_F12: + ScreenShot(); + break; + + // Enter or escape close the window: + case SDLK_RETURN: + case SDLK_ESCAPE: + engine->PopState(); + return; + + default: + break; + } + } + break; + + // Quit: + case SDL_QUIT: + engine->Quit(); + break; + } + } + + if (redraw) + engine->Redraw(); +} + + +// The computer makes another move. +void QuitState::Update(Engine* engine) +{ + TRAP(m_initialized == false, "QuitState::Update() - State has not been initialized"); + + // Redraw if one of the window's controls requires: + if (m_quitWindow->Update()) + engine->Redraw(); +} + + +void QuitState::Draw(Engine* engine) +{ + TRAP(m_initialized == false, "QuitState::Draw() - State has not been initialized"); + + engine->GetMainWindow()->Draw(engine->GetScreen()); + engine->GetGame()->Draw(engine->GetScreen()); + m_quitWindow->Draw(engine->GetScreen()); +} + + +// Cleans up any state specific resources loaded in Init(). +void QuitState::Cleanup(Engine* engine) +{ + TRAP(m_initialized == false, "QuitState::Cleanup() - State has not been initialized"); + + delete m_quitWindow; + + m_initialized = false; +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.h new file mode 100644 index 000000000..db493406b --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/engine/quitstate.h @@ -0,0 +1,54 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _QUITSTATE_H_ +#define _QUITSTATE_H_ + +// About screen engine state. Singleton. + +#include "../engine/enginestate.h" +#include "../UI/quitwindow.h" + +class QuitState: public EngineState +{ + private: + QuitWindow *m_quitWindow; // The quit dialog window + + public: + void Init(Engine* engine); + void Enter(Engine* engine); + void Exit(Engine* engine); + void HandleEvents(Engine* engine); + void Update(Engine* engine); + void Draw(Engine* engine); + void Cleanup(Engine* engine); + + static QuitState* GetInstance(); + + private: + static QuitState* m_instance; + QuitState(){}; + QuitState(const QuitState&); + QuitState& operator= (const QuitState&); +}; + + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.cpp new file mode 100644 index 000000000..fc25f58d5 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.cpp @@ -0,0 +1,740 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../game/board.h" +#include +#include +#include +#include + +#include "../game/selection.h" +#include "../common/soundmanager.h" +#include "../common/surfacemanager.h" + +#include "../common/events.h" +#include "../common/trap.h" + +using namespace std; + + +// Constructor +Board::Board() +{ + // Init the PRNG: + srand((unsigned)time(NULL)); + + // Load the marble surfaces: + SurfaceManager* surfaceMgr = SurfaceManager::GetInstance(); + + m_normalSurfaces[BLUE] = surfaceMgr->GetSurface("MarbleNormalBlue"); + m_normalSurfaces[GREEN] = surfaceMgr->GetSurface("MarbleNormalGreen"); + m_normalSurfaces[RED] = surfaceMgr->GetSurface("MarbleNormalRed"); + m_normalSurfaces[YELLOW] = surfaceMgr->GetSurface("MarbleNormalYellow"); + + m_selectedSurfaces[BLUE] = surfaceMgr->GetSurface("MarbleSelectedBlue"); + m_selectedSurfaces[GREEN] = surfaceMgr->GetSurface("MarbleSelectedGreen"); + m_selectedSurfaces[RED] = surfaceMgr->GetSurface("MarbleSelectedRed"); + m_selectedSurfaces[YELLOW] = surfaceMgr->GetSurface("MarbleSelectedYellow"); + + m_pausedSurface = surfaceMgr->GetSurface("MarblePaused"); + + m_isDropping = false; + m_isAnimating = false; + m_Highlighted.x = -1; + + Reset(); +} + + +// Destructor - free resources +Board::~Board() +{ + +} + + +// Resets the board. +void Board::Reset() +{ +#ifdef MARBLE_DROP + if (m_isDropping) + SDL_FreeSurface(m_droppingRectSfc); +#endif + + m_isDropping = false; + m_isAnimating = false; + m_flashStart = 0; + +#ifdef MARBLE_DROP + m_dropStartTime = 0; + m_dropVelocity = 0.0f; + m_droppingRectSfc = NULL; +#endif + + // Mark all the marbles as visible: + memset(m_isVisible, 1, sizeof(bool) * BOARD_SIZE * BOARD_SIZE); + + // Populate the board: + do + { + Populate(0, 0, BOARD_SIZE - 1, BOARD_SIZE - 1); + } while (!ContainsRectangle()); +} + + +// Returns the color of a marble: +COLOR Board::GetMarbleColor(int x, int y) +{ + // Sanity check: + if (x < 0 || y < 0 || x >= BOARD_SIZE || y >= BOARD_SIZE) + return NUM_OF_COLORS; + + return m_marbles[x][y]; +} + + +// Returns a marble's color: +COLOR Board::GetMarbleColor(Coordinate coord) +{ + return GetMarbleColor(coord.x, coord.y); +} + + +// Flash a rectangle. +void Board::Flash(Coordinate coord1, Coordinate coord2) +{ + // Sanity check: + TRAP(coord1.x < 0 || coord1.y < 0 || coord2.x >= BOARD_SIZE || coord2.y >= BOARD_SIZE || + coord1.x >= coord2.x || coord1.y >= coord2.y, "Board::Flash() - Invalid arguments"); + + m_isFlashing = true; + m_flashColor = m_marbles[coord1.x][coord1.y]; + m_flashCoord1 = coord1; + m_flashCoord2 = coord2; + m_flashStart = SDL_GetTicks(); + + // Force redraw: + PushUserEvent(EVENT_REDRAW); +} + + +// Clears a rectangle, and starts the dropping animation for +// the marbles that will fill in the void. +void Board::ClearRectangle(Coordinate coord1, Coordinate coord2) +{ + // Sanity check: + TRAP(coord1.x < 0 || coord1.y < 0 || coord2.x >= BOARD_SIZE || coord2.y >= BOARD_SIZE || + coord1.x >= coord2.x || coord1.y >= coord2.y, "Board::ClearRectangle() - Invalid arguments"); + + // Setup flashing: + Flash(coord1, coord2); + + // Start animating: + m_isAnimating = true; + +#ifdef MARBLE_DROP + // Save the affected rectangle (cleared + marbles above): + m_coordTL.x = coord1.x; m_coordTL.y = 0; // Top left + m_coordBR.x = coord2.x; m_coordBR.y = coord2.y; // Bottom right + + // Make the rectangle and the marbles above it invisible. + ChangeVisibility(m_coordTL, m_coordBR, false); + + // Drop the rectangle to fill in the void, and randomize the new void: + DropRectLogic(coord1, m_coordBR); + + // Render the surface used in the dropping animation: + RenderDroppingRect(m_coordTL, m_coordBR); + + // Set the dropping rectangle surface's location: + m_dropRectX = (Sint16)(BOARD_X + (coord1.x * MARBLE_IMAGE_SIZE) - (MARBLE_IMAGE_DELTA / 2)); + m_dropRectY = (Sint16)(BOARD_Y - ((coord2.y - coord1.y + 1) * MARBLE_IMAGE_SIZE) - MARBLE_IMAGE_DELTA / 2); + + // Calcualte where to stop dropping: + m_dropMaxY = BOARD_Y; + +#else + // Repopulate while making sure the board contains a rectangle: + do { + Populate(coord1.x, coord1.y, coord2.x, coord2.y); + } while (!ContainsRectangle()); + +#endif // MARBLE_DROP +} + + + +// Fills the argument vector of vectors of coordinates with the +// coordinates of up to num valid rectangles. +// The method returns the number of valid rectangles found. +// If a_opCoordVect is NULL, the rectangles are just counted. +// If num is 0 or less, the method processes all of the +// board's rectangles. +int Board::GetRectangles(vector > *a_opCoordVect, int num) +{ + a_opCoordVect->clear(); + + Coordinate l_oCoord; + int l_iCount = 0; + + for (int i = 0 ; i < BOARD_SIZE - 1 ; ++i) + for (int j = 0 ; j < BOARD_SIZE - 1 ; ++j) + { + COLOR l_eColor = m_marbles[i][j]; + + // Keep moving to the right, until a marble of the same color is found. + int X = -1; + for (int k = j + 1 ; k < BOARD_SIZE ; ++k) + if (m_marbles[i][k] == l_eColor) + { + X = k; + break; + } + + // If no match found, continue with next marble. + if (X == -1) + continue; + + // Keep moving down, until a marble of the same color is found. + int Y = -1; + for (int k = i + 1 ; k < BOARD_SIZE ; ++k) + if (m_marbles[k][j] == l_eColor) + { + Y = k; + break; + } + + // If no match found, continue with next marble. + if (Y == -1) + continue; + + // Check the fourth marble: + if (m_marbles[Y][X] == l_eColor) + { + + if (a_opCoordVect != NULL) + { + vector rect; + + l_oCoord.x = i ; l_oCoord.y = j; + rect.push_back(l_oCoord); + + l_oCoord.x = Y ; l_oCoord.y = j; + rect.push_back(l_oCoord); + + l_oCoord.x = i ; l_oCoord.y = X; + rect.push_back(l_oCoord); + + l_oCoord.x = Y ; l_oCoord.y = X; + rect.push_back(l_oCoord); + + a_opCoordVect->push_back(rect); + } + + l_iCount++; + if (num > 0 && (int) l_iCount == num) + return l_iCount; + } + } + + return l_iCount; + +} + +// Gets a valid rectangle. +// Returns false if no rectangle found. +bool Board::GetRectangle(Selection* selection) +{ + if (selection != NULL) + selection->Clear(); + + for (int i = 0 ; i < BOARD_SIZE - 1 ; ++i) + for (int j = 0 ; j < BOARD_SIZE - 1 ; ++j) + { + COLOR l_eColor = m_marbles[i][j]; + + // Keep moving to the right, until a marble of the same color is found. + int X = -1; + for (int k = j + 1 ; k < BOARD_SIZE ; ++k) + if (m_marbles[i][k] == l_eColor) + { + X = k; + break; + } + + // If no match found, continue with next marble. + if (X == -1) + continue; + + // Keep moving down, until a marble of the same color is found. + int Y = -1; + for (int k = i + 1 ; k < BOARD_SIZE ; ++k) + if (m_marbles[k][j] == l_eColor) + { + Y = k; + break; + } + + // If no match found, continue with next marble. + if (Y == -1) + continue; + + // Check the fourth marble: + if (m_marbles[Y][X] == l_eColor) + { + // Populate the selection: + if (selection != NULL) + { + selection->Add(i, j, this); + selection->Add(Y, j, this); + selection->Add(i, X, this); + selection->Add(Y, X, this); + } + + return true; + } + } + + // If we are here, no match was found. + return false; +} + + +// Does the board contain a rectangle? +bool Board::ContainsRectangle() +{ + return GetRectangle(NULL); +} + + +// Update the board. +// If the board is flashing, push a redraw event. +bool Board::Update() +{ + bool redraw = false; + Uint32 flashElapsed = SDL_GetTicks() - m_flashStart; // Time elapsed since last flash + +#ifdef MARBLE_DROP + // Handle dropping rectangle animation: + if (m_isDropping) + { + // Update the velocity, as a function of m_gravity and time: + m_dropVelocity += ((SDL_GetTicks() - m_dropStartTime) / 1000.0f) * RECT_DROP_GRAVITY; + //m_dropVelocity += ((SDL_GetTicks() - m_dropStartTime) / 1000.0f) * 0.75f; + + // Update the location: + Sint16 temp = m_dropRectY; + m_dropRectY += (Sint16) m_dropVelocity; + + // Check if the rectangle has fallen into place: + if (m_dropRectY >= m_dropMaxY) + { + m_dropRectY = m_dropMaxY; + m_isDropping = false; + m_isAnimating = false; + + // Make the marbles visible again: + ChangeVisibility(m_coordTL, m_coordBR, true); + + // Free the dropping surfaces: + SDL_FreeSurface(m_droppingRectSfc); + SDL_FreeSurface(m_droppingRectSfcPaused); + + // Play the sound: + SoundManager::GetInstance()->PlaySound("RectangleDrop"); + } + + // Redraw only if the rectangle's location has actually changed: + return (temp != m_dropRectY); + } +#endif // MARBLE DROP + + // Handle flashing rectangle: + if (m_isAnimating && flashElapsed <= FLASH_DURATION) + { + // Determine the flashing status: + if (flashElapsed < FLASH_DURATION && ((flashElapsed / (FLASH_DURATION / FLASH_COUNT)) % 2) == 0) // Flashing + { + if (!m_isFlashing) // ... but was not flashing before + redraw = true; + + m_isFlashing = true; + } + else // Not flashing + { + if (m_isFlashing) // ... but was flashing before + redraw = true; + + m_isFlashing = false; + } + } + +#ifdef MARBLE_DROP + // If flash is over, start dropping: + else if (m_isAnimating && !m_isDropping && flashElapsed > FLASH_DURATION) + { + // Start dropping: + m_isDropping = true; + m_dropVelocity = 0.0f; + m_dropStartTime = SDL_GetTicks(); + } +#else + // Turn off animation flag if flash time has expired: + else if (m_isAnimating && flashElapsed > FLASH_DURATION) + m_isAnimating = false; +#endif + + return redraw; +} + + +// Converts a rectangle's board coordinates to its location on screen, in pixels. +void Board::CoordToPixels(Coordinate *coord1, Coordinate *coord2, + Uint16 *x1, Uint16 *y1, Uint16 *x2, Uint16 *y2) +{ + if (coord1 == NULL || coord2 == NULL || x1 == NULL || x2 == NULL || y1 == NULL || y2 == NULL) + return; + + // Upper left corner: + *x1 = (Sint16)(BOARD_X + coord1->x * MARBLE_IMAGE_SIZE); + *y1 = (Sint16)(BOARD_Y + coord1->y * MARBLE_IMAGE_SIZE); + + // Lower right corner: + *x2 = (Sint16)(BOARD_X + (coord2->x + 1) * MARBLE_IMAGE_SIZE); + *y2 = (Sint16)(BOARD_Y + (coord2->y + 1) * MARBLE_IMAGE_SIZE); +} + + +// Converts a rectangle's screen location, in pixels, to its board coordinates. +void Board::PixelsToCoord(Coordinate *coord1, Coordinate *coord2, + Uint16 *x1, Uint16 *y1, Uint16 *x2, Uint16 *y2) +{ + if (coord1 == NULL || coord2 == NULL || x1 == NULL || x2 == NULL || y1 == NULL || y2 == NULL) + return; + + // Upper left corner: + coord1->x = (*x1 - BOARD_X) / MARBLE_IMAGE_SIZE; + coord1->y = (*y1 - BOARD_Y) / MARBLE_IMAGE_SIZE; + + // Lower right corner: + coord2->x = (*x2 - BOARD_X) / MARBLE_IMAGE_SIZE; + coord2->y = (*y2 - BOARD_Y) / MARBLE_IMAGE_SIZE; +} + + +// Converts a rectangle's board coordinates to its location on screen, in pixels. +// The result is stored in an SDL_Rect structure. +void Board::CoordToSDLRect(Coordinate *coord1, Coordinate *coord2, SDL_Rect *rect) +{ + if (coord1 == NULL || coord2 == NULL) + return; + + Uint16 x1, y1, x2, y2; + + CoordToPixels(coord1, coord2, &x1, &y1, &x2, &y2); + + rect->x = x1; + rect->y = y1; + rect->w = x2 - x1; + rect->h = y2 - y1; +} + + +// Draws the board to screen: +void Board::Draw(SDL_Surface *screen, Selection *selection, bool paused) +{ + SDL_Rect rect = {0, 0, 0, 0}; + Uint32 flashElapsed = SDL_GetTicks() - m_flashStart; // Time elapsed since last flash + +#ifdef MARBLE_DROP + // Draw dropping rectangle: + if (m_isAnimating)//m_isDropping) + { + rect.x = m_dropRectX; + rect.y = m_dropRectY; + + if (paused) + SDL_BlitSurface(m_droppingRectSfcPaused, NULL, screen, &rect); + else + SDL_BlitSurface(m_droppingRectSfc, NULL, screen, &rect); + } +#endif // MARBLE_DROP + + // Draw the marbles: + for (int i = 0 ; i < BOARD_SIZE ; ++i) + for (int j = 0 ; j < BOARD_SIZE ; ++j) + { + rect.x = (Sint16) (BOARD_X + i * MARBLE_IMAGE_SIZE - (m_normalSurfaces[0]->w - MARBLE_IMAGE_SIZE) / 2); + rect.y = (Sint16) (BOARD_Y + j * MARBLE_IMAGE_SIZE - (m_normalSurfaces[0]->h - MARBLE_IMAGE_SIZE) / 2); + + if (!paused) + { + // Flash: + if (flashElapsed < FLASH_DURATION + && m_flashCoord1.x <= i && m_flashCoord2.x >= i + && m_flashCoord1.y <= j && m_flashCoord2.y >= j) + { + if (!m_isFlashing) + SDL_BlitSurface(m_normalSurfaces[m_flashColor], NULL, screen, &rect); + else + SDL_BlitSurface(m_selectedSurfaces[m_flashColor], NULL, screen, &rect); + + continue; + } + + + // Don't render invisible marbles (unless flashing): + if (!m_isVisible[i][j]) + continue; + + // Selected: + else if (selection->IsSelected(i, j)) // Marble is selected + SDL_BlitSurface(m_selectedSurfaces[m_marbles[i][j]], NULL, screen, &rect); + /* + else if ( m_Highlighted == Coordinate(i, j) ) // Marble is highlighted + SDL_BlitSurface(m_selectedSurfaces[m_marbles[i][j]], NULL, screen, &rect); + */ + // Normal: + else + SDL_BlitSurface(m_normalSurfaces[m_marbles[i][j]], NULL, screen, &rect); + } + else // Game is paused, use greyed out marbles + if (m_isVisible[i][j]) + SDL_BlitSurface(m_pausedSurface, NULL, screen, &rect); + } + if( m_Highlighted.x >=0 && m_Highlighted.y >=0 ) + { + SDL_Rect r, r2; + CoordToSDLRect(&m_Highlighted, &m_Highlighted, &r); + r.x += MARBLE_IMAGE_SIZE / 2; + r.y += MARBLE_IMAGE_SIZE / 2; + enum {LINE_WIDTH = 4}; + r2.x = r.x - LINE_WIDTH/2; + r2.y = r.y - MARBLE_IMAGE_SIZE * 2; + r2.w = LINE_WIDTH; + r2.h = MARBLE_IMAGE_SIZE * 4; + SDL_FillRect(screen, &r2, SDL_MapRGB(screen->format, 255, 255, 128)); + r2.x = r.x - MARBLE_IMAGE_SIZE * 2; + r2.y = r.y - LINE_WIDTH/2; + r2.w = MARBLE_IMAGE_SIZE * 4; + r2.h = LINE_WIDTH; + SDL_FillRect(screen, &r2, SDL_MapRGB(screen->format, 255, 255, 128)); + } +} + +// Populates a section of the board with random marbles: +void Board::Populate(int x0, int y0, int x1, int y1) +{ + // Sanity check: + TRAP(x0 < 0 || y0 < 0 || x1 >= BOARD_SIZE || y1 >= BOARD_SIZE + || x0 >= x1 || y0 >= y1, "Board::Populate() - Invalid arguments"); + + for (int i = x0 ; i <= x1 ; ++i) + for (int j = y0 ; j <= y1 ; ++j) + m_marbles[i][j] = static_cast(rand() % (NUM_OF_MARBLE_COLORS)); +} + +void Board::Highlight(Coordinate c) +{ + m_Highlighted = c; +}; + +////////////// Marble drop methods - disabled by default //////////////// + +#ifdef MARBLE_DROP + +// Changes a rectangle's visibility. +void Board::ChangeVisibility(Coordinate coord1, Coordinate coord2, bool visible) +{ + TRAP(coord1.x < 0 || coord1.y < 0 || coord2.x >= BOARD_SIZE || coord2.y >= BOARD_SIZE || + coord1.x >= coord2.x || coord1.y >= coord2.y, "Board::ChangeVisibility() - Invalid arguments"); + + for (int i = coord1.x ; i <= coord2.x ; ++i) + for (int j = coord1.y ; j <= coord2.y ; ++j) + m_isVisible[i][j] = visible; +} + + +// Eliminates the given rectangle, drops the marbles above it +// to fill in the void, and fills what's left with new marbles. +// This method is LOGICAL, and not visual. +// +// To illustrate, lets define two rectangles. +// Rectangle A is the rectangle being cleared, whose coordinates +// are the method's arguments. +// Rectangle B is a rectangle of exisitng marbles, located between +// the top of A and the board's top. It has the same horizontal +// size a A. +// Rectangle C is composed of the "new" marbles, filling up the +// void left. It has the same dimensions as A. +// +// Step 1: Copy B into A, starting from the bottom. +// Step 2: Randomize C. +// +// Before: Step 1: Step 2: +// +// ...BBBB... ...BBBB... ...CCCC... +// ...AAAA... ...AAAA... ...CCCC... +// ...AAAA... ...BBBB... ...BBBB... +// .......... .......... .......... +// +void Board::DropRectLogic(Coordinate coord1, Coordinate coord2) +{ + TRAP(coord1.x < 0 || coord1.y < 0 || coord2.x >= BOARD_SIZE || coord2.y >= BOARD_SIZE || + coord1.x >= coord2.x || coord1.y >= coord2.y, "Board::DropRectLogic() - Invalid arguments"); + + /* + ////// +#ifdef _DEBUG + ScreenShot("DropRectLogic.bmp"); + cout << "(" << coord1.x << "," << coord1.y << ") - (" << coord2.x << "," << coord2.y << ")" << endl; + PrintBoard(&coord1, &coord2); + cout << endl; +#endif + //////// + */ + + // Get the rectangles' heights: + int hA = coord2.y - coord1.y + 1; + int hB = coord1.y; + + // Step 1: + for (int j = coord2.y ; j > coord2.y - hB ; --j) + for (int i = coord1.x ; i <= coord2.x ; ++i) + m_marbles[i][j] = m_marbles[i][j - hA]; + + // Step 2: + // Repopulate while making sure the board contains a rectangle: + do { + Populate(coord1.x, 0, coord2.x, hA - 1); + } while (!ContainsRectangle()); + + /* + ////// +#ifdef _DEBUG + PrintBoard(&coord1, &coord2); +#endif + ////// + */ +} + + +// Renders a rectangle of marbles to an SDL surface. +// The method renders two versions of the surface - paused and unpaused. +void Board::RenderDroppingRect(Coordinate coord1, Coordinate coord2) +{ + TRAP(coord1.x < 0 || coord1.y < 0 || coord2.x >= BOARD_SIZE || coord2.y >= BOARD_SIZE || + coord1.x >= coord2.x || coord1.y >= coord2.y, "Board::RenderDroppingRect() - Invalid arguments"); + + // Calculate surface dimensions: + Uint16 width = (Uint16) ((coord2.x - coord1.x + 1) * MARBLE_IMAGE_SIZE + MARBLE_IMAGE_DELTA); + Uint16 height = (Uint16) ((coord2.y - coord1.y + 1) * MARBLE_IMAGE_SIZE + MARBLE_IMAGE_DELTA); + + + // Create the new surface: + m_droppingRectSfc = SDL_CreateRGBSurface( + m_normalSurfaces[BLUE]->flags, + width, + height, + m_normalSurfaces[BLUE]->format->BitsPerPixel, + m_normalSurfaces[BLUE]->format->Rmask, + m_normalSurfaces[BLUE]->format->Gmask, + m_normalSurfaces[BLUE]->format->Bmask, + m_normalSurfaces[BLUE]->format->Amask); + + // Create the puased version of the surface + m_droppingRectSfcPaused = SDL_CreateRGBSurface( + m_normalSurfaces[BLUE]->flags, + width, + height, + m_normalSurfaces[BLUE]->format->BitsPerPixel, + m_normalSurfaces[BLUE]->format->Rmask, + m_normalSurfaces[BLUE]->format->Gmask, + m_normalSurfaces[BLUE]->format->Bmask, + m_normalSurfaces[BLUE]->format->Amask); + + TRAP(m_droppingRectSfc == NULL || m_droppingRectSfcPaused == NULL, + "Board::RenderDroppingRect() - Could not create surface"); + + // Blit the marbles on to the surface: + SDL_Rect rect = {0, 0, 0, 0}; + SDL_Rect rect1 = {0, 0, 0, 0}; + for (int i = coord1.x ; i <= coord2.x ; ++i) + for (int j = coord1.y ; j <= coord2.y ; ++j) + { + rect.x = rect1.x = (Sint16)((i - coord1.x) * MARBLE_IMAGE_SIZE); + rect.y = rect1.y = (Sint16)((j - coord1.y) * MARBLE_IMAGE_SIZE); + + // Normal surface: + SurfaceManager::Blit( + m_normalSurfaces[m_marbles[i][j]], // Source - a single marble + m_droppingRectSfc, // Destination - the dropping rect surface + 1.0f, // Alpha + &rect); // Location, relative to the destination + + // Paused surface: + SurfaceManager::Blit( + m_pausedSurface, // Source - paused marble surface + m_droppingRectSfcPaused, // Destination - the dropping rect surface + 1.0f, // Alpha + &rect1); // Location, relative to the destination + } +} + +#endif // MARBLE_DROP + + +#ifdef _DEBUG +// Prints the board to the console: +void Board::PrintBoard(Coordinate *coord1, Coordinate *coord2) +{ + bool inRect; + + for (int i = 0 ; i < BOARD_SIZE ; i++) + { + for (int j = 0 ; j < BOARD_SIZE ; j++) + { + if (coord1 && coord2 && j >= coord1->x && j <= coord2->x && i >= coord1->y && i <= coord2->y) + inRect = true; + else + inRect = false; + + switch (m_marbles[j][i]) + { + case BLUE: + cout << (inRect ? "B" : "b"); + break; + case YELLOW: + cout << (inRect ? "Y" : "y"); + break; + case RED: + cout << (inRect ? "R" : "r"); + break; + case GREEN: + cout << (inRect ? "G" : "g"); + break; + default: + cout << "!"; + } + } + cout << endl; + } +} +#endif // _DEBUG \ No newline at end of file diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.h new file mode 100644 index 000000000..d8a4f038c --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/board.h @@ -0,0 +1,153 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// The game board. + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include +#include +#include "../common/common.h" + +class Selection; + +using namespace std; + +// Marble coordinate: +struct Coordinate +{ + int x; + int y; + Coordinate(int _x = -1, int _y = -1): x(_x), y(_y) {}; + bool operator== ( const Coordinate & c ) + { + return x == c.x && y == c.y; + } +}; + +// Marble colors: +enum COLOR {BLUE, GREEN, RED, YELLOW, NUM_OF_COLORS}; +static const int NUM_OF_MARBLE_COLORS = NUM_OF_COLORS; + +// Size of a marble image (in pixels): +static const Uint16 MARBLE_IMAGE_SIZE = 44; + +// This is the difference between the actual size of the marble image, and its +// "logical" size, which is used to position it on screen. +static const Uint16 MARBLE_IMAGE_DELTA = 64 - 44; + +// Gravity affecting dropping marble rectangles, in pixels per second per second: +static const float RECT_DROP_GRAVITY = 0.75f; + +// Board dimensions and location: +static const int BOARD_SIZE = 10; // Game board size, in marbles. The board is square. +static const Uint16 BORDER_SIZE = 8; // Size of window border, in pixels +static Uint16 BOARD_X = SCREEN_WIDTH - BOARD_SIZE * MARBLE_IMAGE_SIZE - BORDER_SIZE; // = 192 +static Uint16 BOARD_Y = BORDER_SIZE; // = 8 + +// Rectangle flash: +static const int FLASH_DURATION = 300; // Duration of rectangle flash sequnece, in ms +static const int FLASH_COUNT = 3; // Number of flashes in a flash sequence + + +class Board +{ + private: + COLOR m_marbles[BOARD_SIZE][BOARD_SIZE]; // The board's contents + bool m_isVisible[BOARD_SIZE][BOARD_SIZE]; // Marbles' visibility + SDL_Surface *m_normalSurfaces[NUM_OF_COLORS]; // Normal marbles' surfaces + SDL_Surface *m_selectedSurfaces[NUM_OF_COLORS]; // Selected marbles' surfaces + SDL_Surface *m_pausedSurface; // Surface for greyed out marble + + // Marble flash: + bool m_isFlashing; // Are we currently flashing + COLOR m_flashColor; // Color of flashing rectangle + Uint32 m_flashStart; // Time flashing started + Coordinate m_flashCoord1, m_flashCoord2; // Flashing rectangle coordinates + Coordinate m_Highlighted; + + // Drop animation: + bool m_isAnimating; // Are we curretly animating (flashing or dropping) + bool m_isDropping; // Is a rectangle currently dropping? + +#ifdef MARBLE_DROP + SDL_Surface *m_droppingRectSfc; // Dropping rectangle surface + SDL_Surface *m_droppingRectSfcPaused; // Dropping rectangle surface (for paused game) + Sint16 m_dropRectX, m_dropRectY; // Dropping rectangle's location + float m_dropVelocity; // Dropping rectangle's velocity + Sint16 m_dropMaxY; // Where to stop the dropping rectangle + Uint32 m_dropStartTime; // Drop Starting time + Coordinate m_coordTL, m_coordBR; // Coordinates of affected rectangle +#endif + + public: + Board(); + ~Board(); + + void Reset(); // Resets the board + + void Populate(int x0, int y0, int x1, int y1); // Populates a section of the board with random marbles + + COLOR GetMarbleColor(int x, int y); // Returns the color of a marble + COLOR GetMarbleColor(Coordinate coord); + + int GetRectangles(vector > *a_opCoordVect, int num = -1); // Returns a vector of N valid rects + bool GetRectangle(Selection* selection); // Returns a valid rectangle + bool ContainsRectangle(); // Does the board contain a valid rectangle? + + bool IsAnimating(){return (m_isAnimating);} // Is the board currently animating? + + bool Update(); // Update (for flashing) + + // Converts between marble coordinates and its screen location, in pixels: + static void CoordToPixels(Coordinate *coord1, Coordinate *coord2, + Uint16 *x1, Uint16 *y1, Uint16 *x2, Uint16 *y2); + static void PixelsToCoord(Coordinate *coord1, Coordinate *coord2, + Uint16 *x1, Uint16 *y1, Uint16 *x2, Uint16 *y2); + static void CoordToSDLRect(Coordinate *coord1, Coordinate *coord2, SDL_Rect *rect); + + void Draw(SDL_Surface *screen, Selection *selection, bool paused = false); // Draws the board + + // Rectangle clearing: + void ClearRectangle(Coordinate coord1, Coordinate coord2); // Starts the rectangle clear sequence + + void Highlight(Coordinate c = Coordinate(-1, -1)); + + private: + // Helper methods for rectangle clearing and dropping animation: + void Flash(Coordinate coord1, Coordinate coord2); // Flashes a rectangle + +#ifdef MARBLE_DROP + void DropRectLogic(Coordinate coord1, Coordinate coord2); // Eliminates the given rect, and drops a new one + void ChangeVisibility(Coordinate coord1, Coordinate coord2, bool visible); // Changes a rect's visibility + void RenderDroppingRect(Coordinate coord1, Coordinate coord2); // Renders the dropping rect to a surface +#endif + +#ifdef _DEBUG + // Prints the board to the console: + void PrintBoard(Coordinate *coord1, Coordinate *coord2); +#endif + + +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.cpp new file mode 100644 index 000000000..a6768445d --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.cpp @@ -0,0 +1,344 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../game/game.h" +#include "../common/events.h" +#include "../game/highscores.h" + +#include "../common/surfacemanager.h" +#include "../common/soundmanager.h" + +#include +#include + +using namespace std; + +// Constructor - initializes the class' members +Game::Game() +{ + Restart(); +} + + +// Destructor - free resources +Game::~Game() +{ + +} + + +// Get the playing time left (in ms): +Sint32 Game::GetTimeLeft() +{ + return m_timeLeft; +} + + +// Clears the current selection +void Game::ClearSelection() +{ + m_selection.Clear(false); +} + + +// Interprets a mouse click: +bool Game::Click(int x, int y) +{ + if (m_paused) + return false; + + m_board.Highlight(); // Clear highlight + + if (x < BOARD_X || x > BOARD_X + MARBLE_IMAGE_SIZE * BOARD_SIZE || + y < BOARD_Y || y > BOARD_X + MARBLE_IMAGE_SIZE * BOARD_SIZE) + return false; + + // Convert the coordinates from pixels to marbles: + int X = (x - BOARD_X) / MARBLE_IMAGE_SIZE; + int Y = (y - BOARD_Y) / MARBLE_IMAGE_SIZE; + + m_selection.Add(X, Y, &m_board); + + // If a rectangle has been completed, add to the score and repopulate + // the area: + if (m_selection.IsRect()) + RectangleComplete(); + + return true; +} + + +// Interprets a right mouse button click. +// Right clicking anywhere on the game board clears +// the current selection. +bool Game::RightClick(int x, int y) +{ + if (m_paused) + return false; + + m_board.Highlight(); // Clear highlight + + if (x < BOARD_X || x > BOARD_X + MARBLE_IMAGE_SIZE * BOARD_SIZE || + y < BOARD_Y || y > BOARD_X + MARBLE_IMAGE_SIZE * BOARD_SIZE) + return false; + + if (m_selection.GetSize() > 0) + m_selection.Clear(true); + + return true; +} + +// Interprets a mouse over: +bool Game::Hover(int x, int y) +{ + if (m_paused) + return false; + + if (x < BOARD_X || x > BOARD_X + MARBLE_IMAGE_SIZE * BOARD_SIZE || + y < BOARD_Y || y > BOARD_X + MARBLE_IMAGE_SIZE * BOARD_SIZE) + return false; + + // Convert the coordinates from pixels to marbles: + int X = (x - BOARD_X) / MARBLE_IMAGE_SIZE; + int Y = (y - BOARD_Y) / MARBLE_IMAGE_SIZE; + + m_board.Highlight(Coordinate(X,Y)); + + return true; +} + + +// Provide the user with a hint. +// This changes the selection: only one marble is now selected, and it is +// part of a rectangle. +// The user pays a time penalty for getting a hint. +void Game::Hint() +{ + if (m_paused) + return; + + if (m_timeLeft > HINT_PENALTY) + { + m_timeLeft -= HINT_PENALTY; + + // Get a valid rectangle: + vector > l_oValidRects; + m_board.GetRectangles(&l_oValidRects); + + // Get a random coordinate: + Coordinate l_oCoord = l_oValidRects[rand() % l_oValidRects.size()][rand() % 4]; + + // Replace the current selection with a random marble from the rectangle: + m_selection.Clear(); + m_selection.Add(l_oCoord, &m_board); + + // Check if time is running low: + if (m_timeLeft <= HINT_PENALTY) + PushUserEvent(EVENT_TIME_LOW); + } +} + + +// Populates the argument selection with a valid rectangle. +void Game::GetRectangle(Selection *a_opSelection) +{ + vector > l_oValidRects; + m_board.GetRectangles(&l_oValidRects); + + size_t i = rand() % l_oValidRects.size(); + + a_opSelection->Clear(); + a_opSelection->Add(l_oValidRects[i][0], &m_board); + a_opSelection->Add(l_oValidRects[i][1], &m_board); + a_opSelection->Add(l_oValidRects[i][2], &m_board); + a_opSelection->Add(l_oValidRects[i][3], &m_board); +} + + +// Pauses or resumes the game: +void Game::SetPaused(bool paused) +{ + // Pause: + if (paused == true) + { + m_paused = true; + } + + // Resume: + else + { + m_paused = false; + m_lastTick = SDL_GetTicks(); + } +} + +// Restart the game: +void Game::Restart() +{ + // Reset the board: + m_board.Reset(); + + // Reset score and time: + memset(&m_stats, 0, sizeof(m_stats)); + m_selection.Clear(); + m_paused = false; + m_score = 0; + m_level = 1; + m_timeLeft = TIME_BASE; + m_lastTick = SDL_GetTicks(); + + // Score and level were changed: + PushUserEvent(EVENT_RECT_COMPLETE); + PushUserEvent(EVENT_NEW_LEVEL); + + // Time is not running low: + PushUserEvent(EVENT_TIME_OK); +} + + +// Returns the current score. +Uint32 Game::GetScore() +{ + return m_score; +} + + +// Returns game statistics. +Statistics Game::GetStats() +{ + return m_stats; +} + + +// Returns the current level. +Uint32 Game::GetLevel() +{ + return m_level; +} + + +// Can the user make a move? +bool Game::CanMove() +{ + return (!m_board.IsAnimating()); +} + + + +// Update the game. +bool Game::Update() +{ + Sint32 prevTime = m_timeLeft; + + if (!m_paused) + { + // Update the time: + m_stats.TotalTime += (SDL_GetTicks() - m_lastTick); + + // DIFFICULTY // + // This controls the rate the timer counts down as a function of the current level: + m_timeLeft -= (Sint32) ((SDL_GetTicks() - m_lastTick) * (m_level / 5.0f + 0.2f)); + //m_timeLeft -= (Sint32) ((SDL_GetTicks() - m_lastTick) * (m_level / 1.0f + 1.5f)); + //// + + m_lastTick = SDL_GetTicks(); + } + + // If time is up, push the game over event into the queue: + if (m_timeLeft <= 0) + PushUserEvent(EVENT_GAME_OVER); + + // If the time bar has been filled, advance to the next level: + else if (m_timeLeft >= TIME_MAX) + { + m_level++; + m_timeLeft = TIME_BASE; + + // Push the level over event: + PushUserEvent(EVENT_NEW_LEVEL); + } + + // Check if time is running low: + if (m_timeLeft <= HINT_PENALTY && prevTime > HINT_PENALTY) + PushUserEvent(EVENT_TIME_LOW); + + return m_board.Update(); +} + +// Draws the game elements. +void Game::Draw(SDL_Surface *screen) +{ + // Render the game board: + m_board.Draw(screen, &m_selection, m_paused); +} + +// Handle rectangle completion: +void Game::RectangleComplete() +{ + // Update stats: + m_stats.RectCleared++; + + // Get the rectangle: + m_selection.GetRectangle(&m_A, &m_B); + + // Get its screen location: + m_board.CoordToSDLRect(&m_A, &m_B, &m_rectLocation); + + // Clear the rectangle: + m_board.ClearRectangle(m_A, m_B); + + // Calculate the rectangle's size: + Uint32 rectSize = ((m_B.x - m_A.x + 1) * (m_B.y - m_A.y + 1)); + + // Check if the extra time earned takes us out of low time mode: + if (m_timeLeft <= HINT_PENALTY && + (m_timeLeft + TIME_BONUS * rectSize) > HINT_PENALTY) + PushUserEvent(EVENT_TIME_OK); + + // Update time: + m_timeLeft += TIME_BONUS * rectSize; + + // Update score: + m_movePoints = (Uint32) (rectSize * (m_level / 2.0)); + m_score += m_movePoints; + + // Update statistics: + m_stats.MarblesCleared += rectSize; + m_stats.BestMove = (m_movePoints > m_stats.BestMove) ? m_movePoints : m_stats.BestMove; + m_stats.NumOfPerfect += (rectSize == BOARD_SIZE * BOARD_SIZE) ? 1 : 0; + + // Clear the selection: + m_selection.Clear(); + + // Push the score event, in case anyone is interested: + PushUserEvent(EVENT_RECT_COMPLETE, + (void *) &m_movePoints, // Move's points + (void *) &m_rectLocation); // Rectangle's screen coordinates + + // If a perfect rectangle was cleared, push an event: + if (rectSize == BOARD_SIZE * BOARD_SIZE) + { + PushUserEvent(EVENT_PERFECT); + SoundManager::GetInstance()->PlaySound("PerfectRectangle"); + } + else + SoundManager::GetInstance()->PlaySound("RectangleComplete"); +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.h new file mode 100644 index 000000000..7170f4df6 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/game.h @@ -0,0 +1,101 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _GAME_H_ +#define _GAME_H_ + +#include "SDL.h" +#include "../common/common.h" +#include "../game/board.h" +#include "../game/selection.h" + + +// Game statistics: +typedef struct +{ + Uint32 RectCleared; // Total rectangles cleared + Uint32 MarblesCleared; // Total marbles cleared + Uint32 TotalTime; // Total playing time + Uint32 BestMove; // Best move (in points) + Uint32 NumOfPerfect; // The number of perfect moves + Uint32 OverflowBonus; // Total points earned due to time overflow +} Statistics; + +class Game +{ + private: + Uint32 m_score; // Score + Statistics m_stats; // Game statistics + + Uint32 m_level; // Current game level + + Sint32 m_timeLeft; // Time left + Uint32 m_lastTick; // The last timer tick recorded + + Board m_board; // Game board + Selection m_selection; // Selected marbles + + bool m_paused; // Is the game paused? + + Coordinate m_A, m_B; // Corners of last completed rectangle (A - top-left, B - bottom-right) + Uint32 m_movePoints; // Points earned is the latest move + SDL_Rect m_rectLocation; // Screen location (in pixels) of the last completed rectangle + + public: + Game(); + ~Game(); + + bool CanMove(); // Can the user make a move? + + Sint32 GetTimeLeft(); // Get the time left to play + + bool Click(int x, int y); // Interprets a left mouse button click + bool RightClick(int x, int y); // Interprets a right mouse button click + bool Hover(int x, int y); // Interprets a mouse-over + + void SetPaused(bool paused); // Sets the game's pause state + + void Restart(); // Restarts the game + + void Hint(); // Give the user a hint + + void ClearSelection(); // Clears the current selection + + void GetRectangle(Selection *selection); // Returns a valid rectangle + + Uint32 GetScore(); // Returns the score + Statistics GetStats(); // Returns the game statistics + Uint32 GetLevel(); // Returns the level + + bool Update(); // Updates the game + void Draw(SDL_Surface *screen); // Draws the game elements + + // Timing (all units are in ms): + static const Sint32 TIME_BASE = 45000; // Base time for a new level + static const Sint32 TIME_BONUS = 350; // Time bonus per marble cleared + static const Sint32 TIME_MAX = 2 * TIME_BASE; // Maximum allowed time + static const Sint32 HINT_PENALTY = 8000; // Time penalty for requesting a hint + + private: + void RectangleComplete(); // Handles rectangle completion +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.cpp new file mode 100644 index 000000000..b89daf992 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.cpp @@ -0,0 +1,211 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../game/highscores.h" +#include "../common/trap.h" + +#include +#include +#include +#include + +// Constructor. +HighScores::HighScores() +{ + m_fileName = DEFAULT_FILENAME; + Read(); +} + +HighScores::~HighScores(){}; + + +// Get the table's size (number of entries) +Uint32 HighScores::GetSize() +{ + return (Uint32) m_table.size(); +} + + +// Gets the name of the i-th table entry. +string HighScores::GetName(Uint32 i) +{ + multimap >::iterator itr = m_table.begin(); + Uint32 j = 0; + while (j < i) + { + itr++; + ++j; + } + + return itr->second; +} + + +// Gets the comma formatted score of the i-th entry. +string HighScores::GetScore(Uint32 i) +{ + multimap >::iterator itr = m_table.begin(); + Uint32 j = 0; + while (j < i) + { + itr++; + ++j; + } + + return AddCommas(itr->first); +} + +// Determines whether the score qualify as a high score. +bool HighScores::Qualifies(Uint32 score) +{ + // Since the table (STL map) is guaranteed to be + // sorted in a descending order, the last element + // is always the smallest. + return (score > (--m_table.end())->first); +} + +// Add an entry to the high score table +void HighScores::Add(string playerName, Uint32 score) +{ + // Make sure the score should be added: + if (!Qualifies(score)) + return; + + // Remove the lowest score from the table: + m_table.erase(--m_table.end()); + + if (playerName == "") + playerName = "Anonymous"; + + // Add the new entry: + m_table.insert(make_pair(score, playerName)); + + // Write the modified table to disk: + HighScores::Write(); +} + + +// Reads the table from disk. +// If the file is missing or invalid, the table is reset +// to default values. +void HighScores::Read() +{ + m_table.clear(); + + ifstream inputFile(m_fileName.c_str(), ios::in); + if (!inputFile.is_open()) + { + SetDefault(); + return; + } + + string line = ""; + for (int i = 0 ; i < NUM_OF_HIGH_SCORES ; ++i) + { + if (std::getline(inputFile, line).eof()) + { + // File too short + inputFile.close(); + SetDefault(); + return; + } + + Uint32 score; + string playerName; + size_t comma; // Index of comma in string + + if ((comma = line.find_first_of(",")) == line.npos // Get comma location, and make sure it exists + || (playerName = line.substr(0, comma)).length() <= 0 // Get player name, make sure it is not empty + || (line.length() - comma) <= 1) // No score + { + // File malformed + inputFile.close(); + SetDefault(); + return; + } + + score = atoi(line.substr(comma + 1).c_str()); + + // Add the data to the table in memory: + m_table.insert(make_pair(score, playerName)); + } + + inputFile.close(); +} + + +// Writes the high scores to a file. +void HighScores::Write() +{ + if (m_fileName == "") + m_fileName = DEFAULT_FILENAME; + + ofstream outputFile(m_fileName.c_str(), ios::out); + + TRAP(!outputFile.is_open(), "HighScores::Write - Could not open \"" << m_fileName << "\" for writing."); + + /* + // Maybe silent failure is better? + if(!outputFile.is_open()) + return; + */ + + multimap >::iterator itr; + for (itr = m_table.begin() ; itr != m_table.end() ; itr++) + outputFile << itr->second << "," << itr->first << endl; + + outputFile.close(); +} + + +// Sets the table to the default values +void HighScores::SetDefault() +{ + m_table.clear(); + + for (int i = 0 ; i < NUM_OF_HIGH_SCORES ; ++i) + m_table.insert(make_pair(DEFAULT_SCORE[i], DEFAULT_NAME[i])); +} + + +// Adds commas to a number (e.g. 1520 -> 1,520). +string HighScores::AddCommas(Uint32 num) +{ + string result = ""; + int i = 0; + + while (num > 9) + { + result += '0' + (char) (num % 10); + + ++i; + if (i % 3 == 0) + result+= ','; + + num /= 10; + } + result += '0' + (char) (num % 10); + + // Reverse the string: + reverse(result.begin(), result.end()); + + return result; +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.h new file mode 100644 index 000000000..a1bfa9e8d --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/highscores.h @@ -0,0 +1,138 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _HIGHSCORES_H_ +#define _HIGHSCORES_H_ + +/* + High scores table. + + File format: + playerName,score<\n> + + For example: + RandomJoe,666<\n> +*/ + +#include "SDL.h" + +#include +#include +#include + +using namespace std; + +static const int NUM_OF_HIGH_SCORES = 10; // Number of high scores to keep + +static const string DEFAULT_FILENAME = "highscores.dat"; // Default high scores file name + +// Default player names and scores. +// This is used when the high scores file is missing or invalid. + +static const string DEFAULT_NAME[NUM_OF_HIGH_SCORES] = { + "Player 1", + "Player 2", + "Player 3", + "Player 4", + "Player 5", + "Player 6", + "Player 7", + "Player 8", + "Player 9", + "Player 10" +}; + + +static const Uint32 DEFAULT_SCORE[NUM_OF_HIGH_SCORES] = { + 1000, + 2000, + 3000, + 4000, + 5000, + 6000, + 7000, + 8000, + 9000, + 10000 +}; + + +/* +static const Uint32 DEFAULT_SCORE[NUM_OF_HIGH_SCORES] = { + 500, + 1000, + 1500, + 2000, + 2500, + 3000, + 3500, + 4000, + 4500, + 5000 +}; +*/ +/* +static const Uint32 DEFAULT_SCORE[NUM_OF_HIGH_SCORES] = { + 5, + 10, + 15, + 20, + 25, + 30, + 35, + 40, + 45, + 50 +}; +*/ + +class HighScores +{ + private: + multimap > m_table; // Sorted high scores table (score/player) + string m_fileName; // High scores file name + + public: + HighScores(); + ~HighScores(); + + Uint32 GetSize(); // Gets the table's size (number of entries) + + string GetName(Uint32 i); // Gets the name of the i-th table entry + string GetScore(Uint32 i); // Gets the comma formatted score of the i-th entry + + bool Qualifies(Uint32 score); // Does the score qualify as a high score? + + void Add(string playerName, Uint32 score); // Adds an entry to the high score table + + static string AddCommas(Uint32 num); // Adds commas to a number (e.g. 1520 -> "1,520") + + private: + void Read(); // Reads the table from disk + void Write(); // Writes the table to disk + void SetDefault(); // Sets the table to the default values + + // No copying: + HighScores(const HighScores&){}; + HighScores& operator= (const HighScores&){}; +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.cpp new file mode 100644 index 000000000..251ff8d80 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.cpp @@ -0,0 +1,215 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../game/selection.h" + +#include "../common/soundmanager.h" +#include "../common/trap.h" + +#include +#include +#include +#include "SDL_image.h" + +using namespace std; + +// Constructor +Selection::Selection() +{ + m_selected.clear(); +} + + +// Destructor - free resources +Selection::~Selection() +{ + +} + + +// Is the selection complete (represents a rectangle)? +bool Selection::IsRect() +{ + return (m_selected.size() == 4); +} + + +// Clears the selection. +void Selection::Clear(bool playSound) +{ + if (playSound) + SoundManager::GetInstance()->PlaySound("SelectionCancelled"); + + m_selected.clear(); +} + + +// Index operator. +Coordinate& Selection::operator[](int i) +{ + TRAP(i < 0 || i >= (int) m_selected.size(),"Selection::operator[] - Out of bounds"); + + return m_selected[i]; +} + +// Gets the selected rectangle. +// Returns 0 on success. +int Selection::GetRectangle(Coordinate* A, Coordinate* B) +{ + if (A == NULL || B == NULL || m_selected.size() != 4) + return -1; + + // Get the bounds: + A->x = A->y = BOARD_SIZE; + B->x = B->y = -1; + for (int i = 0 ; i < 4 ; ++i) + { + if (m_selected[i].x < A->x) + A->x = m_selected[i].x; + else if (m_selected[i].x > B->x) + B->x = m_selected[i].x; + + if (m_selected[i].y < A->y) + A->y = m_selected[i].y; + else if (m_selected[i].y > B->y) + B->y = m_selected[i].y; + } + + return 0; +} + + +// Adds a marble to the current selection. +// The marble is added only if it is valid. Otherwise, the selection is cleared. +// +// Rules to determine validity of adding a new marble (T) to the selection: +// 1. T is not already selected +// 2. T is the same color as everyone else +// 3. If 2 marbles are already selected, T must align with one of them +// 4. If 3 marbles are already selected, T must align with 2 of them +void Selection::Add(Coordinate coord, Board *board) +{ + if (board == NULL) + return; + + // Sanity check: + TRAP(m_selected.size() < 0 || m_selected.size() > 4, + "Selection::Add() - Invalid number of marbles selected (" + << (unsigned int) m_selected.size() << ")"); + + // Bounds check (does not clear selection): + if (coord.x < 0 || coord.y < 0 || coord.x >= BOARD_SIZE || coord.y >= BOARD_SIZE) + return; + + // Check validity: + int l_iHAlign = 0, l_iVAlign = 0; // Number of marbles the new marbles is aligned with + for (unsigned int i = 0 ; i < m_selected.size() ; ++i) + { + // Rules 1: + // If the new marble is already selected, remove it from the selection: + if (coord.x == m_selected[i].x && coord.y == m_selected[i].y) + { + SoundManager::GetInstance()->PlaySound("SelectionCancelled"); + m_selected.erase(m_selected.begin() + i); + return; + } + + // Rule 2: + // Is the new marble the same color as everyone else? + if (board->GetMarbleColor(m_selected[i]) != board->GetMarbleColor(coord) ) + { + SoundManager::GetInstance()->PlaySound("SelectionInvalid"); + m_selected.clear(); + return; + } + + // Check for alignment: + if (coord.y == m_selected[i].y) + l_iHAlign++; + if (coord.x == m_selected[i].x) + l_iVAlign++; + + for (unsigned int j = 0 ; j < m_selected.size() ; ++j) + { + if (i != j) + { + if (m_selected[i].y == m_selected[j].y) + l_iHAlign++; + if (m_selected[i].x == m_selected[j].x) + l_iVAlign++; + } + } + } + + + // Rule 3 - If 2 marbles are already selected, T must align with one of them: + if (m_selected.size() == 2 && !( + (l_iHAlign == 1 && l_iVAlign == 1) || + (l_iHAlign + l_iVAlign == 3) + )) + { + SoundManager::GetInstance()->PlaySound("SelectionInvalid"); + m_selected.clear(); + return; + } + + // Rule 4 - If 3 marbles are already selected, T must align with both of them: + if (m_selected.size() == 3 && (l_iHAlign != 3 || l_iVAlign != 3)) + { + SoundManager::GetInstance()->PlaySound("SelectionInvalid"); + m_selected.clear(); + return; + } + + // If we are here, the new marble is valid. Add it to the selection: + m_selected.push_back(coord); + + // Play the click sound: + if (m_selected.size() != 4) + SoundManager::GetInstance()->PlaySound("MarbleClick"); +} + +// Adds a coordinate to the selection. +void Selection::Add(int x, int y, Board *board) +{ + Coordinate l_oCoord; + l_oCoord.x = x; + l_oCoord.y = y; + Add(l_oCoord, board); +} + +// Returns whether a coordinate is selected. +bool Selection::IsSelected(Coordinate coord) +{ + vector::iterator itr; + for (itr = m_selected.begin() ; itr != m_selected.end() ; itr++) + if (itr->x == coord.x && itr->y == coord.y) + return true; + + return false; +} + +// Returns whether a coordinate is selected. +bool Selection::IsSelected(int x, int y) +{ + Coordinate coord (x, y); + return IsSelected(coord); +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.h new file mode 100644 index 000000000..3b1bc53a3 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/game/selection.h @@ -0,0 +1,63 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _SELECTION_H_ +#define _SELECTION_H_ + +// This class represents the currently selected marbles. +// It enforces the selection rules so that at any given moment, +// the current selection is valid. + +#include "SDL.h" + +#include "../game/board.h" + +#include + +using namespace std; + +class Selection +{ + private: + vector m_selected; // Coordinates of the selected marbles + + public: + Selection(); + ~Selection(); + + bool IsRect(); // Is the selection a rectangle? + + void Clear(bool playSound = false); // Clears selection + + Coordinate& operator[](int i); // Index operator + + int GetRectangle(Coordinate* A, Coordinate* B); // Gets the selected rectangle + + int GetSize(){return (int) m_selected.size();} // Gets selection size + + bool IsSelected(Coordinate); // Returns whether a coordinate is selected + bool IsSelected(int x, int y); + + void Add(Coordinate coord, Board *board); // Adds a marble to the selection + void Add(int x, int y, Board *board); +}; + +#endif + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/main.cpp b/alienblaster/project/jni/application/jooleem_0.1.4/src/main.cpp new file mode 100644 index 000000000..12c7a41f5 --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/main.cpp @@ -0,0 +1,113 @@ +/* +* Copyright (C) 2005 Chai Braudo (braudo@users.sourceforge.net) +* +* This file is part of Jooleem - http://sourceforge.net/projects/jooleem +* +* Jooleem is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* Jooleem is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Jooleem; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + Jooleem is a simple yet extremely addictive puzzle game. The player is + presented with a 10x10 board of colored marbles, and must click on four + marbles of the same color that form a rectangle. Time is constantly + running out, but forming rectangles earns the player more time, as well + as points. The larger the rectangle, the more time and points are won. + + Inspired by Nick Kouvaris' ZNAX: + http://www.freestuff.gr/lightforce/znax.html +*/ + +// Platform specific headers, to display a dialog box. See MsgBox(). +#ifdef _WIN32 +#include +#elif defined( __APPLE__ ) && defined( __MACH__ ) +#include +#endif + +#include +#include "engine/engine.h" +#include "SDL_main.h" + + +using namespace std; + +void MsgBox(string message); // Show a messagebox (cross platform) + +int main(int argc, char* argv[]) +{ + Engine engine; + engine.Run(); + + return 0; +} + + +// Shows an exception in an OS message box (cross platform). +// FIX: the message doesn't get here properly +void MsgBox(string message) +{ + + // Prepare the error message: + char buffer[4096]; + + sprintf(buffer, + "The game has encountered an unrecoverable error. Please send\n" + "the error message below to braudo@users.sourceforge.net.\n\n%s", + message.c_str()); + /* + sprintf(buffer, + "The game has encountered an unrecoverable error\n" + "and will shut down. Downloading and installing\n" + "the game again might solve the problem.\n\n" + "If the problem persists, please contact\n" + "braudo@users.sourceforge.net" + ); + */ + +// Windows: +#ifdef WIN32 + + MessageBox(NULL, buffer, "Critical Error", MB_OK | MB_ICONERROR); + + +// Mac OS X: +#elif defined( __APPLE__ ) && defined( __MACH__ ) + // Reference: + // http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/hitb-wind_cont_tasks/chapter_3_section_4.html + + DialogRef theItem; + DialogItemIndex itemIndex; + + // Create a string ref of the message: + CFStringRef msgStrRef = CFStringCreateWithCString(NULL, message.c_str(), kCFStringEncodingASCII); + + // Create the dialog: + CreateStandardAlert(kAlertStopAlert, CFSTR("Critical Error"), msgStrRef, NULL, &theItem); + + // Show it: + RunStandardAlert(theItem, NULL, &itemIndex); + + // Release the string: + CFRelease(msgStrRef); + +// Default to standard error: +#else + // Note that only the basic error message is displayed here. + cerr << message << endl; + +#endif + +} + diff --git a/alienblaster/project/jni/application/jooleem_0.1.4/src/resource.h b/alienblaster/project/jni/application/jooleem_0.1.4/src/resource.h new file mode 100644 index 000000000..44474abbd --- /dev/null +++ b/alienblaster/project/jni/application/jooleem_0.1.4/src/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Jooleem.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif +