cϽ 1""2"2SAS FILETETRIS_SUGI30 CATALOG AIA 58.0202M0WIN_PROWINƃƃ>>8 SYSRESR PGBITMAPXSOURCE CREATEPIECES SYSRESR PGBITMAPXSOURCE CREATEBLOCKS SCL SCORESCLASS SCL SCORES SCL PLAYMETHODS8 SCL PLAYdSCL PIECECLASS SCL LOADBLOCKS SCL FIELDCLASS SCL BLIPSOUNDCLASSIMAGE GRIDIMAGE GH IMAGE Ft IMAGE E IMAGE D IMAGE C IMAGE B$ IMAGE APFRAME PLAY|CLASS SCORESCLASS PIECECLASS FIELDCLASS BLIPSOUND, >XLCH5(XLSRIAIA  XLSR *A *A ********  F  XLSR؋ *A؋ *A J ********  F  XLSRN*AN*A"q ********  F  XLSRAA+" 05/11/04   F  XLSR 1RA*A 84  F  Play TetrisXLSR {E *A{E *A  2  XLSR |E *A|E *A  2  XLSR }E *A}E *A  2  XLSR  }E *A}E *A  2  XLSR }E *A}E *A  2  XLSR }E *A}E *A  2  XLSR }E *A}E *A  2  XLSR}E *A}E *A  2  XLSR *A *Aca{  F %Create waveform for blip sound effect>j00BP>0/!UCLASSL POBJECTLCLLCPplayLP()V LCPoffLP()V LCC=L  L  PN PUL  PN PUL  PN PUP(N)VL L PCL PNLLPSCNLPSCCCPBBBIz!!!_TYPE__IV_DESC _METHODS_playentryLABEL signature sigStringoff_INITCONSTRUCTORdurTYPEINOUTfreqvol _ATTRIBUTES_ samplebuffer canplaysound_EVENTS_samplebuffer changedstate descriptioncanplaysound changed_PARENT__ATTR__UATTR_ _ALTATTR_ _FILLATTR_usePropertySheet _RELEASE_GAMES.TETRIS.BLIPSOUND.CLASSGAMES.TETRIS.BLIPSOUNDCLASS.SCL_INITCONSTRUCTOR1Occurs when the samplebuffer attribute is changed1Occurs when the canplaysound attribute is changedSASHELP.FSP.OBJECT.OBJECTSASHELP.FSP.PROPERTYSHEET.FRAMEx NAME6NAME7NAME8NAME9NAME10SCORE1formatinformatdataTypeSCORE2SCORE3SCORE4SCORE5SCORE6SCORE7SCORE8SCORE9SCORE10OK_onClick _METHODS__newstateentry saveScores signature sigStringsetcamSlistEntryscopeattributeValueINOUT DESCRIPTIONReturn descriptionaddScorenewscore _ATTRIBUTES_ resourceEntry initialValue borderColorborderTitleFontborderTitleFontScaling borderWidthivlinkable sendEventcategoryonameoscorescoreseditorsetCAM slistEntrynewix_EVENTS_ oname changedoscore changedscores changedslistEntry changed newix changed_ATTR__UATTR_ _ALTATTR_ _FILLATTR_usePropertySheet _RELEASE_+COMPOSITGAMES.TETRIS.SCORES.CLASS!SASHELP.FSP.afcomponents.resourceSYSFONTS Comic Sans MS High ScoresCX3TEXTLABEL_C.AFCNTRL TEXTENTRY1SASHELP.CLASSES.TEXTENTRY_CXCOMPOSXCx3TEXTENTRY_C.AFCNTRL saveScoresPUSHBUTTON_C.AFCNTRLGAMES.TETRIS.SCORES.SCLgames.tetris.scores.sclsetcamSlistEntry Protectedcontains the attribute valueqreturns a value indicating whether the setcam completed successfully: 0 if successful, >0 if error, <0 if warning0Invoked when the slistEntry attribute is changedaddScore11 if score was added to high scores, 0 if too low Textentry1&Returns the id of the component object&sashelp.classes.simplelisteditor.frame*Catalog entry where high scores are stored Slot where new score was entered*Occurs when the oname attribute is changed+Occurs when the oscore attribute is changed+Occurs when the scores attribute is changed/Occurs when the slistEntry attribute is changed*Occurs when the newix attribute is changedSASHELP.FSP.COMPOSIT.COMPOSITSASHELP.FSP.PROPERTYSHEET.FRAME  ;IISAS/IMAGE CAT5>&&66BB44**++++>>//;;//..''''##''&&==((((00DD))EE))11GG1122[[z----,,--0000,,****..@@%%%%$$$$$$33882299%H\HÇ!~Pa TbAC (Xb /fcȑ%O\2K5rR$I(Uυ343)O L< fQHw.mjBVDoթgVJط lXeؚjضX pbTlt",r}K[E [ Gi[!Li gl0-17qJ~JCLASSL PSASOGVUPIMAGELLLCLLPO C P_init P()V L C C5 LL PNPR P()NL  C CE L L PNPR P()NL  C CX L P()VL C CdCp LLPNPI P(N)VL C CzCp LLPNPI P(N)VL C CCp LLPNPI P(N)VLPO C P_term P()VL LPNN4@CpLPNN$@CpLPNNCLPNNCz LPNNCd!LPNN"L PNN$@#L!PO(*,*)$L"PO(*)%L# &L$PS'C(L%PS'C)L&PS'C*L'PS'C+L(PS'CJ,L)PS'Cu-L*PS'C.L+PS'C/L,PS'C0C-1CQ2P3B4B5B6Iz111_MODULE__TYPE__IV_USERATTR_REGION_DESC _METHODS__initstateentryLABEL sigStringgetNumberOfRows signatureReturnTYPEINOUTgetNumberOfColumns clearBlocks setcamScorescopeN setcamLevelsetcamRowsCleared_term _ATTRIBUTES_nRows initialValuenCols rowsClearedsetCAMlevelscoregameover rowsPerLevelblocksclicks_EVENTS_ nRows changed description nCols changedrowsCleared changed level changed score changedgameover changedrowsPerLevel changedblocks changedclicks changed_PARENT__ATTR__UATTR_ _ALTATTR_ _FILLATTR_usePropertySheet _RELEASE_qqqGAMES.TETRIS.FIELD.CLASSGAMES.TETRIS.FIELDCLASS.SCLgetNumberOfRowsgetNumberOfColumns clearBlocks setcamScore Protected setcamLevelsetcamRowsCleared*Occurs when the nRows attribute is changed*Occurs when the nCols attribute is changed0Occurs when the rowsCleared attribute is changed*Occurs when the level attribute is changed*Occurs when the score attribute is changed-Occurs when the gameover attribute is changed1Occurs when the rowsPerLevel attribute is changed+Occurs when the blocks attribute is changed+Occurs when the clicks attribute is changed#SASHELP.CLASSES.IMAGEVIEWER_C.IMAGESASHELP.FSP.PROPERTYSHEET.FRAME+ ;IISAS/IMAGE CAT6D[2r&/=>l$m$|)n$/;k#DGE00+0,,11w'v'u't&B.6.~*@8[y(z(z({)*9-4-3*2-+q%p%H f( Ç!PHD @ň,\ ,aʼn /fcȑ%O\ٲK5rR$I(U\"υ343)O1*<%!fQHw.mZVDoթgV JطdlXeؚjضXxbTl8Et",2}K[9[ Gi&B &Jl7mϰKdتytk3h*5lغvg¥sJu7p7@cfҷOVkg_#V xB 1T`2B`B hPC  >^h@ " B(!`@+rx?AjG"K29OBS> oname[i].text = getNItemC (score,'name');`F@voscore[i].text = getNItemN (score,'score');`D@vpMend;`m@v`w@vreturn 1;`h@vendmethod;`i@v`w@v`w@venduseclass;`k@v>0kV7qCLASSL POBJECTLCLLPOCC5P()V LCCF L L CW PUL PC PUCpL CC L L  PC PRP()CL CCC L L PC PUL PN PRP(C)NLCPsetcamXC LL PN PUL PN PRP(N)NLCPsetcamYC LL PN PUL PN PRP(N)NLCCC LL PN PUL PN PRP(N)NLCCC LL PN PUL PN PRP(N)NL CCPPrivate L!L" PN PUL# PN PRP(N)NL$CCPPrivate L%L& PN PUL' PN PRP(N)NL(CCPPrivate L)L* PN PUL+ PN PRP(N)NL,CCPPrivate L-L. PN PUL/ PN PRP(N)N L0CPleft L1P()V!L2CPright L3P()V"L4CPdown L5#L6 PN PIP(N)V$L7CPdrop L8P()V%L9CC L:L; PN PRP()N&L<CProtate L=P()V'L>CPwait L?L@ PN PRP()N(LACC LBLC PO PRP()O)LDCCC LEP()V*LFCPlock LGP()V+LHCC  LIP()V,LJ-LK PO(4) LL POCLM PCCLN PN.N?/LO PN.N0LP PN.N1LQ PN2LR PN.N$@CLS PC3C4PYes NoLT PN3PsetcamXLU PN3PsetcamYLV PN3CLW PN3C5LX PN.N3?6LY PN.N@o@7LZ PN.ND@8L[ C.L\@NNN?NNNN@NNNN@NNNN@NNNNNNNNNN@N@N@N?NNNNNNN@NNNN@NNNN@NNNN?NNNNNNNNNN?N@N@N@NNNNPPrivate9L] C.L^$NN?NN@N@N@NNNNN@NNN@N?NN@NNNNN@N@N@NN?NNN@NN?N@NNN@NPPrivate:L_ C.L`$NNN?N@N@N@NNNNN@NNN@NNN@N?NNNN@N@N@N?NNN?N@NNN@NNN@NPPrivate;La C.Lb$NNNN?N@N@NNN@NN?NNN@NN@N@NN@NNN@N@N?NNNNN@N@NN@NNN?NPPrivate<Lc C(.LdN?N@N@N@N@N?N@N@N@N@N@N?N@N@N?N@PPrivate=Le C.Lf$NN?N@N@N@NNNNNN@NNN@N?NNN@NNNNN@N@N@N?NN@NNN?N@NNN@NPPrivate>Lg C.Lh$N?N@NNN@N@NNNNNN?NN@N@NN@NNNNN@N@NNN@N?NN@NN@N@NN?NNPPrivate?Li C1PPrivate@Lj C:PPrivateALk PN.NPPrivateBLl PN.NPPrivateCLm PN.NPPrivateDLn PN.NPPriv>  ateELoFLpPSGCCHLqPSGCnILrPSGCJLsPSGCKLtPSGCLLuPSGCMLvPSGCFNLwPSGCsOLxPSGCPLyPSGCQLzPSGCRL{PSGCSL|PSGCFTL}PSGCoUL~PSGCVLPSGCWLPSGCXLPSGC)YLPSGCPZLPSGCw[LPSGC\LPSGC]LPSGC^LPSGC_LPSGC:`LPSGChaLPSGCbLPSGCcLPSGCdCeC6fPgBhBiBjIz_TYPE__IV_DESC _METHODS__initConstructorstateentryLABEL sigString_INITCONSTRUCTOR signaturefieldTYPEINOUTpiecegetPieceReturn setcamVisiblescopevisiblesetcamXxsetcamYy setcamRowrow setcamColcol blockRowOf blockColOftopOfRow leftOfColleftrightdowndydrop canRotaterotatewaitgetField nextLevellock termBlocks _ATTRIBUTES_block initialValuesidegravitytimeout baseSleepsetCAM validValuesdropWiggleTime interval1 interval10ABCDEFGPlocationincamXincamYincamRowincamCol_EVENTS_ block changed description field changed piece changed state changed side changedgravity changedtimeout changedbaseSleep changedvisible changed x changed y changed col changed row changeddropWiggleTime changedinterval1 changedinterval10 changed A changed B changed C changed D changed E changed F changed G changed P changedlocation changedincamX changedincamY changedincamRow changedincamCol changed_PARENT__ATTR__UATTR_ _ALTATTR_ _FILLATTR_usePropertySheet _RELEASE_VVVGAMES.TETRIS.PIECE.CLASSGAMES.TETRIS.PIECECLASS.SCL_initConstructor_INITCONSTRUCTORGAMES.TETRIS.FIELD.CLASS(O:GAMES.TETRIS.FIELD.CLASS;C)VgetPiece setcamVisible Protected setcamRow setcamCol blockRowOf blockColOftopOfRow leftOfCol canRotategetField nextLevel termBlocksN(4,4,4)N(4,3,3)N(4,2,2)N(*,*,*)N(4,4,2)*Occurs when the block attribute is changed*Occurs when the field attribute is changed*Occurs when the piece attribute is changed*Occurs when the state attribute is changed)Occurs when the side attribute is changed,Occurs when the gravity attribute is changed,Occurs when the timeout attribute is changed.Occurs when the baseSleep attribute is changed,Occurs when the visible attribute is changed&Occurs when the x attribute is changed&Occurs when the y attribute is changed(Occurs when the col attribute is changed(Occurs when the row attribute is changed3Occurs when the dropWiggleTime attribute is changed.Occurs when the interval1 attribute is changed/Occurs when the interval10 attribute is changed&Occurs when the A attribute is changed&Occurs when the B attribute is changed&Occurs when the C attribute is changed&Occurs when the D attribute is changed&Occurs when the E attribute is changed&Occurs when the F attribute is changed&Occurs when the G attribute is changed&Occurs when the P attribute is changed-Occurs when the location attribute is changed+Occurs when the incamX attribute is changed+Occurs when the incamY attribute is changed-Occurs when the incamRow attribute is changed-Occurs when the incamCol attribute is changedSASHELP.FSP.OBJECT.OBJECTSASHELP.FSP.PROPERTYSHEET.FRAME  > 0$"CLASSLPSASOCMXCLC C#LLLCE NЂ N NSUQ@ NNN>@ PNªA@NNN>@iiiiiiiiiiiiiiii i!i"i#i$i%i&L'L(L )L *CN+N@,N-CN.N?/Na@0N?1N"@2N@3N4N6:?5N6:?6N?7PNone8C\9PNo:Ch;PWhite<PCenter=C\>P*P?Cq@CANBL CCL CE NFU @ N؉? Nѕ N;; @ CDL (L )L*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME1ANBL8LFPCGPOCCHLILGPOJPownerIDKCLP()VLCE Nª? NW;;@ NLU3@ Nj;;@ CML (L)L*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME2ANBL8LFPCGPOCCHLILGPOJPownerIDKCLP()VLCE Nª? N$vb'v@ NLU3@ N&vb'v @ CNL (L)L*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME3ANBL8L FPCGPOCCHL!IL"GPOJPownerIDKCLP()VL#CE Nª? N؉!@ NLU3@ N ;%@ COL$ (L%)L&*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME4ANBL'8L(FPCGPOCCHL)IL*GPOJPownerIDKCLP()VL+CE Nª? N$vb'v&@ NLU3@ N79;)@ CPL, (L-)L.*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME5ANBL/8L0FPCGPOCCHL1IL2GPOJPownerIDKCLP()VL3CE Nª? N٭;+@ NLU3@ NcNN.@ CQL4 (L5)L6*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME6ANBL78L8FPCGPOCCHL9IL:GPOJPownerIDKCLP()VL;CE Nª? N7;/@ NLU3@ N%vb'v1@ CRL< (L=)L>*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME7ANBL?8L@FPCGPOCCHLAILBGPOJPownerIDKCLP()VLCCE Nª? N`'vb'2@ NLU3@ N]N3@ CSLD (LE)LF*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME8ANBLG8LHFPCGPOCCHLIILJGPOJPownerIDKCLP()VLKCE Nª? N$vb'v4@ NLU3@ N;6@ CTLL (LM)LN*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME9ANBLO8LPFPCGPOCCHLQILRGPOJPownerIDKCLP()VLSCE Nª? NCN6@ NLU3@ Nsb'vb8@ CULT (LU)LV*CN/NX@1N"@7PNone8PTop Gun9PNo:CEPWhite*P?C@PNAME10ANBLW8LXFPCGPOCCHLYILZGPOJPownerIDKCLP()VL[CE Nª? N٭;9@ NLU3@ N8;:@ CVL\(L] )L^*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE1ANBL_8L`FPNGPOCCLaCE NLU6@ NW;;@ NA@ Nj;;@ CZLb(Lc )Ld*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE2ANBLe8LfFPNGPOCCLgCE NLU6@ N$vb'v@ NA@ N&vb'v @ C[Lh(Li )Lj*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE3ANBLk8LlFPNGPOCCLmCE NLU6@ N؉!@ NA@ N ;%@ C\Ln(Lo )Lp*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE4ANBLq8LrFPNGPOCCLsCE NLU6@ N$vb'v&@ NA@ N79;)@ C]Lt(Lu )Lv*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.X>  PYPNumeric:CEPWhite*P?C@PSCORE5ANBLw8LxFPNGPOCCLyCE NLU6@ N٭;+@ NA@ NcNN.@ C^Lz(L{ )L|*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE6ANBL}8L~FPNGPOCCLCE NLU6@ N7;/@ NA@ N%vb'v1@ C_L(L )L*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE7ANBL8LFPNGPOCCLCE NLU6@ N`'vb'2@ NA@ N]N3@ C`L(L )L*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE8ANBL8LFPNGPOCCLCE NLU6@ N$vb'v4@ NA@ N;6@ CaL(L )L*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE9ANBL8LFPNGPOCCLCE NLU6@ NCN6@ NA@ Nsb'vb8@ CbL(L )L*CN/NX@1N"@7PNone9PNo<PRightWPcomma9.XPYPNumeric:CEPWhite*P?C@PSCORE10ANBL8LFPNGPOCCLCE NLU6@ N٭;9@ NA@ N8;:@ CcL(L=POK*P?CHLdLGPOJPownerIdKCLP()V@POKANLCE NFU @ N;;;@ Nѕ N;;>@ CeLfLgPOhC@P_newiLhC@CjLkP()VlLhC @C"mC3jLnLFPCoPUpC=qLFPNoPRpCZkP(C)NrCsLhC @CjLtLFPNoPIqLFPNoPRpCkP(N)NuL#rLgPOvLgPO:LgPOwChxLgPOwPGrayyLgPOwLzLgPOwPNo7LgPOwPSimple{LgPOwN@LgPSFPO|Pname1mC39PN}PN~PNPSystemLgPSFPO|Pname2mC39PN}PN~PNPSystemLgPSFPO|Pname3mC39PN}PN~PNPSystemLgPSFPO|Pname4mC39PN}PN~PNPSystemLgPSFPO|Pname5mC39PN}PN~PNPSystemLgPSFPO|Pname6mC39PN}PN~PNPSystemLgPSFPO|Pname7mC39PN}PN~PNPSystemLgPSFPO|Pname8mC39PN}PN~PNPSystemLgPSFPO|Pname9mC39PN}PN~PNPSystemLgPSFPO|Pname10mC39PN}PN~PNPSystemLgPSFPO|Pscore1mC39PN}PN~PNPSystemLgPSFPO|Pscore2mC39PN}PN~PNPSystemLgPSFPO|Pscore3mC39PN}PN~PNPSystemLgPSFPO|Pscore4mC39PN}PN~PNPSystemLgPSFPO|Pscore5mC39PN}PN~PNPSystemLgPSFPO|Pscore6mC39PN}PN~PNPSystem LgPSFPO|Pscore7mC39PN}PN~PNPSystem!LgPSFPO|Pscore8mC39PN}PN~PNPSystem"LgPSFPO|Pscore9mC39PN}PN~PNPSystem#LgPSFPO|Pscore10mC39PN}PN~PNPSystem$LgPSFPO|PokmC39PN}PN~PNPSystem%L gPSFPO|C8mC39PN}PN~PNrCCPSystemLFPO(10)mC3LFPO(10)mC3LFPLCjmC3C"PDataLFPCC"rCPDataLFPNwNmC3rCPDataLLgPSrCLgPSrCLgPSrC4LgPSrC`LgPSrC CCPBBBIz_MODULE__TYPE__IV_DESCRESNAMEUSERATTRCHILDREN_REGION_UNITSULXULYLRXLRY_PARENT_XSIZEYSIZEname1name2name3name4name5name6name7name8name9name10score1score2score3score4score5score6score7score8score9score10ok Textentry1 _OBJECTS_ TEXTENTRY1_ATTRS_fontNAMEOPTIONSFAMILYFAMNAMECHARSETPOINTSSTYLEWEIGHTWIDTHPORTABLERATIO SYS_RATIOcursorPosition borderStyletexteditablebackgroundColor labelColor justificationlabel errorMessage _CLASSNAME_LABEL_LEN__INSTANCE_ATTRIBUTES_ _CURRENT_NAME1 textColorTYPESTATE_INSTANCE_METHODS_ _onReturnKey COMPONENT COMP_METHOD SIGSTRINGNAME2NAME3NAME4NAME5 >  PLAYFRAME SYSFORE SYSBACK YELLOW 0@.@ P0"APPLlLLCL N?N?NUW@NO@I4 C L PYes PEdit PSYSFONTPNONEI=OBJECTSNONVISRESNAMEGATTRSROWSCOLNCOLNROWEXESIZE _CLASSNAME__ATTRS_ buildTime buildTimeMode sizingUnits_BANNER__APPL_"""afcomponents.resource FRAME.FRAME-46"@ pP.D*(8&P./ 4/;Zj6?@@@p@$@^@C@a@"@@F@@D@Y@[@>@``@A@[@K@@b@V@i@ @@P ! )08 AD HLPTX \`d h j lrvz~   1   EE            VV      ' /1(&(Y'/')(Y */)*+/+(^$-^.$3/(W6.^=$(WB.^I$^N$^S$X/^[$X/(x`.e4^)t 04^2. 4.5 56 67(8^2(x87^)t^28^2787665^9(x87^0)t^98^9787665^:(x58:7^n)t/(,^s;z/ 08^;}/l/7 876 65(4^;(x87^)t 08^=7 876 65 54(.^=(x87^)t 08^>7 876 65 54(.^>(x87^ )t*0A^28 187^26 765^;}/l/4 54. .C^>D CDE EB AF^?E FED(G BF^ ?!EED FDC(&HGy*GHw*H(?+I IF(2E EI^6?F IFEEJ^6?!F IFEEK 0F FJE ED DC(&L 1F FKE ED DC(&M^7?^<?^A?^F?MKFFN^K;^=FNFEED^P=^>FNFEED^P>^U>Z(x_FdE^)t 0F^OE FED DC C8(7^O 1F^OE FED DC C8(7^O^;/^;)g(d,,)(xFE^)t^PZ*U(TT(SS(FFEUD EDCC(T(+U(S(TUFF( SSdV(.7F7W<(2CX(JT(QT8W<(T(,7T)gVe >  )gV*TTp*INTdhq!+@H\w~]' &' &*  -  -. .-..01.0   !"#$ %&' ( 24. +-78)8.80   / !"#$ %&'( 978))50  0 !"#$ %&'( :7183  2334565 !"#789:;<;7>,@=+54)4*   AB$ %&'( =74.).*   CD$ %&'( >7E8  ?7FGHDCIHC8HGFFE)LFM JKFNFDJKLF9  M"N !OPJK$ %&'( OEF87)7F7Q8RST,VF   PEWXYFSF SRFRZF Y[\FY]F$^Z_`abcdefghVFFVWXSXESERi  """""""""&...000000004<<<>>>>>>>>BLLLNNNOOOOOOOOOSYYY[[[[[[[[[_eeegggggggggkkkknpppppqqqqqrrrrsuuuuuvvvvvvxxyy{|||~~~~sp_MSG__STATUS__ERROR__CURROW__CURCOL__SELF__FRAME__CFRAME_sn$T0cat$T1$T2$T3$T4box$T5$T6whscore$T7$T8$T9$T10$T11$T12level remainingkbd$T13startkeysfield$T14gridwgridh$T15$T16$T17$T18dimwdimhdimfwfhfxfy_ygameoverscores$T19linefidrc routinefound >~ routinei$T20.titleSASTris - Richard A. DeVenezia, 2004_SetAttributeValueulxulylrxlryunitspixels_convertBoxcharacterswidthLRXheightLRYbackgroundColorBlack_winfonumxpixelnumypixelSASHELP.CLASSES.TEXTLABEL_C.CLASS_NEW__region__attrs_labelColorWhitelabelScorejustificationCenterborderStyleSimpleborderColorcx303030fontNAMEComic Sans MSPOINTSWEIGHThorizontalPositionFLOOR_GetAttributeValueSASHELP.FSP.WIDGET.CLASS(C)N(CN)VLevelRemainSASHELP.CLASSES.TEXTENTRY_C.CLASStextColorcx505050enabledYeskeyFeedback_instance_attributes_pieceTYPEODESCRIPTIONPiece that is falling_setInstanceMethod_onKeyPlaymethodsonkeyOrangePress S to StartGray4,5,6,2,DGAMES.TETRIS.FIELD.CLASSverticalPositiongetNumberOfColumns()NgetNumberOfRowsvisibleNo(CC)VBlueCx808080borderWidthGAME OVER_cursorcanplaysound0SYSSCPWINGAMES.TETRIS.SCORES.CLASSslistEntrysasuser.scores.tetrisSASCBTBL* PlaySoundA for AF;WORK.WINAPI.ROUTINES.SOURCECATALOGA routine PlaySoundAmodule = winmmminarg = 3maxarg = 3stackpop = calledreturns= long;arg 1 char inputbyaddrformat=$CHAR32767.; *lpszSoundName;arg 2 numinputbyvalue format=pib4.;*hModule, always 0;arg 3 numinputbyvalue format=pib4.;*uFlags;1  hlSASCBTBLq?xpV@؉N@@#L  pp'@SYSFORE SYSBACK SYSFORE p  ;IISAS/IMAGE CAT5>zz[[3ww{{mm~~yyfkk||nnqq ll pprrttuuvv5Hh`Ç!P (1 L8hpB&  /fcȑ%O\K5rR$I(UDυ343)O/Zf3zz %HHÇ!nPH10 ) 4  /fcȑ%O\ٲK5rR$I(U$Aυ343)Od< fQHw.m*VDoթgV %Jط%lXeؚjضXxqaTlŠt",}K[ył[ Gi[!Li&g&Fll]Mlmʛsu3iӋ0`kq賯Paks%+, & dH@t ( " BR8`&`f'V;أ=N(CYG")K2٤O.  >  ;IISAS/IMAGE CAT5>4466,,p$$))88>>//;;..##''%%&&==//BBDDEEGG0000112211&&22******++,,++----((--..00[[))((@@$$$$''''3399%%#H^DHÇ!P Xx`dpȠ (@PpD /fcȑ%O\ْK5rR$I(U4Abυ343)O#Bx`pbrsuQff 33zl|}~jk{m_ohiyaqcdtfgwH<Ç!6Ph@*P !"X"6h /fcȑ%O\K5rR$I(U`"υ343)Oh< fQHw.mJVDoթgV1Jط1lXe*ؚjضX/PbTlt",r}K[A[ Gi[!Li g8lzz[[3ww{{mm~~yyfkk||nnqq ll pprrttuuvv5Hh`Ç!P (1 L8hpB&  /fcȑ%O\K5rR$I(UDυ343)O/Z;IISAS/IMAGE CAT¥-Y-¥ OOO444pH*\ȰÇ#JHŋȱǏ IƑ&SzD%˖)_,)sfȚ6?q'ϓ>94gQGg&OMUF9dUOofyV_W9cכg=Vd۴`+۹d-׬ݽc+-అ8ƈ!U|x䭉)3rV͎9YSҖM |ugDYmT6QןmצTwoJq8SN3>{KGO͗ylɧ֞T뻹TT[Uz [u~qX "*ؠB( B8! Zxajh . %(b axa0c6VX"8:#:>dBJHdFHdJn$;JY%Szh%X[jiGyal 馜r $kYbJym֩|I薃Zh(hNʨ^Ji )i ꣨j5Z⚫ګ[l҈ȪhjRh^>l޺mNkmK.)o6n pFoSiӨ ,qk'FpG rbOLr& s24gs:s"w >FrHwrD4JoRnjZlu6\LvB f/ھ6r)vlWT~ xzg ؂x֊oxׄ p;^v;mݗMtܦ-桇zv{xԤ5yӮ빯;?{7ò?_?xKS|S[磟sϟOc X T @`%@ VPĠ5AvЃa8B0( 7B 0 (Ђ8\3HCQTZU^YVՙ +GEZVz.*Hͪϵt-ZjӺ:m+OƘ`+FJ̴4tXKֳq-P'Kƚ<,<+z}=7 ʲun=-\Ckؾc|md9&VkgkZv5-pQZ6'nwk[&,t9\vuqYֺ-v\vUn(Jܕr׽׭ovjv}AK`.0 oH0*‡ BHP"E/B̨1bG'r Yp$I'#LdK/C8cM7/2aÞ>")RhITjiSD7F}8#TUf zҭCTlRF.ZoE+4ݶt._x .60. U\^#oeP!xˉ=,^ДED-װc˞M۸sͻ 5MUD\NҝM[vS:f.^F:c>{jS/KǏ>WWoUrH "6F8Z "!~蠇!8"H"'v".)H6rc:Z+XbBbF飄J^x$":NRdCJ`-Z/vA~a209.I$uR8'x"yiɦ©|"j֘(t2zc9N 螕鏞.(jz(MBjN骤(*BJv돶f릾. v,šJ,̪ mȂ)Rll *nԚylߒ>6KoJ'W gˮN o q1'| \'+ܲ/3\73ˉp"GLé@o $)YIK^&9IO~4$ C|"UV5 gR $e-T&w)}b3 )f>hr&ier/ir<',9vve&VUf[+2ֲ^ EY=gZ[k:[2hE\o[XTp[\U.$aܿ:7`{X^׷}tj7o1ˊصnv YB׻og+|W[_ݒכ0iڅ\HA*\X0!Ç8Haŋ/>̨q!ǎAn#Ɂ&OHyRʐ/Ɣ9eM7Wԙ%I"] dюG5&HОK+F8bՑOo^-T+ѭ,LYNJ)[iٮi`]Zԋܸtk`y x_QH1+MY3ƈ=KM3hȧ'֙a+%m6ŃM-nԿU͵hTEnU7ଡfe}uc{qəo_c׆{_KXx "Ƞ&J .x!j!2! h#baXaha8`!)d$&`OBSRYWb[r٥_cdK*&g*yI`Fgw"rɧz)('?Z96h&Z':Z)ȩ"ZB**HꩦZ꤬(+ 릶v맾ˆ뮺 򈬅KƮ ʆbJ-֊-fmH.fnn覩m;lI I0 p Ok1 wK1q ">+Ir˲/2wLs s*6 :WFJjrBR?NIuPu^(omufόb vdunsHttj|4vwwЂw҆O ׄxgeR^cs>%ۊ,yՐxwۦzɪܫ~v>{+kÞew?x|?}s؟sS?k叞 ~/W?ӯ  2Ё (AVЂ `AЃ`E8&%LWA 0| AHp8 ` 9 Ђ@ uh"B/xD&6t)&:b E-R18 (0p5,#x5Ұ9| 3saM_ (HCq,#B"hl'ID𑒼d+ML" IJN~2%*XJV.Q|eg LⱖR̥wHR%#{Ia:j f,LX&ӍǤ$4G(LH^SҴ6=MZ38ST:NwOSΤ%:eIfRӎ 8N6$'2@Nt}FQ2T iD)nEAZRliFQzΚ+ͩg͛)/4MOԘ~T,1Ѫv)eiTzUzU`EQE9Ue՗hjV{HVj=+\JVr5v^Tn+_Jذ5*^ײ5Y(غ:f/ =ZVM(e'+>v+gCzV]j [ʶ0_?عⶰ=pKn=i/Z6}s#KZ7q_[V v߆ww\Bwmy+KѾ׷`, J\8"bp#DŽ? )r ɒQ*cwO_9^z=wiWx0"` 2 B(F6x!nXaj!"2"xb$('"2vH6b#:z<@f(F*dJ@dL6 2bRbyJNc\Jb%d gijn)$rIv Ki(b,.b3hHiiF驠Y%h.*NJk^jjT)c:,ƺe|B맲N[k7Zrۭ߂[碛ۮ%^k޻ic[漪lL.|lNl%> h^k~\c|klo;n L`C53gL$ b'p84@3τJBG ot`w]6lf&=lrmujmp>uZznw\?.b_>cx/vtx9nt2zrXx[>;ľh߰nznx^{ħλ_:˓ =cۼ|K+>KN#ϽO}Nß??>4`6RĠ7A vG!L WX@ 1 iXC9yCA X& b*b`+E%z1 cA0e̠FIt# #[;ڱxda(c BD]Lc$HG62$&MZ2t(HJ)zҔTLWVjb$!IKF$cI^Q )IY%fbL&3gen IiZsL'1io.zBy ~̦/ {bb!ˉ΀,(7'ƆS5FQ:(BGЊd ?=*Җt1(Hȗ<)_pg]~ "*` :R6x! jf %pb*"a Hc&ވc).z0أYKdIJHLNPFZheR^Ie^b~ffrfl"U9f_I`6Y()`:+.b/yh)jd~hveYeZꥲfJ릶zd+B?ji j. g6 -N[kH쵹gm~gn;lʞlΆ;g;Kﻠ뮶Jk'>lm.;1{jln莬n+pr.głLެ/̦֌h lCwG#K3ݴOCSS]Wc[s -qطMsÂ~2-vmǼfϓ618WgO o>?wr<"yK_0YLcT2Lg>%-K(R3֜61JAڲܬ&8-IzԤ8NV3T%a-VJZ5JMXհu`)Zk|"udZլux*PH׷ʵ]S֥pM`{WFL#cJ٧Md ijhYS5XWMӾ_[;Wئ n+zvm,dIlur[^E<-kҶe mc]y{Ji|[_MpGK\-v^v^i BTH \P† >Hq"E/2̨! Ip$I'@vend;`o@v_super();`j@vendmethod;`k@v`w@vendclass;`n@v >0#!#_SCLD1_LIIP1RELEASEEXESIZEFLAGS-@  H f4(2ff4?@@0@5@@@@@F@ @F@a2U0*3?P !   ' / 8 AIVcg k o tx |            %*/*4*6*8p^ " ))^"*)^#"(^ " )))5d>(fQ)^Q"V^ " ))..-*-#-*- -.([/*0 ,+.([1 0+.([2 1.(`) .)5 526 299:^";:^";(e9 92 299: :9(Nj;/;(Nq?/>?@(NxA/@AB(NC/BCD(NE/DEF 0.(NG/FGH(NI/HIJ(NK/JKL/LM 2)(NN/MNO^"(*4*877c(9 /9.([36464666^"O(NN)b^"(68887Vep4@LOSeioy}  **   +,-E ) .)) 99;?AC0E.GIK)NO2493N O8N^^^^ ''())++-//11333488:::;;;;==ABBCDEEFFGGHHHIIJJKKLLMMMMOPRTTTUVXXXXXXZ[\\^pF_MSG__STATUS__ERROR__CURROW__SELF__FRAME__CFRAME__METHOD__EVENT_ samplebuffer canplaysound$T0$T1durfreqvol$T2maxlevel sampleratecycles samplecountlevelthetathetamax thetastepiix$T3bytes$T4$T5$T6$T7$T8$T9$T10$T11$T12$T13$T14$T15$T16$T17$T18$T19$T20$T21$T22$T23$T24GAMES.TETRIS.BLIPSOUND.CLAS;ASHELP.FSP.OBJECT.CLASSsamplebuffercanplaysound()Vplay_GetAttributeValue(C)NMODULEPlaySoundA(C)C_SetAttributeValue(CC)Voff(N)V_INITCONSTRUCTOR(CN)VFLOORCONSTANTPIRIFFPIB4.WAVEfmt PIB2.dataSINIB2.ht@playoff_INITCONSTRUCTOR@ x'@(@`6HALFHALF 7 10 13 16 19 >  22`/class BlipSound;`g@v`w@vpublicchar samplebuffer;`[@vpublicnumcanplaysound;`[@v`w@v%let SND_ALIAS = 10x;`]@v%let SND_ASYNC = 1x;`a@v%let SND_FILENAME = 20x;`Z@v%let SND_LOOP = 8x;`b@v%let SND_MEMORY = 4x;``@v%let SND_NODEFAULT = 2x;`]@v%let SND_NOSTOP = 10x;`_@v%let SND_SYNC = 0x;`b@v`w@vrplay:`p@vpublic method;`g@vif canplaysound then`_@vcall module ('PlaySoundA', samplebuffer, 0, &SND_ASYNC+&SND_MEMORY+&SND_NOSTOP);`!@vendmethod;`k@v`w@voff:`q@vpublic method;`g@vif canplaysound then`_@vcall module ('PlaySoundA', 0,0,&SND_MEMORY);`E@vendmethod;`k@v`w@vblipSound:`k@vpublic method dur:num freq:num vol:num;`N@v`w@vxcanplaysound = symgetn ('canplaysound');`K@v`w@vif not canplaysound then return;`S@v`w@vdeclare num maxlevel samplerate cycles samplecount ;`?@vdeclare num level;`a@vdeclare num theta thetamax thetastep i;`L@vdeclare num ix;`d@v`w@vif vol > 1 then vol = 1;`[@velse`o@vif vol < 0 then vol = 0;`[@v`w@vmaxlevel = floor (32767/2 * vol);`R@v`w@vsamplerate = 10;* samples / sec;`N@v`w@vcycles = floor (freq * dur); * number of oscillations needed for dur to achieve freq;`@v`w@v samplecount = floor (samplerate * dur); * number of samples needed for dur;`(@v`w@vthetamax = cycles * 2 * constant ('PI');`K@vthetastep = thetamax / samplecount;`P@v`w@vdeclare num bytes ;``@v`w@vbytes = samplecount*2 + 44;`X@v`w@vif bytes > mlength(samplebuffer) then`N@vsamplecount = floor(mlength(samplebuffer) / 2) - 44;`=@v `w@vbytes = samplecount*2 + 44;`X@v`w@vsamplebuffer =`e@v'RIFF'`j@v|| put (bytes-8,pib4.) %* # of bytes to next chunk;`@@v|| 'WAVE'`j@v|| 'fmt '`j@v|| put (16, pib4.)%* # of fmt bytes;`G@v|| put ( 1, pib2.)%* uncompressed format;`B@v|| put ( 1, pib2.)%* # of channels;`H@v|| put (samplerate,pib4.) %* sampling rate;`H@v|| put (samplerate*2, pib4.)%* average bytes per second;`9@v|| put ( 2, pib2.)%* bytes per sample frame;`?@v|| put (16, pib2.)%* bits per sample;`F@v;|| 'data'`j@v|| put(samplecount*2,pib4.)%* # of data bytes;`C@v;`r@v`w@vtheta = 0;`i@vix = 45;`k@v`w@vdo i = 1 to samplecount;`[@v`w@vlevel = floor (maxlevel * sin(theta));`K@vtheta + thetastep;`_@vthetastep + 0.03;`^@v`w@vsubstr (samplebuffer,ix,2) = put(level,ib2.);`D@v`w@vP>ix + 2;`j@vend;`o@vendmethod;`k@v`w@vendclass;`n@v >XLSRً *Aً *An1#   F $Tetris field - locked block handlingXLSRSASA1(:   F *Load blocks created by Createblocks.source(7Ls$MV] l)g` l)gXLSRN*AN*A % F Tetris piece (all)XLSR&,A*A ( F  Play TetrisXLSR)pQApQAoH * F %Override method for kbd in Play frameXLSR+6A6A/  F High scores methodsXLSR.#A#A 1 F High scores compositeXLSR2SAqSA[ 5 Create Tetris blocks x .60. U\^#oeP!xˉ=,^ДED-װc˞M۸sͻ 5MUD\NҝM[vS:f.^F:c>{jS/KǏ>WWoUrH "6F8Z "!~蠇!8"H"'v".)H6rc:Z+XbBbF飄J^x$":NRdCJ`-Z/vA~a209.I$uR8'x"yiɦ©|"j֘(t2zc9N 螕鏞.(jz(MBjN骤(*BJv돶f릾. v,šJ,̪ mȂ)Rll *nԚylߒ>6KoJ'W gˮN o q1'| \'+ܲ/3\73ˉp"GLé@o $)YIK^&9IO~4$ C|"UV5 gR $e-T&w)}b3 )f>hr&ier/ir<',9vve&VUf[+2ֲ^ EY=gZ[k:[2hE\o[XTp[\U.$aܿ:7`{X^׷}tj7o1ˊصnv YB׻og+|W[_ݒכ0iڅ\HA*\X0!Ç8Haŋ/>̨q!ǎAn#Ɂ&OHyRʐ/Ɣ9eM7Wԙ%I"] dюG5&HОK+F8bՑOo^-T+ѭ,LYNJ)[iٮi`]Zԋܸtk`y x_QH1+MY3ƈ=KM3hȧ'֙a+%m6ŃM-nԿU͵hTEnU7ଡfe}uc{qəo_c׆{_KXx "Ƞ&J .x!j!2! h#baXaha8`!)d$&`OBSRYWb[r٥_cdK*&g*yI`Fgw"rɧz)('?Z96h&Z':Z)ȩ"ZB**HꩦZ꤬(+ 릶v맾ˆ뮺 򈬅KƮ ʆbJ-֊-fmH.fnn覩m;lI I0 p Ok1 wK1q ">0#!#_SCLD1_LII#P1RELEASEEXESIZEFLAGS-#@74(#% <734@$@?@F@@5)^r @f6\?Q?™?P !   ' / 8 AIOUagmv  A          g     a        $  ).pd^ "1^"2^"3(4((5(Y+6/68(Y49/89:/:7/7;^="B"G<^"3(L2*?*@^"47=S9 =3(Z22 @?3 =2 320^"A AB 0BC?C> >DD>(aD(f>(xkD^p)ts^xE^"8 =C^"F^"8=SedX^"DedP^"DedH"1(C7G\"1(B7H[d ^"II^IJ^"e 8HQ8GNed ^ "F^FM(NN^$L)e d ,^ "F^7FQ(N<R^CP)e d H^ "F^SFU^X"D DSSS*S(N[V^bT)e d]^o"F^sFvX^o"F^sFX^"D7Wy^"F WA^"YFYe^"Y^YX8Wy^ep;@EValq|#)MV\_n 0 12346 56 59;4<32432>DDCDED >  E=!DC"F=#   D1CC1BB (DGH)* (GH+K -/ L0K2N1NO PO3R1RS 4T S5V1V]D6DCWBA* """$$$$$$$$%%&&(((((((*+++++,-> -00111225566677::<<<====>>?@@AACCDEEHHJJJJKKKLLOOQQQQRRRSSVVXXXXYYYZZ[[[\\__aaaabbbbcccddddddddddeffggi   _MSG__STATUS__ERROR__CURROW__SELF__FRAME__CFRAME__METHOD__EVENT_nRowsnCols rowsClearedlevelscoregameover rowsPerLevelblocksclicks$T0$T1$T2$T3$T4sn$T5cat$T6$T7$T8$T9$T10ifreqminidmaxid$T11$T12$T13$T14$T15$T16jb$T17N$T18$T19$T20$T21 remaining$T22$T23$T24$T25GAMES.TETRIS.FIELD.CLASASHELP.CLASSES.IMAGEVIEWER_C.CLASSnRowsnColssetcamRowsClearedrowsClearedsetcamLevellevelsetcamScorescoregameoverrowsPerLevelblocksclicksO()V_init_GetAttributeValue(C)N.imagegrid_SetAttributeValue(CC)VMODFLOOREXPCLICKSGAMES.TETRIS.BLIPSOUND.CLASS_NEW__INITCONSTRUCTOR(N,)V(CO:GAMES.TETRIS.BLIPSOUND.CLASS;N)V(CNN)O(*)(CON)V()NgetNumberOfRowsgetNumberOfColumnsclearBlocksBLOCKS(CN)O(*,*)_term(CN )V(N)VframeIdSASHELP.FSP.OBJECT.CLASS(C)O_getNumVarlabel8.3.remaining2.offeh(HHHHHH;BI^it $$,,,@N%_initgetNumberOfRowsgetNumberOfColumns clearBlocks setcamScore setcamLevelsetcamRowsCleared_term @ x'@ (@ )*+ ,@ -@ .@/@`g6HALFHALF 7 10 13 16 19 22`/class Field extends sashelp.classes.ImageViewer_c;`E@vprotected num nRows / (initialValue = 20);`K@vprotected num nCols / (initialValue = 10);`K@v`w@vpublic num rowsCleared / (initialValue = 0, setcam="setcamRowsCleared");`-@vpublic num level / (initialValue = 0, setcam="setcamLevel");`9@vpublic num score / (initialValue = 0, setcam="setcamScore");`9@vpublic num gameover / (initialValue = 0);`L@vpublic num rowsPerLevel / (initialValue = 10);`G@v`w@vpublic Object blocks [*,*];`Z@v`w@vpublic Object clicks [*];`\@v`w@v_init:`o@vmethod / (state='O');``@v_super();`j@vredim (blocks,nRows,nCols);`X@v`w@vdeclare char(131) sn = screenname();`O@vdeclare char(65) cat = scan(sn,1,'.') || '.' || scan(sn,2,'.') || '.';`-@v`w@vimage = cat || 'grid';`]@v`w@vredim (clicks,nRows);`^@vdeclare num i freq;``@v`w@v* id values corresponding to notes;`P@vdeclare num minid = 33;`\@vdeclare num maxid = 45;`\@v`w@vdo i = 1 to nRows;`a@v* new higher pitched sound every five rows;`F@vif mod (i-1,5) = 0 then do;`V@v* convert noteid to corresponding frequency;`C@vfreq = minid + (maxid-minid) * (i-1) / (nRows-1);`>@vfreq = 3.430845 + 0.057742 * freq;`M@vfreq = floor(exp (freq));`V@v* compute waveform for desired blip sound;`E@vclicks[i] = _new_ BlipSound (.07, freq, .1); * dur,freq,vol;`3@vend;`m@velse`m@vclicks[i] = clicks[i-1];`W@vend;`o@vendmethod;`k@v`w@vgetNumberOfRows:`e@vmethod return=num;`c@vreturn nRows;`f@vendmethod;`k@v`w@vgetNumberOfColumns:`b@vm>  0#!#_SCLD1_LII P1RELEASEEXESIZEFLAGS?- 6@ Lxd *   *u*p?@@P ! ( , /7;? CGK O QVZ ^ c g l n("($(Y #/#&(Y'/&'%(x*^ )t#^%+(*+)7,-(S4* *..,/(9(/(-8,- +-^;)>/"(/(-0/%(/(-1^C)F^I)LO2^P)S(WV3(W]4:d(,q2p"2JMQRV^cdq~## $# $'*+* */( 0122/2/ -342/  "$$&')+,,p_MSG__STATUS__ERROR__CURROW_in_path$T0snout_cat$T1$T2$T3img$T4$T5iname$T6$T7fileentattrwhWORK.SASHELP.FSP.IMGDAT.CLASS_NEW__INITCONSTRUCTORSASHELP.FSP.OBJECT.CLASS()VBYTEa.gifgrid.gif_term\_readFilepath_writeCatalog_getAttributeswidthheightname=w=h= hlttttttttttimportHALFHALF 7 10 13 16 19 22`//* Richard A. DeVenezia``@v * Aug 11 2004`i@v *`u@v * Create IMAGE entries for Tetris game`P@vF */`t@v`w@vinit:`r@vin_path = pathname ('WORK');`Y@v`w@vsn = screenname();`c@vout_cat = scan(sn,1,'.') || '.' || scan(sn,2,'.');`C@v`w@vdeclare sashelp.fsp.imgdat img`W@v= _new_ sashelp.fsp.imgdat ();`W@v`w@vdo i = 1 to 7;`g@vname = byte(rank('a')-1+i) || '.gif';`N@vlink import;`g@vend;`q@v`w@vname = 'grid.gif';`c@vlink import;`i@v`w@vimg._term();`i@vreturn;`p@v`w@vimport:`p@vfile = in_path || '\' || name;`W@vent= out_cat || '.' || name;`W@v`w@vimg._readFilepath (file);`\@vimg._writeCatalog (ent);`]@v`w@vdeclare list attr = {};`^@v  `w@vimg._getAttributes (attr);`[@v`w@vw = getNitemN (attr,'width');`X@vh = getNitemN (attr,'height');`W@v`w@vput name= w= h=;`e@v`w@vattr = dellist (attr);`_@vreturn;`p@v >0#!#_SCLD1_LIIP1RELEASEEXESIZEFLAGS- P@ 0peX`cX=4(4 {?$@3?@o@D@@@@Q~?™?MbP?@@@e@Y@r@@P !   ' / 8 AIOU[afnv          %O U       [     A"', 1 7 @DHMR W\ c hm t y~               # # # # # # # ### ) ) ) ) ) ) ) ) )) 0 l11 [2 $2 2 &3 +3 3 3 3 3035:3 ?5 5 B5K5 l8P8U Z;`;e;j; o; y; ; ;; = = = = = = == == = ==== == == o= @ $ $ $  $ $ 6  *O***pd(q,AOC1$AC:9^@"E^J"OA"TE"YF(^H"eI(jK"qL(vN(}O"L"LfA"L"I(M"F(J"E(G(D"L"LfA"L"I(M"F(J"E(G(D"L"LfA"L"I(M"F(J"E(G(D"L"LfA"L"I(M"F(J"E(G(D"L"LfA"L"I(M" F(J"E(G(D"L"LfA"L"I(M"F(J"#E(G(D"(L"Lf"L(-N7P4z"L(;M7QBy"L(IK7RPx^W"bSSw^g"r^w"r8RPo8QBl8P4i(T(YB/BV(YW/VWX/XU+Z^@O^>@N ONM(K^"^"O ON(M^"[\([O([O^"O(ZN^"O(ZN(xO^)t^ "(xO^)t^"(xO^)t^"(xO^)t^$"(,+O7S2(9OOJ^>"E^^J^Q/UAY^>"E^^T^Q8S2(;OON^["ed_^h"k_pedr^"kaa1P^"E^^^Q^"E^^^Q^"E^^^Q^"E^^^Q:edC^"kdd^"OO:^"7e2^"M^"K^"J KJHcHG^"E^^^Q8e2 cO^"^^^flfN ONM^"K MKJ(HHG^"^" ed ^"kii^"OO ^"7j2)^"M^%"K^"J KJHhHG^"E^^0^Q8j2 hO^"^^7^klkN ONM^"K MKJ(HHG^:"^?"BedD^"knn6^O"OOB^R"^"^^7^oloO mN^"M NMKOKJJH^W"^\"_eda^"krrU^l"OO_^o"^"^^^slsO qN^"M NMKOKJJH^t"^y"|ed~ tO^"^^7^uluN ONM^"K MKJ(HHG=edt vO^"^^^wlwN ONM^"K MKJ(HHG=edi xO^"N ONM^"^^7^ylyKMKJJH(GedW zO^"N ONM^"^^^{l{KMKJJH(GedO^"OO7|2^"E^^7^^"^^Ql}^"E^^7^lN^"MNMK KJ^"~^"E^^^lNNM^D"^"E^^^lNNM^"KMKJ JH^b"OO*~^"^^^lN N^"^^^lN N}^"^^^lN N^"^^^lN N *O^;"N^"E^^>^lK NKJ(8|2^ "O6OO^"ed#^"72}^"E^^7^^#"^&^Ql^"E^^7^lN^"MNMK KJ^"^"E^^^lNNM^D"^"E^^^lNNM^"KMKJ JH^ "^"^^"^+lOOOO*^"^^.^lN N^"^^7^lN N^"^^@^lN N^"^^I^lN No* O^;"N^R"E^^^lK NKJ(*82"^ "O6OO^"e#d)Y72^d"E^^7^lNNM^D"^d"E^^7^lNNM^"KMKJ JH^ "^d"E^^^^k"n^q^Ql^d"E^^^lN^"MNMK KJ^"^"^^j^vlOOOO-*;^"^^y^lN N^"^^^lN N.^"^^^lN N^"^^^lN N* O^;"N^"E^^7^lK NKJ(^"^^^Q82^"O6OO^"e)d0Jd1^"^^"N^^l^^"^"O^;"e1^"OO(;O^"NONM^"e0d2&^"OO"L(-*72dd3^ "O^"M^"K MKJOJ^"O^"M^"K MKJOJ^"^"OON NM^D"^"^"OON NM^D"^"^^^vlOO||^"^^^+lOO|^"^^^lN^"^lK NKJJ|^"^lN^"^^^lK NKJJ|e382e2!^'"*OONN^"O6OO^/"^"O"4L(9MOM^@"^ "O^"^"O^"d5C(;^M"OON(a=MMK NKJJo^P"O(SN(;^"^ZlOOh]^M"OO4d8^">^"N^l^Y^"^_"O^;"^"OOQY^"^blOOH^e"^h"O^e"N^h"M NMK^"^blJ KJH HGOG OON^["e8(a;OO{|e5d:Y^"se:d;p^"^b6^}Q^"^Q^"^^^"^b(L^Q^"^^^Q^"^^^m^Q7(N/^Q(O8^Q^Q^"^e;d=$72;^"O^"M^"KOK^"O^"M^"KOK^"^Q^"^lNN^"^Q8272Q^"O^"M^"KOK^"O^"M^"KOK^ "E^^"^ Q82<^"^ vl^"^ +l**7 7 h^"^lNNMMh8 _L7 {^"^^$ Q^"^^- m(+0 NN68 j>(7 O7 ^"^l^"^> Q^F G 8 ~ O7J 7 ^"^Q lMM`^"^Q ^7^"M6M^"^Z Q^"^Q lN^"^c Q8 8J 7 ^"^l Q8 668 ^Ou ^"^{ N~ O^"^^b^lNNMMK OKJ6J^ Q^"^^ ^"^{ (L ^ Q^"^ 6^ Q^"^ ^"^^ ^kOO^t " ^"^^ ^"^ lO^"^^ ^lN ON(N ^ Qe= O^"E^ G ^"E^ G ^"E^ G ^"E^ G p05:?DHOV_ery)>Pot  %HMxy #-5:C>GQ[ajosw !*+.8:EIPUZ\hq{lll0ll@A!AB'A(@)*A)+ DGF HJI KML N E HKNOO  ONI MKF JHE G L MJGDONKHONKHONKHONKHONKHOL NNL MML KK OPQR,- .QPS)/ .RPSB T0B T0W2,456MKK)7NMM89:;<= >?@ Z[AO Z\BO [O:N [O;NDO]ZOEC])FC]C]C]ZGO OCOS,IJKS)JYS N_ ,O_`u PCO `CO `CO `CO `cu RRCOe .NMe,UTGe,VT,JHGR hu WWCOj >.NMjXGjXGW mu YYHY quZZHZ tuvuxuEn6HGzuCO|aXaSbS cO~ cO~ cO} cO}dSCM|JHOCOX5 cO cO cO cOCMCObTh cO cO cO cOiSCMjOmONn#of M .N .N cO cM cO cM!r6O NL MC  O Nj uYpuy zu{}|~|j|   |O >| .NM .NM cOCO c^  >JN O c O  cN X cN c  |yy#~}                     "##00111122223367777777777778::::::::::::::<<=>>DDEEEEFFFFGGJKKKKKKKKKKKKLNNNNNNNNNNNNNNPPQRRXXYYYYZZZZ[[]]]]]]]]]]]]]__`aagghhhhiiiijjlllllllllllllnnoppuuvvvvvvvv>vvvvvww||}}}}}}}}}}}}}~~          ########$$$$$$$$&&''''''(())))))+++++++,,-------/001111122222356677777888889::<==BCCCCCEEEEEFFFFFFFHHHHIIIIJOOPUUUUUUUVVVWXZZZZZZZ\\\\^^^^^^^__aabbbbdddfiiiijjjjkkkkkkkkkkkkkkkkmmmmnooqrrwwxxxyy}}~~~~~~~p>######################################################################################################))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))001111111111111111000000000002222222222333333333333333333333333333333333333333333333333333333333333333333333333333332222pb555555555555555555555555588888888888888888888888888888888888888888888888855555::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;===================================================================================================================================================================================================================================p>_MSG__STATUS__ERROR__CURROW__SELF__FRAME__CFRAME__METHOD__EVENT_blockfieldpiecestatesidegravitytimeout baseSleepvisiblexycolrowdropWiggleTime interval1 interval10ABCDEFGPlocation$T0$A#11$T1$T2$T3$T4$T5$T6$T7$T8$T9$T10$T11$T12blocknosncat$T13$T14$T15$T16attrs_region__attrs_$T17$T18$T19$T20incamX$T21$T22incamY$T23$T24incamRow$T25$T26incamCol$T27$T28$T29$T30$T31$T32itrowbrowlcolrcollblockedblockeddx$T33$T34rblocked$T35$T36dybblocked$T37$T38oldyblip$T39nnewxnewy$T40$T41$T42dtinterval$T43$T44$T45level$T46$T47$T48 remaininggameoverlabel$T49rrrcc rowsCleared$T50nr$T51ncadvancer$T52$T53$T54factor$T55score$T56$T57GAMES.TETRIS.PIECE.CLAS/ASHELP.FSP.OBJECT.CLASSblockfieldpiecestatesidegravit> ytimeoutbaseSleepYes NosetcamVisiblevisiblesetcamXxsetcamYysetcamColcolsetcamRowrowdropWiggleTimeinterval1interval10ABCDEFGPlocationO()V_INITCONSTRUCTORGAMES.TETRIS.FIELD.CLASS(O:GAMES.TETRIS.FIELD.CLASS;C)VERROR: pieceis out of range (A-G)_SetAttributeValue(CO:GAMES.TETRIS.FIELD.CLASS;)V(CC)V_GetAttributeValue(CN)N(*,*,*)LOCATION(CN)V.FLOORwidthSASHELP.FSP.WIDGET.CLASS(C)NgetNumberOfColumns()N(CN)VulxulylrxlryunitsPixelsNoimageSourceCatalog_region__attrs_BLOCKSASHELP.CLASSES.IMAGEVIEWER_C.CLASS_NEW_(CO:SASHELP.CLASSES.IMAGEVIEWER_C.CLASS;N)VYRANUNI(CNN)O(4)imageSASHELP.I0808.SASIDSDATETIME()CgetPiece(C)CerrorMessageincamX(N)NhorizontalPosition(CNV)N(4,4,2)(C)OincamYverticalPositionincamRowincamColblockRowOfblockColOftopOfRowROUNDleftOfColleftBLOCKROWOFBLOCKCOLOFblocksLEFTOFCOLright(N)VdowngetNumberOfRowsTOPOFROWgameoverdropGAMES.TETRIS.BLIPSOUND.CLASSclicksplayDOWNcanRotaterotateCANROTATEwaitSLEEPlevel()OgetFieldnextLevelrowsClearedframeId_getNumVarlabel2.remaining0YesGet Ready 1.clearBlockslockSASHELP_termscore8.rowsPerLevelNEXTLEVELtermBlocksK!KhL``````<Zx g #$%%$)*++*.025668;=>>==BBDDDGD#&M4SSSSSSSS##f#6#6v###A_INITCONSTRUCTOR_INITCONSTRUCTORgetPiece setcamVisiblesetcamXsetcamY setcamRow setcamCol blockRowOf blockColOftopOfRow leftOfColleftrightdowndrop canRotaterotatewaitgetField nextLevellock termBlocks@ x'@(@)@*@ +@ ,@ -@.@ / 01234@ 5@ 6@ 7@ 8@ 9/@ :@ ; @ <:@ =@ >@?@b @ g @ l @ p @ 6HALFHALF 7 10 13 16 19 22`//*`@ * Richard A. DeVenezia`@ * Tetris piece`@ */`@`@/*`@ * Each piece is composed of four blocks in a distinct`@m * geometric arrangement.`@ */`@`@`@class Piece ;`@`@public Object block[4];`@`@1protected Object field;`@`@protected char piece;`@public num state / ( initialValue = 1 );`@public num side / ( initialValue = . ); * dimension of side;`@public num gravity / ( initialValue = . );`@public num timeout;`@protected num baseSleep / (initialValue = 10);`@J`@ public char(3) visible / ( validValues="Yes No", setcam="setcamVisible") ;`@public num x / ( setcam="setcamX" );`@public num y / ( setcam="setcamY" );`@public num col / ( setcam="setcamCol" );`@public num row / ( setcam="setcamRow" );`@`@public num dropWiggleTime / ( initialValue = 0.6 );`@,public num interval1/ ( initialValue = 250 );* level1 time between drops;`@public num interval10 / ( initialValue =40 );* level 10 time between drops;`@`@/*`@* Enumerate the arragements of the blocks in each of the`@* four rotations of each piece`@*/`@`@private num A [ 4, 4, 4 ] / ( initialValue =`@{ ., ., 1, .`@, ., ., 2, .`@, ., ., 3, .`@, ., ., 4, .`@`@, ., ., ., .`@, ., ., ., .`@|, 4, 3, 2, 1`@, ., ., ., .`@`@, ., ., 4, .`@, ., ., 3, .`@, ., ., 2, .`@, ., ., 1, .`@`@&!>! , ., ., ., .`@, ., ., ., .`@, 1, 2, 3, 4`@, ., ., ., .`@});`@`@private num B [ 4, 3, 3 ] / ( initialValue =`@{ ., 1, .`@, 2, 3, 4`@, ., ., .`@j`@, ., 2, .`@, ., 3, 1`@, ., 4, .`@`@, ., ., .`@, 4, 3, 2`@, ., 1, .`@`@, ., 4, .`@, 1, 3, .`@, ., 2, .`@});`@`@private num C [ 4, 3, 3 ] / ( initialValue =`@{ ., ., 1`@j, 2, 3, 4`@, ., ., .`@`@, ., 2, .`@, ., 3, .`@, ., 4, 1`@`@, ., ., .`@d, 4, 3, 2`@, 1, ., .`@`@, 1, 4, .`@, ., 3, .`@, ., 2, .`@});`@`@`@private num D [ 4, 3, 3 ] / ( initialValue =`@{ ., ., .`@, 1, 2, 3`@, ., ., 4`@`@, ., 1, .`@, ., 2, .`@j, 4, 3, .`@`@, 4, ., .`@, 3, 2, 1`@, ., ., .`@`@, ., 3, 4`@, ., 2, .`@~, ., 1, .`@});`@`@private num E [ 4, 2, 2 ] / ( initialValue =`@{ 1, 2`@, 3, 4`@`@, 3, 1`@U, 4, 2`@`@, 4, 3`@, 2, 1`@`@, 2, 4`@, 1, 3`@});`@`@private num F [ 4, 3, 3 ] / ( initialValue =`@{ ., 1, 2`@, 3, 4, .`@, ., ., .`@`@, ., 3, .`@, ., 4, 1`@j, ., ., 2`@`@, ., ., .`@, ., 4, 3`@, 2, 1, .`@`@, 2, ., .`@, 1, 4, .`@, ., 3, .`@});`@`@private num G [ 4, 3, 3 ] / ( initialValue =`@{ 1, 2, .`@, ., 3, 4`@, ., ., .`@`@j, ., ., 1`@, ., 3, 2`@, ., 4, .`@`@, ., ., .`@, 4, 3, .`@, ., 2, 1`@`@, ., 4, .`@, 2, 3, .`@, 1, ., .`@});`@`@/*`@* Array P will contain the enumeration of whichever`@* piece this instance is rendering`@*/`@`@private num P[*,*,*];`@`@/*`@* Array location is an inverse mapping of P that`@* tells which row and col a block is in in a given`@* rotation (aka state)`@*/`@`@private num location[4,4,2];`@`@`@Piece:`@private method / ( state='O' );`@endmethod;`@`@`@Piece:`@public method field:Field piece:char(1);`@`@piece = upcase (piece);`@`@if piece not in ('A','B','C','D','E','F','G') then do;`@put 'ERROR: piece' piece 'is out of range (A-G)';`@return;`@end;`@`@_self_.field = field;`@_self_.piece = piece;`@`@select (piece);`@when ('A') redim (P,dim(A,1),dim(A,2),dim(A,3)); P=A;`@when ('B') redim (P,dim(B,1),dim(B,2),dim(B,3)); P=B;`@when ('C') redim (P,dim(C,1),dim(C,2),dim(C,3)); P=C;`@when ('D') redim (P,dim(D,1),dim(D,2),dim(D,3)); P=D;`@when ('E') redim (P,dim(E,1),dim(E,2),dim(E,3)); P=E;`@when ('F') redim (P,dim(F,1),dim(F,2),dim(F,3)); P=F;`@when ('G') redim (P,dim(G,1),dim(G,2),dim(G,3)); P=G;`@otherwise;`@end;`@ >"!`@declare num state row col blockno;`@`@/*`@* Populate the inverse mapping from the block enumeration`@*/`@do state = 1 to dim (P,1);`@do row = 1 to dim (P,2);`@do col = 1 to dim (P,3);`@blockno = P[state,row,col];`@if blockno = . then continue;`@`@location [state,blockno,1] = row;`@location [state,blockno,2] = col;`@end;`@end;`@end;`@`@declare char(131) sn = screenname();`@declare char(65) cat = scan(sn,1,'.') || '.' || scan(sn,2,'.') || '.';`@`@declare list attrs = {};`@`@[side = floor(field.width / field.getNumberOfColumns());`@gravity = floor (side/3);`@`@declare list _region_ = { ulx=1, uly=1, lrx=1, lry=1, units='Pixels' };`@declare list _attrs_= { visible='No', imageSource='Catalog' };`@`@setNitemL (attrs, _region_, '_region_');`@setNitemL (attrs, _attrs_,'_attrs_');`@`@setNitemN (_region_, side, 'lrx');`@setNitemN (_region_, side, 'lry');`@`@/*`@* Instantiate the four image viewers controls that`@* the blocks will be displayed in`@*/`@#`@block[1] = _neo_ sashelp.classes.imageviewer_c (attrs);`@block[2] = _neo_ sashelp.classes.imageviewer_c (attrs);`@block[3] = _neo_ sashelp.classes.imageviewer_c (attrs);`@block[4] = _neo_ sashelp.classes.imageviewer_c (attrs);`@`@dellist (attrs, 'Y');`@`@/*`@* Load the block images into the viewers`@* Note the small chance of getting a SAS piece`@*/`@`@do blockno = 1 to 4;`@if ranuni(0) < 0.0075`@then block[blockno].image = 'SASHELP.I0808.SASIDS';`@else block[blockno].image = cat||piece;`@end;`@`@timeout = datetime() + .2;`@endmethod;`@`@`@`@sgetPiece:`@method return=char;`@return piece;`@endmethod;`@`@`@`@setcamVisible:`@protected method visible:char return=num;`@if errorMessage ne '' then return 1;`@`@block[1].visible = visible;`@block[2].visible = visible;`@block[3].visible = visible;`@block[4].visible = visible;`@`@ return 0;`@endmethod;`@`@/*`@* The piece horizontal position is to be set`@* errorMessage is an attribute of all Objects, and will be`@* non-blank if an attempt is made to place and imageviewer (block)`@* outside allowed bounds.`@* incamX is used as a semaphore to prevent`@* reentry while the method is running`@*/`@`@private num incamX / ( initialValue = 0 );`@setcamX:`@protected method x:num return=num;`@if errorMessage ne '' then return 1;`@if incamX then return 0;`@incamX = 1;`@`@declare num blockno;`@do blockno = 1 to 4;`@ block[blockno].horizontalPosition = x + location[state,blockno,2] * side;`@end;`@`@col = floor ( ( x-1 - field.horizontalPosition ) / side ) + 1;`@`@incamX = 0;`@return 0;`@endmethod;`@`@`@`@private num incamY / ( initialValue = 0 );`@setcamY:`@protected method y:num return=num;`@if errorMessage ne '' then return 1;`@if incamY then return 0;`@incamY = 1;`@`@declar#>#"e num blockno;`@do blockno = 1 to 4;`@block[blockno].verticalPosition = y + location[state,blockno,1] * side;`@end;`@`@row = floor ( ( y-1 - field.verticalPosition ) / side ) + 1;`@`@incamY = 0;`@return 0;`@endmethod;`@`@`@`@private num incamRow / ( initialValue = 0 );`@setcamRow:`@protected method row:num return=num;`@if errorMessage ne '' then return 1;`@if incamRow then return 0;`@incamRow = 1;`@`@y = field.verticalPosition + (row-1) * side + 1;`@`@incamRow = 0;`@return 0;`@endmethod;`@`@`@`@private num incamCol / ( initialValue = 0 );`@setcamCol:`@protected method col:num return=num;`@if errorMessage ne '' then return 1;`@if incamCol then return 0;`@incamCol = 1;`@`@x = field.horizontalPosition + (col-1) * side + 1;`@`@incamCol = 0;`@return 0;`@endmethod;`@`@`@`@blockRowOf:`@private method y:num return=num;`@return floor ( ( y-1 - field.verticalPosition ) / side ) + 1;`@endmethod;`@`@`@`@blockColOf:`@private method x:num return=num;`@return floor ( ( x-1 - field.horizontalPosition ) / side ) + 1;`@endmethod;`@`@`@`@topOfRow:`@private method row:num return=num;`@return round((row-1) * side + field.verticalPosition + 1,1);`@endmethod;`@`@`@`@leftOfCol:`@private method col:num return=num;`@return round((col-1) * side + field.horizontalPosition + 1,1);`@endmethod;`@`@`@`@left:`@method;`@sdeclare num i trow brow lcol rcol lblocked blocked ;`@declare num dx = -side;*/3;`@`@do i = 1 to 4;`@trow = blockRowOf ( block[i].verticalPosition );`@brow = blockRowOf ( block[i].verticalPosition + side-1 );`@lcol = blockColOf ( block[i].horizontalPosition + dx );`@rcol = blockColOf ( block[i].horizontalPosition + dx + side-1 );`@`@lblocked = (lcol < 1);`@`@if not lblocked then do;`@blocked = 0;`@if brow > 0 then do;`@blocked = blocked or _self_.field.blocks[brow,lcol];`@blocked = blocked or _self_.field.blocks[brow,rcol];`@end;`@if trow > 0 then do;`@blocked = blocked or _self_.field.blocks[trow,lcol];`@blocked = blocked or _self_.field.blocks[trow,rcol];`@end;`@end;`@else`@blocked = 1;`@`@if blocked then do;`@dx = round(leftOfCol (lcol+1) - block[i].horizontalPosition,1);`@end;`@end;`@`@x + dx;`@endmethod;`@`@`@`@right:`@method;`@declare num i trow brow lcol rcol rblocked blocked ;`@declare num dx = side;*/3;`@`@Qdo i = 1 to 4;`@trow = blockRowOf ( block[i].verticalPosition );`@brow = blockRowOf ( block[i].verticalPosition + side-1 );`@lcol = blockColOf ( block[i].horizontalPosition + dx );`@rcol = blockColOf ( block[i].horizontalPosition + dx + side-1 );`@`@rblocked = (rcol > field.getNumberOfColumns());`@`@$if not rblocked then do;`@block">$#ed = 0;`@if brow > 0 then do;`@blocked = blocked or _self_.field.blocks[brow,lcol];`@blocked = blocked or _self_.field.blocks[brow,rcol];`@end;`@if trow > 0 then do;`@blocked = blocked or _self_.field.blocks[trow,lcol];`@blocked = blocked or _self_.field.blocks[trow,rcol];`@end;`@end;`@else`@blocked = 1;`@`@if blocked then do;`@dx = round(leftOfCol (rcol-1) - block[i].horizontalPosition,1);`@a`@if dx < 0 then dx = 0;`@end;`@end;`@`@x + dx;`@endmethod;`@`@`@`@down:`@method dy:input:num;`@declare num i trow brow lcol rcol bblocked blocked ;`@`@do i = 1 to 4;`@trow = blockRowOf ( block[i].verticalPosition + dy );`@/brow = blockRowOf ( block[i].verticalPosition + dy + side-1 );`@lcol = blockColOf ( block[i].horizontalPosition );`@rcol = blockColOf ( block[i].horizontalPosition + side-1 );`@`@bblocked = (brow > field.getNumberOfRows());`@`@if not bblocked then do;`@blocked = 0;`@8if brow > 0 then do;`@blocked = blocked or _self_.field.blocks[brow,lcol];`@blocked = blocked or _self_.field.blocks[brow,rcol];`@end;`@if trow > 0 then do;`@blocked = blocked or _self_.field.blocks[trow,lcol];`@blocked = blocked or _self_.field.blocks[trow,rcol];`@end;`@end;`@else`@blocked = 1;`@`@if blocked then do;`@`@dy = round(topOfRow (brow-1) - block[i].verticalPosition,1);`@`@uif dy < 0 then do;`@field.gameover = 1;`@return;`@end;`@end;`@end;`@`@y + dy;`@^endmethod;`@`@`@`@drop:`@public method;`@declare num oldy;`@`@do until (y = oldy);`@declare BlipSound blip = _self_.field.clicks[row];`@blip.play();`@`@oldy = y;`@down(side);`@end;`@`@timeout = datetime() + dropWiggleTime;`@endmethod;`@`@`@`@canRotate:`@method return=num;`@declare num state = _self_.state + 1;`@declare num n = dim(P,1);`@if state > n then state = 1;`@`@declare num blockno;`@do blockno = 1 to 4;`@`@declare num newx newy;`@declare num trow brow lcol rcol;`@ `@newx = x + location[state,blockno,2] * side ;`@newy = y + location[state,blockno,1] * side ;`@`@trow = blockRowOf ( newy );`@brow = blockRowOf ( newy + side-1 );`@lcol = blockColOf ( newx );`@rcol = blockColOf ( newx + side-1 );`@ `@if (brow > field.getNumberOfRows()) then return 0;`@if (lcol < 1) then return 0;`@if (rcol > field.getNumberOfColumns()) then return 0;`@`@if brow > 0 then`@if _self_.field.blocks[brow,lcol]`@or _self_.field.blocks[brow,rcol]`@then`@return 0;`@`@if trow > 0 then`@if _self_.field.blocks[trow,lcol]`@or _self_.field.blocks[trow,rcol]`@then`@return 0;`@Nend;`@`@return 1;`@endmethod;`@`@`@`@rotate:`@method;`@if not canRotate() then return;`@`@state + 1;`@i%>%$f state > dim(_self_.P,1) then state = 1;`@`@x = x;* cause setCam methods to run;`@y = y;`@endmethod;`@`@`@`@wait:`@method return=num;`@declare num dt = datetime();`@declare num oldy interval;`@`@do until (event());`@`@do while (dt= timeout) then do;`@`@declare BlipSound blip = _self_.field.clicks[row];`@blip.play();`@`@oldy = y;`@down (gravity);`@`@if oldy = y then do;`@* time for a new piece;`@return 1;`@end;`@`@if field.level > 10`@then interval = interval10;`@else interval = interval1 + (interval10-interval1) * field.level / 10;`@`@timeout = dt + interval / 10;`@end;`@end;`@`@return 0;`@xendmethod;`@`@`@`@getField:`@public method return=Object;`@return field;`@endmethod;`@`@`@nextLevel:`@protected method;`@field.level + 1;`@field.rowsCleared = 0;`@`@declare Object level;`@field.frameId._getNumVar ('level', level);`@level.label = put (field.level,2.);`@`@declare Object remaining;`@field.frameId._getNumVar ('remaining', remaining);`@remaining.label = '0';`@`@declare Object gameover;`@declare Char label;`@declare num i;`@`@field.frameId._getNumVar ('gameover', gameover);`@label = gameover.label;`@gameover.visible = 'Yes';`@`@do i = 5 to 0 by -1 until (i=1);`@gameover.label = 'Get Ready ' || put (i,1.);`@sleep (1,1);`@end;`@gameover.visible = 'No';`@gameover.label = label;`@`@field.clearBlocks();`@endmethod;`@x`@`@`@lock:`@public method;`@declare num i r c rr cc rowsCleared;`@declare Object b;`@`@do i = 1 to 4;`@r = row + location[state,i,1] ;`@c = col + location[state,i,2] ;`@`@if r < 1 then do;`@field.gameover = 1;`@return;`@end;`@`@if _self_.field.blocks[r,c] then do;`@field.gameover = 1;`@return;`@end;`@end;`@`@do i = 1 to 4;`@ r = row + location[state,i,1] ;`@c = col + location[state,i,2] ;`@_self_.field.blocks[r,c] = block[i];`@end;`@`@declare num nr = field.getNumberOfRows();`@declare num nc = field.getNumberOfColumns ();`@declare num advancer = 0;`@`@rowsCleared = 0;`@`@do r = nr to 1 by -1;`@`@do c = 1 to nc ;`@if not _self_.field.blocks[r,c] then leave;`@end;`@`@if c > nc then do;`@* row cleared;`@do c = 1 to nc;`@_self_.field.blocks[r,c].visible = 'No';`@if index (_self_.field.blocks[r,c].image, 'SASHELP') then advancer+1;`@end;`@refresh;`@sleep (175,0.001);`@`@do c = 1 to nc;`@b = _self_.field.blocks[r,c];`@_self_.field.blocks[r,c] = 0;`@b._term();`@$>%end;`@`@do rr = r-1 to 1 by -1;`@do cc = 1 to nc;`@if _self_.field.blocks[rr,cc] then`@_self_.field.blocks[rr,cc].verticalPosition + side;`@b = _self_.field.blocks[rr,cc] ;`@_self_.field.blocks[rr+1,cc] = b;`@end;`@end;`@z`@do cc = 1 to nc;`@_self_.field.blocks[1,cc] = 0;`@end;`@`@rowsCleared + 1;`@`@r + 1;`@end;`@end;`@`@* per http://folk.uio.no/perjp/java/;`@declare num factor [0:4] = (0,40,100,300,1200);`@`@field.score + factor[rowsCleared] * (field.level+1+advancer);`@`@ declare Object score;`@field.frameId._getNumVar ('score', score);`@score.label = put (field.score,8.);`@`@field.rowsCleared + rowsCleared;`@if field.rowsCleared >= field.rowsPerLevel then nextLevel();`@`@declare Object remaining;`@field.frameId._getNumVar ('remaining', remaining);`@r = field.rowsPerLevel - field.rowsCleared;`@remaining.label = put (r,2.);`@endmethod;`@`@`@termBlocks:`@public method;`@block[1]._term();`@block[2]._term();`@block[3]._term();`@block[4]._term();`@endmethod;`@`@endclass;`@%'>'&0##_SCLD1_LIIP1RELEASEEXESIZEFLAGS<6HALFHALF 7 10 13 16 19 22`//* Richard A. DeVenezia`@ * August 2004`@  */`@`@ init:`@sn = screenname();`@<cat = scan(sn,1,'.') || '.' || scan(sn,2,'.') || '.';`@`@>_frame_.title = "SASTris - Richard A. DeVenezia, 2004";`@`@Gdeclare list box = {ulx=0,uly=0,lrx=500,lry=750,units='pixels'};`@._frame_._convertBox (box,'characters');`@._frame_.width = getNitemN (box, 'LRX');`@/_frame_.height = getNitemN (box, 'LRY');`@`@)_frame_.backgroundColor = 'Black';`@A* _frame_.bannerType = 'None';* can only be set in Build;`@`@'_frame_._winfo ('numxpixel', w);`@'_frame_._winfo ('numypixel', h);`@`@ *@<-;`@0declare sashelp.classes.textlabel_c score`@*= _neo_ sashelp.classes.textlabel_c`@B( { _region_ = {ulx=1,uly=10,lrx=120,lry=38,units='pixels'}`@&, _attrs_= { labelColor='White'`@, label='Score'`@, justification='Center'`@, borderStyle='Simple'`@, borderColor='cx303030'`@<, font={NAME='Comic Sans MS', POINTS=140, WEIGHT=9 }}`@ } );`@`@Mscore.horizontalPosition = floor ( ( (w-4) - score.width) * 1 / 2 );`@`@ *@<-;`@0declare sashelp.classes.textlabel_c level`@*= _neo_ sashelp.classes.textlabel_c`@A( { _region_ = {ulx=1,uly=10,lrx=45,lry=38,units='pixels'}`@&, _attrs_= { labelColor='White'`@, label='Level'`@, justification='Center'`@, borderStyle='Simple'`@, borderColor='cx303030'`@<, font={NAME='Comic Sans MS', POINTS=120, WEIGHT=9 }}`@ } );`@`@Nlevel.horizontalPosition = score.horizontalPosition + score.width + 3;`@`@ *@<-;`@4declare sashelp.classes.textlabel_c remaining`@*= _neo_ sashelp.classes.textlabel_c`@A( { _region_ = {ulx=1,uly=10,lrx=40,lry=38,units='pixels'}`@&, _attrs_= { labelColor='White'`@, label='Remain'`@, justification='Center'`@, borderStyle='Simple'`@, borderColor='cx303030'`@<, font={NAME='Comic Sans MS', POINTS=100, WEIGHT=9 }}`@ } );`@`@R remaining.horizontalPosition = level.horizontalPosition + level.width + 3;`@`@ *@<-;`@declare Object`kbd`@*= _neo_ sashelp.classes.textentry_c`@B( { _region_ = {ulx=1,uly=10,lrx=1,lry=30,units='pixels'}`@(, _attrs_= { textColor='cx505050'`@#, backgroundColor='cx505050'`@, enabled='Yes'`@, keyFeedback='Yes'`@, borderStyle='Simple'`@!, borderColor='cx303030' }`@!, _instance_attributes_= {`@Bpiece = { TYPE='O', DESCRIPTION='Piece tha&>('t is falling' } }`@ } );`@`@Fkbd._setInstanceMethod ('_onKey', cat||'Playmethods', 'onkey');`@Ekbd.horizontalPosition = floor ( ( (w-4) - kbd.width) / 2 );`@`@ *@<-;`@0declare sashelp.classes.textlabel_c start`@*= _neo_ sashelp.classes.textlabel_c`@B( { _region_ = {ulx=1,uly=10,lrx=131,lry=35,units='pixels'}`@', _attrs_= { labelColor='Orange'`@!, label='Press S to Start'`@, justification='Center'`@<, font={NAME='Comic Sans MS', POINTS=110, WEIGHT=9 }}`@ } );`@`@Mstart.horizontalPosition = floor ( ( (w-4) - start.width) * 1 / 2 );`@`@ *@<-;`@/declare sashelp.classes.textlabel_c keys`@*= _neo_ sashelp.classes.textlabel_c`@B( { _region_ = {ulx=1,uly=30,lrx=131,lry=55,units='pixels'}`@%, _attrs_= { labelColor='Gray'`@, label='4,5,6,2,D'`@, justification='Center'`@<, font={NAME='Comic Sans MS', POINTS=110, WEIGHT=9 }}`@ } );`@`@Kkeys.horizontalPosition = floor ( ( (w-4) - keys.width) * 1 / 2 );`@`@ *@<-;`@declare Field field`@N= _neo_ Field ({_region_={ulx=1,uly=1,lrx=10,lry=10,units='pixels'}});`@`@ *@<-;`@gridw = w;`@gridh = h`@.- score.verticalPosition - score.height`@- kbd.height - 2`@- keys.height - 2`@;`@`@Cdimw = floor ( (gridw - 1) / (field.getNumberOfColumns()) );`@Cdimh = floor ( (gridh - 1) / (field.getNumberOfRows()+2));`@`@#if dimw > 30 then dimw = 30;`@#if dimh > 30 then dimh = 30;`@`@dim = min (dimh, dimw);`@dim = floor (dim/3) * 3;`@`@=declare num fw = dim * field.getNumberOfColumns() + 1;`@:declare num fh = dim * field.getNumberOfRows() + 1;`@`@9declare num fx = floor ( ( (w-4) - fw ) * 1 / 2 );`@9declare num fy = floor ( ( (h-4) - fh ) * 1 / 2 );`@`@ *@<-;`@%field.horizontalPosition = fx;`@$field.verticalPosition= fy;`@field.width= fw;`@field.height = fh;`@`@ *@<-;`@_y = fy + fh + 6;`@`@"kbd.verticalPosition = _y ;`@6start.verticalPosition = _y + start.height + 4;`@4keys.verticalPosition = _y + keys.height + 4;`@keys.visible = 'No';`@`@ *@<-;`@3declare sashelp.classes.textlabel_c gameover`@*= _neo_ sashelp.classes.textlabel_c`@B( { _region_ = {ulx=1,uly=10,lrx=150,lry=90,units='pixels'}`@%, _attrs_= { labelColor='Blue'`@ , backgroundColor='White'`@, borderColor='Cx808080'`@, borderStyle='Simple'`@, borderWidth=2`@, label='GAME OVER'`@, justification='Center'`@, visible='No'`@)> ( <, font={NAME='Comic Sans MS', POINTS=200, WEIGHT=9 }}`@ } );`@`@Sgameover.horizontalPosition = floor ( ( (w-4) - gameover.width) * 1 / 2 );`@Rgameover.verticalPosition= floor ( ( (h-4) - gameover.height ) * 1 / 2 );`@`@kbd._cursor();`@kbd.piece = 0;`@`@'* check if sounds can be played;`@)call symput ('canplaysound', '0');`@8if symget ('SYSSCP') eq 'WIN' then link SASCBTBL;`@`@T declare Scores scores = _neo_ Scores ({_region_={ulx=8,uly=4,lrx=9,lry=5}});`@3scores.slistEntry = 'sasuser.scores.tetris';`@ return;`@`@`@SASCBTBL:`@declare char line;`@'declare num fid rc routinefound;`@`@routinefound = 0;`@!rc = fileref ('SASCBTBL');`@`@if rc = 0 then do;`@ fid = fopen ('SASCBTBL');`@if (fid) then do;`@7do while (fread(fid) eq 0 and not routinefound);`@rc = fget(fid,line,200);`@;routinefound = index (line, '* PlaySoundA for AF;');`@ end;`@fid = fclose (fid);`@ end;`@ end;`@else do;`@Mrc = filename ('SASCBTBL', 'WORK.WINAPI.ROUTINES.SOURCE', 'CATALOG');`@ end;`@`@#if not routinefound then do;`@%fid = fopen ('SASCBTBL', 'A');`@if fid then do;`@declare list routine =`@ { ' '`@, '* PlaySoundA for AF;'`@, 'routine PlaySoundA'`@, 'module = winmm'`@, 'minarg = 3'`@, 'maxarg = 3'`@, 'stackpop = called'`@, 'returns= long'`@ , ';'`@H, 'arg 1 char inputbyaddrformat=$CHAR32767.; *lpszSoundName;'`@G, 'arg 2 numinputbyvalue format=pib4.;*hModule, always 0;'`@<, 'arg 3 numinputbyvalue format=pib4.;*uFlags;'`@ };`@%do i = 1 to listlen (routine);`@,rc = fput (fid, getitemc(routine,i));`@rc = fwrite (fid);`@ end;`@rc = fclose (fid);`@rc = dellist (routine);`@)call symput ('canplaysound', '1');`@ end;`@ end;`@ else`@)call symput ('canplaysound', '1');`@ return;`@`@rc = rc;`@`@( (>*)0#!#_SCLD1_LIIP1RELEASEEXESIZEFLAGS-@<X 9$@?@P@@@P !   & , 2 ; @ F MUY] a hmquy}   ^d^)*^ )*^)*^)*^)*^)*^#$&*m*++d^)-&*O.,m*/%/.,^)-&0m0112m0334 24556 ,677^/-4^7$4^7%4^<&4^"A^)-&0O8,m03%38^F"KE^)-&0m033^P"KE^)-&0m03(SU7(SZ6 76554^_"K^d"K^i"K^n"Ke^s-&*l*##(v7 7665({9(x7^)t^:*:#^#K^#K^<#^-4^)-&*m*+(q;;^#~;^#~;^#~;^#~;^#~;^"K~^/-4^#<BFPUmuy"$&% ( '       376 475+7:7"9 !"#$#+;&(*,/01 234678  !!!!""#$$$$$$$$$&&''(()+++-....0000001122334477778889999::::;;;;<<<<====>AADDFHHHJJJLLMMNNOOPPRRRRRRSSTTVYY[[[[]]]]]]^^__``aacffhijj+>*p_MSG__STATUS__ERROR__CURROW_fieldpiecestartgameoverkeyslevelscores_frame_$T0$T1$T2_self_$A#1$T3$T4$T5$T6$T7$T8$T9$T10$T11$A#2a2g$T12$T13rcGAMES.TETRIS.FIELD.CLASSGAMES.TETRIS.PIECE.CLASSGAMES.TETRIS.SCORES.CLASS_getNumVarfieldstartkeysgameoverscoreslevel_GetAttributeValuevisibleYestextsS09_SetAttributeValueNoclearBlocks()V(CN)V1scorerowsClearedpieceBYTERANUNI_NEW__INITCONSTRUCTOR(O:GAMES.TETRIS.FIELD.CLASS;C)Vrowcol(CC)V4left5rotate6right2dropDQwait()Nlock(C)NtermBlocks_termSASHELP.FSP.OBJECT.CLASSaddScore(N)N_popRegion  hp onKeywait`6HALFHALF 7 10 13 16 19 22`/onKey:`q@vmethod;`p@v`w@vdeclare Field field;`a@v`w@vdeclare Piece piece;`a@vdeclare Object start gameover keys level;`L@vdeclare Scores scores;`_@v`w@v_frame_._getNumVar ('field', field);`Q@v_frame_._getNumVar ('start', start);`Q@v_frame_._getNumVar ('keys', keys);`S@v_frame_._getNumVar ('gameover', gameover);`K@v_frame_._getNumVar ('scores', scores);`O@v`_frame_._getNumVar ('level', level);`Q@v`w@vif start.visible = 'Yes' then do;`T@v`w@v if _self_.text not in ('s', 'S') and not ('0'<=_self_.text<='9') then do;`*@v_self_.text = '';``@vreturn;`j@vend;`o@v`w@vstart.visible = 'No';`^@vgameover.visible = 'No';`[@vkeys.visible = 'Yes';`^@v`w@vfield.clearBlocks();`_@v`w@vHif _self_.text in ('s', 'S') then`R@vfield.level = 0;`a@velse`o@vif _self_.text = '0' then`Z@vfield.level = 10;``@velse`o@vfield.level = rank(_self_.text) - rank('1') + 1;`A@v`w@vfield.score = 0;`c@vfield.gameover = 0;``@vfield.rowsCleared = 0;`]@vend;`q@v`w@vpiece = _self_.piece;``@v`w@v~if piece = 0 then do;``@va2g = byte(41x+ranuni(0)*7);`W@v`w@vpiece = _new_ Piece(field,a2g);`T@vpiece.row = 1;`e@vpiece.col = 5;`e@vpiece.visible='Yes';`_@v_self_.piece = piece;`^@vend;`q@v`w@vselect (upcase(_self_.text));`X@vwhen ('4') piece.left();`[@vwhen ('5') piece.rotate();`Y@vwhen ('6') piece.right();`Z@vwhen ('2') piece.drop();`[@vwhen ('D') piece.drop();`[@vwhen ('Q') field.gameover = 1;`U@votherwise ;`h@vend;`q@v`w@v_self_.text = '';`d@v`w@vwait:`r@vrc = piece.wait();`c@v`w@vif rc then do;`g@v`w@vif rc > 0 then piece.lock();`W@v`w@vif field.gameover then do;`Y@v7`w@vstart.visible = 'Yes';`[@vkeys.visible = 'No';`]@vpiece.termBlocks();`^@vpiece._term();`c@v_self_.piece = 0;``@v`w@vif not scores.addScore(field.score) then do;`E@vgameover.visible = 'Yes';`V@vgameover._popRegion();`Y@vend;`m@vreturn;`j@vend;`o@v`w@vpiece._term();`e@v`w@va2g = byte(41x+ranuni(0)*7);`W@v`w@vpiece = _new_ Piece(field,a2g);`T@vpiece.row = 1;`e@vpiece.col = 5;`e@vpiece.visible='Yes';`_@v_self_.piece = piece;`^@v`w@vgoto wait;`i@vend;`q@v`w@vendmethod;`m@v`w@v_self_ = _self_;`g@v &_frame_ = _frame_;`e@vrc = rc;`o@v*>,+0#!#_SCLD1_LII/P1RELEASEEXESIZEFLAGS-/@$|+ '"|+B,4(/p ,I?@@@@@@ @"@$@&@P !   ' / 8 AIMQUY]aei m o r x~  x r m o  m o r ^ ^ "^"(^"&^+"(^."&^5"(^8"&^?"(^B"&^I"(^L"&^S"(^V"&^]"(^`"&^g"(^j"&^q"(^t"&^{"(^~"&^"(^"&^"(^"&^"(^"&^"(^"&^"(^"&^"(^"&^"(^"&^"(^"&^"(^"&^"(^"&d^"'')^"*"+(-*-. ).//^"4(q 3^"6^"/(42^".^!"((^-(07m75(Y31(Y<55/33(Y<55^"6(nE1^ "^"//00~*0^"/^N"((^U(\^"/^N"((^_"(8^f807^"/^N"((^i(\^_"((^p(07^"/^N"(8^s8\^z"8^}87^9\^y97edn^">(C=^">(.//B^">(g=7<; (?=8<7<^">(4;^"(886(V?^"(8^8\^"(88.(W.^"(8^8\8<ed7A^"D(4 /(W.@."8AA ^z"8^8F^"E\^'"^",A^1"6;C(ZBB^"G(?KB^T"(8^[8\^T"(8^a8F^T"(8^b8\^T"(8^i8\^"G(4p/(,wB^"G(8pB7A^"H(4|C(VI^T"(8^8\(W.^"(8^8\8A ep3458-,( (  ( (((( (!("(#($( %( '(),+-*+45,-6/. /../ 250- 315 536/ ./6 /  -0777/887/9;9:<=>:  4:>/>/>@/ 0AB ;/B. >;/></ /<;0?/?</<;B./.<@ DA//B. ;E< =E'A F02B C@B/ GCA/ /A6=A7GA8HAG //.HA/C0I/IA/ACB./.A  %%'''''''''''+++-----........001334446688899;;;;;;<<<<<<<<<<<<<<==========@@@@AABBCCHHLLLNNNNOOOPQRRSSSTWXXXZZZZZZZZ[[[[[[[[\]]aaffffffgiillllmmoopprttvwxxxzzzz{{{{||||}}}}qN_MSG__STATUS__ERROR__CURROW__SELF__FRAME__CFRAME__METHOD__EVENT_$T0$T1$T2$T3$T4$T5$T6$T7$T8ircscoreslist$T9$T10$T11$T12$T13kbd$T14$T15newscore$T16$T17$T18$T19$T20GAMES.TETRIS.SCORES.CLASASHELP.FSP.COMPOSIT.CLASSON()V_newSASHELP.FSP.OBJECT.CLASSvisibleNo_SetAttributeValueSASHELP.FSP.WIDGET.CLASS(CC)VONAME_GetAttributeValuename1(C)O(CON)Vname2name3name4name5name6name7name8name9name10OSCOREscore1score2score3score4score5score6score7score8score9score10saveScoresnewix(C)NonameslistEntry(C)Cscores(C)L(CNN)O(10)textname..SLISTSLISTCATALOGeditablebackgroundColortextColorframeId_getNumVarkbdenabledYes_cursorsetcamSlistEntryDTop Gunscore(N)NaddScore_POPREGION(CN)VWhiteBlue   *hxV(C@_new saveScoressetcamSlistEntryaddScore@ xxxxxxxxxxxx,> -`B6HALFHALF 7 10 13 16 19 22`/useclass scores;`g@v`w@v_new:`n@vpublic method / (state='O', signature='N');`H@v`w@v_super();`h@v`w@vvisible = 'No';`b@v`w@voname[1] = name1;``@voname[2] = name2;``@voname[3] = name3;``@voname[4] = name4;``@voname[5] = name5;``@vhoname[6] = name6;``@voname[7] = name7;``@voname[8] = name8;``@voname[9] = name9;``@voname[10]= name10;`_@v`w@voscore[1] = score1;`^@voscore[2] = score2;`^@voscore[3] = score3;`^@voscore[4] = score4;`^@voscore[5] = score5;`^@voscore[6] = score6;`^@voscore[7] = score7;`^@voscore[8] = score8;`^@voscore[9] = score9;`^@voscore[10]= score10;`]@v`w@vendmethod;`i@v`w@v`w@v`w@vsaveScores:`h@vpublic method;`e@v`w@vif newix < 1 or newix > dim (_self_.oname) then return;`:@v`w@vdeclare num i rc;``@vdeclare list score;`^@vdeclare char slist = upcase(slistEntry);`I@v`w@vscore = getitemL (scores, newix);`P@vrc = setNitemC (score,oname[newix].text,'name');`A@v`w@vif scan (slist,4,'.') = '' then`R@vslist = slist || '.SLIST';`U@v`w@vif scan (slist,4,'.') = 'SLIST' then`M@vrc = savelist ('CATALOG', slist, scores);`F@v`w@vvisible = 'No';`b@v`w@vi = newix + 1;`c@vif i > 10 then i = 1;`\@v`w@voname[newix].editable = 'No';`T@voname[newix].backgroundColor = oname[i].backgroundColor;`9@voname[newix].textColor = oname[i].textColor;`E@v`w@vdeclare Object kbd;`^@vframeId._getNumVar ('kbd', kbd);`Q@vkbd.enabled = 'Yes';`]@vkbd._cursor();`c@vendmethod;`i@v`w@v`w@v`w@vsetcamSlistEntry:`b@vprotected method slist:update:Char return=num;`E@vdeclare list score;`^@vdeclare num i rc;``@vn`w@vrc = fillist ('SLIST', slist, scores);`K@v`w@vif listlen (scores) ne 10 then do;`O@vrc = clearlist (scores,'D');`S@vdo i = 1 to 10;``@vscore = {name='Top Gun', score=0};`K@vrc = setNitemN (score,i*10,'score');`I@vrc = insertL (scores, score, 1);`M@vend;`k@vend;`m@v`w@vdo i = 1 to 10 ;`a@vscore = getItemL (scores,i);`S@v`w@vif oname[i]then oname[i].text = getNItemC (score,'name');`4@vif oscore[i] then oscore[i].text = getNItemN (score,'score');`2@vend;`m@vendmethod;`i@v`w@v`w@vaddScore:`j@vpublic method newscore:input:num return=num;`G@vdeclare num i rc;``@vdeclare list score;`^@v`w@vdo i = 1 to 10`c@vwhile (newscore <= getNItemN (getItemL(scores,i),'score'));`4@vend;`m@v`w@v:if i = 11 then return 0;`Y@v`w@vdeclare Object kbd;`^@vframeId._getNumVar ('kbd', kbd);`Q@vkbd.enabled = 'No';`^@v`w@vvisible = 'Yes';`a@v_popRegion();`d@v`w@vif i <= 10 then do;`^@v`w@vnewix = i;`e@v`w@vscore = {name='', score=0};`T@vrc = setNitemN (score,newscore,'score');`G@vrc = insertL (scores,score,i);`Q@v`w@voname[i].editable = 'Yes';`U@voname[i]._cursor();`\@voname[i].backgroundColor = 'White';`L@voname[i].textColor = 'Blue';`S@v`w@vrc = dellist (getItemL(scores,11));`L@vrc = delitem (scores,11);`V@vend;`m@v`w@vdo i = 1 to 10 ;`a@vscore = getItemL (scores,i);`S@v/>/.0##_SCLD1_LIIP1RELEASEEXESIZEFLAGS<6HALFHALF 7 10 13 16 19 22`/`w@v1/* Class File: GAMES.TETRIS.SCORES.CLASS */`L@v2/* SCL File: Games.Tetris.Scoresclass.SCL */`K@v%/* Date:17AUG2004:14:08:21 */`X@v`w@v`w@v%Class GAMES.TETRIS.SCORES.CLASS`X@v#Extends SASHELP.FSP.COMPOSIT`U@v/ (Type="COMPOSIT" ,`]@vModule="SASOCMX");`Z@v`w@v`w@v/*@-*/`V@v/* Attributes:*/`V@v/*@-*/`V@v`w@vPublicChar description`\@v/ (State="O",`d@v0InitialValue="GAMES.TETRIS.SCORES.CLASS")`E@v;`p@v`w@v!PublicChar resourceEntry`Z@v/ (State="O",`d@v8InitialValue="SASHELP.FSP.afcomponents.resource")`=@v;`p@v`w@v#PublicChar backgroundColor`X@v/ (State="O",`d@vInitialValue="CX3")`V@v;`p@v`w@vPublicChar borderColor`\@v/ (State="O",`d@vInitialValue="Gray")`Z@v;`p@v`w@v#PublicList borderTitleFont`X@v/ (State="O",`d@vAutoCreate="N")`_@v;`p@v`w@v*PublicChar borderTitleFontScaling`Q@v/ (State="O",`d@vInitialValue="No")`\@v;`p@v`w@vPublicChar borderStyle`\@v/ (State="O",`d@vInitialValue="Simple")`X@v;`p@v`w@vPublicNum borderWidth`]@v/ (State="O",`d@vInitialValue=3)`_@v;`p@v`w@v`w@v`w@v%macro obj_name (n);``@v ProtectedObject name&N.`W@v/ (State="S",``@vIV="name&N.",`]@vEditable="N",`]@vLinkable="N",`]@vSendEvent="N",`\@vCategory="System",`X@vAutomatic="Y")`\@v;`l@v %mend;`n@v`w@v%obj_name (1)`g@v%obj_name (2)`g@v%obj_name (3)`g@v%obj_name (4)`g@v%obj_name (5)`g@v%obj_name (6)`g@v%obj_name (7)`g@v%obj_name (8)`g@v%obj_name (9)`g@v%obj_name (10)`f@v`w@v`w@v`w@v%macro obj_score (n);`_@v!ProtectedObject score&N.`V@v/ (State="S",``@vIV="score&N.",`\@vEditable="N",`]@vLinkable="N",`]@vSendEvent="N",`\@vCategory="System",`X@vAutomatic="Y")`\@v;`l@v %mend;`n@v`w@v%obj_score (1)`f@v%obj_score (2)`f@v%obj_score (3)`f@v%obj_score (4)`f@v%obj_score (5)`f@v%obj_score (6)`f@v%obj_score (7)`f@v%obj_score .>0/(8)`f@v%obj_score (9)`f@v%obj_score (10)`e@v`w@v`w@v`w@vProtectedObject ok``@v/ (State="S",`d@vIV="ok",`f@vEditable="N",`a@vLinkable="N",`a@vSendEvent="N",``@vCategory="System",`\@vAutomatic="Y")``@v;`p@v`w@v#ProtectedObject Textentry1`X@v/ (State="S",`d@vIV="Textentry1",`^@vEditable="N",`a@vLinkable="N",`a@vSendEvent="N",``@vCategory="System",`\@vAutomatic="Y",``@v<Description="Returns the id of the component object")`9@v;`p@v`w@v"ProtectedObject oname(10)`Y@v;`p@v`w@v#ProtectedObject oscore(10)`X@v;`p@v`w@vProtectedList scores`^@v:/ (Editor="sashelp.classes.simplelisteditor.frame",`>@v!SetCAM="setcamSlistEntry",`T@vCategory="Data")`^@v;`p@v`w@vPublicChar slistEntry`]@v/ (InitialValue="",`^@v!SetCAM="setcamSlistEntry",`T@vCategory="Data",`^@v@Description="Catalog entry where high scores are stored")`5@v;`p@v`w@vProtectedNum newix``@v/ (InitialValue=.,`_@vCategory="Data",`^@v6Description="Slot where new score was entered")`?@v;`p@v`w@v`w@vK/* The attribute ComponentDefinition is generated for Composite. */`1@v`w@v*ProtectedList componentDefinition`P@v/ (State="S",`d@vInitialValue={``@v`TEXTENTRY1={`S@v` _ATTRS_={`S@v` font={`S@v`NAME="Comic Sans MS",`A@v`OPTIONS=4104,`I@v`FAMILY=-1,`L@v `FAMNAME="Comic Sans MS",`>@v`CHARSET=1,`L@v`POINTS=143,`K@v`STYLE=1,`N@v`WEIGHT=9,`M@v`WIDTH=2,`N@v`PORTABLE=0,`K@v`RATIO=1.72289156626506,`?@v"`SYS_RATIO=1.72289156626506`<@v `}`U@v ` ,`X@v` cursorPosition=1,`H@v` borderStyle="None",`F@v` text="High Scores",`F@v` editable="No",`K@v ` backgroundColor="CX3",`>@v` labelColor="White",`F@v` justification="Center",`B@v` label="High Scores",`E@v` errorMessage=""`J@v` } / (HonorCase='Y')`F@v ` ,`[@v` NAME="",`T@v*` _CLASSNAME_="TEXTLABEL_C.AFCNTRL",`:@v` LABEL="TEXTENTRY1",`I@v` _LEN_=0,`T@v` _INSTANCE_ATTRIBUTES_={`E@v` } / (HonorCase='Y')`F@v ` ,`[@v0` _CURRENT_="SASHELP.CLASSES.TEXTENTRY_C",`4@v` _REGION_={`R@v` UNITS="SYSFONTS",`H@v` ULX=3.16,`D@v` ULY=0.76923076923076,`D@v` LRX=32.5,`P@v` LRY=3.15384615384615,`D@v` _PARENT_="XCOMPOSX"`F@v1>10 ` }`X@v ` }`[@v `,`^@v`w@v%macro def_name (N);`c@vNAME&N.={`n@v_ATTRS_={`l@v:font={ NAME="Comic Sans MS", POINTS=98, WEIGHT=9 },`?@vborderStyle="None",`_@vtext="Top Gun",`c@veditable="No",`d@vbackgroundColor="Cx3",`W@vtextColor="White"`a@v} / (HonorCase='Y')`_@v,`t@vNAME="",`m@v)_CLASSNAME_="TEXTENTRY_C.AFCNTRL",`S@vLABEL="NAME&N.",`e@v_LEN_=0,`m@v_INSTANCE_ATTRIBUTES_={`^@v#text={ TYPE="C", STATE="O" }`V@v} / (HonorCase='Y')`_@v,`t@v/_CURRENT_="SASHELP.CLASSES.TEXTENTRY_C",`M@v_INSTANCE_METHODS_={`a@v_onReturnKey={`d@vSTATE="O",`e@vCOMPONENT="ownerID",`[@v COMP_METHOD="saveScores",`V@vSIGSTRING="()V"``@v}`n@v} / (HonorCase='Y')`_@v,`t@v_REGION_={`k@vUNITS="SYSFONTS",`a@vULX=1.6,`]@v/ULY=%sysevalf(2 + &N. * 2.307692307692),`J@vLRX=19.3,`]@vALRY=%sysevalf(2 + &N. * 2.307692307692+ 1.615384615385),`8@v_PARENT_="XCOMPOSX"`_@v}`q@v}`t@v`w@v %mend;`q@v`%def_name (1) ,`P@v`%def_name (2) ,`P@v`%def_name (3) ,`P@v`%def_name (4) ,`P@v`%def_name (5) ,`P@v`%def_name (6) ,`P@v`%def_name (7) ,`P@v`%def_name (8) ,`P@v`%def_name (9) ,`P@v`%def_name (10) ,`O@v`w@v%macro def_score (N);`b@vSCORE&N.={`m@v_ATTRS_={`l@v:font={ NAME="Comic Sans MS", POINTS=98, WEIGHT=9 },`?@vborderStyle="None",`_@veditable="No",`d@vjustification="Right",`\@vformat="comma9.",`a@vinformat="",`f@vdataType="Numeric",`_@vbackgroundColor="Cx3",`W@vtextColor="White"`a@v} / (HonorCase='Y')`_@v,`t@vNAME="",`m@v)_CLASSNAME_="TEXTENTRY_C.AFCNTRL",`S@vLABEL="SCORE&N.",`d@v_LEN_=0,`m@v_INSTANCE_ATTRIBUTES_={`^@v#text={ TYPE="N", STATE="O" }`V@v} / (HonorCase='Y')`_@v,`t@v._CURRENT_="SASHELP.CLASSES.TEXTENTRY_C"`N@v,`t@v_REGION_={`k@vUNITS="SYSFONTS",`a@vULX=22.3,`]@v/ULY=%sysevalf(2 + &N. * 2.307692307692),`J@vLRX=34,`k@vALRY=%sysevalf(2 + &N. * 2.307692307692+ 1.615384615385),`8@v_PARENT_="XCOMPOSX"`_@v}`q@v}`t@v`w@v %mend;`q@v`%def_score (1) ,`O@v`%def_score (2) ,`O@v`%def_score (3) ,`O@v`%def_score (4) ,`O@v`%def_score (5) ,`O@v`%def_score (6) ,`O@v`%def_score (7) ,`O@v`%def_score (8) ,`O@v`%def_score (9) ,`O@v0>1`%def_score (10) ,`N@v`w@v `OK={`[@v` _ATTRS_={`S@v` label="OK"`O@v` } / (HonorCase='Y')`F@v ` ,`[@v` NAME="",`T@v+` _CLASSNAME_="PUSHBUTTON_C.AFCNTRL",`9@v` _INSTANCE_METHODS_={`H@v` _onClick={`O@v`STATE="O",`L@v`COMPONENT="ownerId",`B@v!`COMP_METHOD="saveScores",`=@v`SIGSTRING="()V"`G@v `}`U@v`w@v` } / (HonorCase='Y')`F@v ` ,`[@v` LABEL="OK",`Q@v` _LEN_=0,`T@v` _REGION_={`R@v` UNITS="SYSFONTS",`H@v` ULX=3.16,`D@v` ULY=27.6923076923077,`D@v` LRX=32.5,`P@v` LRY=30.2307692307692,`D@v` _PARENT_="XCOMPOSX"`F@v ` }`X@v ` }`[@v `}`^@v `)`a@v;`p@v`w@v`w@vN/* The following Attributes are generated for the v6 compatibility. */`.@vO/* They are actually V6 instance variables rather than V7 attributes.*/`-@vL/* You may delete these attributes after you apply the SCOM model.*/`0@v`w@vPrivateList USERATTR`^@v/ (IV="USERATTR",``@vPureIV="Y")`c@v;`p@v`w@vPrivateList CHILDREN`^@v/ (IV="CHILDREN",``@vPureIV="Y")`c@v;`p@v`w@vPrivateList _REGION_`^@v/ (IV="_REGION_",``@vPureIV="Y",`c@vInitialValue={``@v`UNITS="SYSFONTS",`M@v`ULX=33,`W@v`ULY=0,`X@v`LRX=68.3,`I@v`LRY=30.9230769230769,`I@v`_PARENT_="",`R@v`XSIZE=35.3,`G@v`YSIZE=30.9230769230769`H@v `}`]@v `)``@v;`p@v`w@v`w@v/*@-*/`V@v/* Methods:*/`V@v/*@-*/`V@v`w@v_new: Public Method`a@v(/ (SCL="GAMES.TETRIS.SCORES.SCL",`R@vState="O",`e@vSIGNATURE="N")`a@v;`p@v`w@v saveScores: Public Method`[@v(/ (SCL="GAMES.TETRIS.SCORES.SCL")`R@v;`p@v`w@v)setcamSlistEntry: Protected Method`R@v!attributeValue:Update:Char`X@vReturn=Num`h@v(/ (SCL="games.tetris.scores.scl",`R@vFDescription="Invoked when the slistEntry attribute is changed",`0@v/ArgDesc1="contains the attribute value",`G@v@ReturnDesc="returns a value indicating whether the setcam completed successfully: 0 if successful, >0 if error, <0 if warning") @v;`p@v`w@vaddScore: Public Method`]@vnewscore:Input:Num``@vReturn=Num`h@v(/ (SCL="games.tetris.scores.scl",`R@vFReturnDesc="1 if score was added to high scores, 0 if too low")`0@v;`p@v`w@vEndClass;`l@v`w@v/* End of Class */`e@v3>32 /* Richard A. DeVenezia`؀@* Aug 11 2004`@*`@* Create blocks for Tetris game`π@* Blocks are saved as gif files, and`ʀ@* turned into IMAGE catalog entries by a`ƀ@* separate AF application`Հ@n*/`@`@`@ %*@,-`@ %* GIF files will be created in work folder`Ā@ %*;`@`@ %let outpath = %sysfunc (pathname(work));`ƀ@`@ %* predelete any gif files that may exist from an earlier run;`@`@ options noxwait xmin xsync mprint;`̀@ x del "&outpath.\*.gif";`׀@`@F filename outpath "&outpath";`Ӏ@`@ %*@,-`@ %* Set GSFNAME to fileref OUTPATH fileref.Since the fileref is`@ %* to a folder, graphics output will be to a file in the folder,`@ %* then filename will correspond to the name specified as the`@ %* for catalog entry [ via GSET('NAME',) ]`ŀ@ %*;`@`@ goptions reset=all gsfname=outpath goutmode=replace;`@`@ %*@,-`@ %* DATA Step code macros;`ր@`@ %macro lighten (r,g,b, factor, outvar);`Ȁ@%* lighten a color toward white, factor in 0..1;`@_f = &factor;`ހ@if _f<0 then _f=0; else`Ԁ@if _f>1 then _f=1;`ـ@_r = &r + (255-&r) * _f;`Ӏ@_g = &g + (255-&g) * _f;`Ӏ@_b = &b + (255-&b) * _f;`Ӏ@&outvar = 'CX' || put (_r,hex2.) || put (_g,hex2.) || put (_b,hex2.);`@ %mend;`@`@ %macro darken (r,g,b, factor, outvar);`ɀ@%* darken a color toward black, factor in -1..0;`@_f = 1-&factor;`܀@if _f<0 then _f=0; else`Ԁ@if _f>1 then _f=1;`ـ@_r = &r * _f;`ހ@_g = &g * _f;`ހ@_b = &b * _f;`ހ@&outvar = 'CX' || put (_r,hex2.) || put (_g,hex2.) || put (_b,hex2.);`@ %mend;`@ `@ %macro shadeOf (r,g,b, factor, outvar);`Ȁ@%* darken or lighten a color based on factor;`@if &factor < 0`߀@then do; %darken(&r,&g,&b,-&factor,&outvar) end;`@else do; %lighten (&r,&g,&b, &factor,&outvar) end;`@ %mend;`@`@`@ %macro block (name, color);`Ԁ@`@%* name- block name`؀@%* color - a literal string containing a SAS color value`@%*having form CXrrggbb.`̀@%*The color is the base color of the block.`@%*Gradient and borders are computed from the base color.`@%*;`@`@%* Note: Active DSGI transform has 1,1 as lower left`@%*and dim,dim as upper right;`ɀ@`@rc = graph ('CLEAR', "&name.");`΀@`@%* 1st color in palette is the base color;`À@rc = gset ('COLREP', 1, "&color");`ˀ@`@%* 2nd color in the palette is black;`Ȁ@rc = gset ('COLREP', 2, 'cx0');`ɀ@`@r = input (substr("&color",3,2),hex2.);`ƀ@g = input (substr("&color",5,2),hex2.);`ƀ@b = input (substr("&color",7,2),hex2.);`ƀ@`@fDD = .4; %* shade factor dark band dark part;`@fDL = .2; %* dark band bright part;`ʀ@`@fLL = .4; %* shade factor bright band bright part;`@fLD = .2; %* bright band dark part;`ʀ@`@* exaggerated factors for sugi 30 paper ;`Ā@ * fDD = .7;`@ * fDL = .5;`@ * fLL = .7;`@ * fLD = .5;`@`@%* 3rd color in palette is used for`ʀ@%2>43* Lower right corner outer band dark shading border ;`@%darken (r,g,b, fDD, acolor);`Ѐ@rc = gset ('COLREP', 3, acolor);`̀@`@%* 4th color in palette is used for`ʀ@%* Lower right border inner band dark shading border;`@%darken (r,g,b, fDL, acolor);`Ѐ@rc = gset ('COLREP', 4, acolor);`̀@`@%* 5th color in palette is used for`ʀ@!%* Upper left corner outer band brightening border;`@%lighten (r,g,b, fLL, acolor);`π@rc = gset ('COLREP', 5, acolor);`̀@`@%* 6th color in palette is use for`ˀ@%* Upper left corner inner band brightening border;`@%lighten (r,g,b, fLD, acolor);`π@rc = gset ('COLREP', 6, acolor);`̀@`@%* Draw the border effects using filled triangles.`@%* The interior of the boxes will get overwritten by the gradient;`@`@rc=gset('FILTYPE', 'solid');`р@`@ %* FILL is used to create border shading because it was the`@%* simplest when blocks having band thickness other than 1`@%* were being examined;`ր@`@%* Note: FILL coordinates are x1..xn,y1..yn;`@`@rc = gset ('FILCOLOR', 2);`Ӏ@rc = gdraw ('BAR', 1+0*t,1+0*t, dim-0*t,dim-0*t );`@`@rc = gset ('FILCOLOR', 3);`Ӏ@rc = gdraw ('BAR', 1+0*t,1+1*t, dim-1*t,dim-0*t );`@`@rc = gset ('FILCOLOR', 4);`Ӏ@rc = gdraw ('BAR', 1+0*t,1+2*t, dim-2*t,dim-0*t );`@`@rc = gset ('FILCOLOR', 5);`Ӏ@rc = gdraw ('FILL', 3, 1+0*t,1+0*t,dim-1*t, 1+1*t,dim-0*t,dim-0*t );`@`@rc = gset ('FILCOLOR', 6);`Ӏ@rc = gdraw ('FILL', 3, 1+1*t,1+1*t,dim-2*t, 1+2*t,dim-1*t,dim-1*t );`@`@%* Spurious, but shows what non-gradient block looks like;`@%* Note: BAR coordinates are x1,y1, x2,y2;`À@`@rc = gset ('FILCOLOR', 1);`Ӏ@rc = gdraw ('BAR', 1+2*t,1+3*t, dim-3*t,dim-2*t);`@`@%* Fill the remaining block interior with a gradient.`@%* 45 degree lines will be drawn across the face,`@%* from upper left to lower right.`ˀ@%* The color of the lines will vary from a lighter shade of`@%* base color to a darker shade of base color`@%*;`@`@%* The block is DIM pixels across.`ˀ@%* The shading is 5 lines of t thickness, leaving a 'face'`@%* of size DIM - 5*t pixels that needs to be filled.`@%*;`@`@dim_face = dim - 5 * t;`ր@`@%* The number of one pixel 45 degree lines that can be drawn`@%* from the left edge and bottom edge is 2 * dim_face - 1`@%*;`@`@nLines = 2 * dim_face - 1;`Ӏ@`@%* The colors of the lines will vary from lighter shade to`@%* darker shade.f1 and f2 are the shading factors for the`@%* upper left and lower right corners respectively.`@%*;`@`@%* Note: f1 is less than both brightening band factors;`@%*f2 is between the dark shading band factors;`@`@f1 =fLD - .1;`ހ@ f2 = -fDL - .1;`ހ@`@%* k will track the number of lines that have been previously drawn.`@%* The fraction k / (nLines-1) is the linear interpolation factor`@%* for determining the next lines color shading factor.`@%*;`@`@k = 0;`@`@%* The color of each line has to be added to the palette.`@ %*5>54 cindex is used to track the next available color index in the palette.`@%*;`@`@cindex = 7;`@`@%* Draw the 45 degree lines from the left edge, starting at`@%* the upper left.`ۀ@%*;`@`@do i = 1 to dim_face;`؀@`@%* Use linear interpolation to determine shade factor of line color;`@`@f = f1 + ( f2 - f1 ) * k / (nLines-1);`ŀ@`@%* Create color corresponding to shade factor;`@`@%shadeOf (r,g,b, f, acolor)`Ѐ@`@%* Store the color in the palette;`ɀ@`@rc = gset ('COLREP', cindex, acolor);`ƀ@rc = gset ('LINCOLOR', cindex);`̀@`@%* Update palette index and lines drawn counter;`@i`@cindex + 1;`@k+1;`@`@%* Draw the line;`ڀ@`@x1 = 1 + 2 * t ;`ۀ@x2 = 1 + 2 * t + i -1 ;`Ԁ@`@y1 = dim - 2 * t - i + 1 ;`р@y2 = dim - 2 * t ;`ـ@`@rc = gdraw ('LINE', 2, x1,x2, y1,y2);`ƀ@end;`@`@%* Draw the 45 degree lines from the bottom edge, starting at`@%* the lower left inset 1.`Ӏ@%*;`@`@do i = 2 to dim_face;`؀@`@%* Use linear interpolation to determine shade factor of line color;`@`@f = f1 + ( f2 - f1 ) * k / (nLines-1);`ŀ@`@%* Create color corresponding to shade factor;`@`@%shadeOf (r,g,b, f, acolor)`Ѐ@`@%* Store the color in the palette;`ɀ@`@rc = gset ('COLREP', cindex, acolor);`ƀ@rc = gset ('LINCOLOR', cindex);`̀@`@%* Update palette index and lines drawn counter;`@p`@cindex + 1;`@k+1;`@`@%* Draw the line;`ڀ@`@x1 = 1 + 2 * t + i - 1;`Ԁ@x2 = dim - 3 * t ;`ـ@`@y1 = 1 + 3 * t ;`ۀ@y2 = dim - 2 * t - i + 1;`Ҁ@`@rc = gdraw ('LINE', 2, x1,x2, y1,y2);`ƀ@end;`@u /**/`@rc = graph ('UPDATE');`׀@ %mend;`@`@ %*@,-`@ %* Create blocks`߀@ %*;`@ `@ %let dim = 30;%* pixel width of block;`ƀ@ %lett =1;%* pixel width (thickness) of a band in the shading border;`@`@ goptions device=gif xpixels=&dim ypixels=&dim;`@`@ %* ODS listing must be open for gsfname to work;`@c`@ ods listing;`@`@ data _null_;`@dim = &dim;`@t = &t;`@`@rc = gset ('CATALOG', 'WORK', 'TETRIS');`ŀ@rc = ginit ();`߀@rc = gset ('WINDOW',1, 1,1, dim,dim);`Ȁ@rc = gset ('TRANSNO', 1);`Ԁ@`@%block ( A , cxCC3 )`ր@%block ( B , cxFF9933 )`ր@%block ( C , cx900 )`ր@%block ( D , cxCC00CC )`ր@%block ( E , cx3BB )`ր@%block ( F , cx008800 )`ր@%block ( G , cx009 )`ր@rc = gterm ();`߀@ run;`@f`@ %* The play field is 10 blocks wide and 20 blocks high.`@ %* When blocks are positioned over the field, the top`@ %* and left edges of the block are inset one pixel from the`@ %* grid line.It makes for a nice visual effect.`@ %* Thus the numbers of pixels (301 & 601) are one more than one might expect.`@ %*;`@`@ goptions 4>*5device=gif xpixels=301 ypixels=601;`À@`@ data _null_;`@rc = gset ('CATALOG', 'WORK', 'TETRIS');`ŀ@rc = ginit ();`߀@`@rc = graph ('CLEAR', 'GRID');`Ѐ@`@* white field with gray lines;`π@ * rc = gset ('COLREP', 1, "cxF8F8F8");`ɀ@ * rc = gset ('COLREP', 2, "cxD");`ɀ@`@* dark field with gray lines;`Ѐ@rc = gset ('COLREP', 1, "cx343434");`ɀ@rc = gset ('COLREP', 2, "cx4F4F4F");`ɀ@`@rc = gset ('WINDOW',1, 0,0, 300,600);`Ȁ@rc = gset ('TRANSNO', 1);`Ԁ@`@rc = gset ('FILCOLOR', 1);`Ӏ@rc = gset ('FILTYPE', 'solid');`΀@rc = gdraw ('BAR', 0,0, 300,600);`̀@`@rc = gset ('LINCOLOR', 2);`Ӏ@do i = 0 to 10;`ހ@rc = gdraw ('LINE', 2, i/10*300,i/10*300, 0,600);`@end;`@do i = 0 to 20;`ހ@rc = gdraw ('LINE', 2, 0,300, i/20*600,i/20*600);`@end;`@`@rc = graph ('UPDATE');`׀@ run;`@`@n goptions goutmode = append;`Ԁ@`@ proc display cat=games.tetris.loadblocks.scl;`€@ run;`@