3 Copyright
2008, 2018 Pajo
<xpio at tut dot by
>
5 This program is free software
: you can redistribute it
and/or modify
6 it under the terms of the GNU General
Public License
as published by
7 the Free Software Foundation
, either version
3 of the License
, or
8 (at your
option) any later version
.
10 This program is distributed
in the hope that it will be useful
,
11 but WITHOUT ANY WARRANTY
; without even the implied warranty of
12 MERCHANTABILITY
or FITNESS
FOR A PARTICULAR PURPOSE
. See the
13 GNU General
Public License
for more details
.
15 You should have received a copy of the GNU General
Public License
16 along
with this program
. If not, see
<https
://www
.gnu
.org
/licenses
/>.
19 Open Cons
For Output
As #
3 ' debug
25 Const VARPATH
= "variations"
28 Const SPEEDUP_TIME
= 20
29 Const SPEED_INDICATOR_SIZE
= 8
30 Const SCORE_INDICATOR_SIZE
= 16
31 Const DRAWPLAYFIELD_DELAY
= 0.02
36 Declare Sub imprint(remove As Byte = True, place As Byte = True, noshadow As Byte = True)
38 Declare Function move(as Byte,as Byte=0,As UByte
=0) As Byte
42 As Byte dropping
= False 'Used when dropping with mouse
45 Declare Function isblocked(x
as Byte, y
As Byte=0, typ
As UByte
=0, mode
As Byte=False) As Byte
51 As Byte show_shadow
= True, show_score
= False, show_speed
= False
52 As Byte play_mouse
= True, first_button_turning
= False
61 As Double tim
, speed_timer
, menu_timer
65 Dim Shared settings
As settings_type
66 Dim Shared game
As game_type
68 Dim Shared nextvariation
As String
69 ReDim Shared
help () As String
70 Dim Shared
As UByte playabletiles
, numberoftiles
71 Dim Shared
As Short columns
=1, rows
=1
72 Dim Shared
As Byte wrap
, gravity
, randominputs
, randomgoals
, inputrotate
73 Dim Shared score
As Short
=0
74 ReDim Shared
tilesfiles(0) As String
75 ReDim Shared
randomtable() As UByte
76 Dim Shared keypress
As String
77 Dim Shared tilewidth
As Short
78 Dim Shared tilesimg
As Any Ptr
79 Dim Shared scoreimg
As Any Ptr
80 Dim Shared
As block blok
, shadow
81 Dim Shared
As Double lazydrawplayfield
= -1, lastdrawplayfield
82 lastdrawplayfield
= Timer()
83 Dim Shared
As UByte maxgoalsw
= 0, maxgoalsh
= 0
86 Declare Function loadgame(filename
As String) As Byte
87 Declare Sub loadTiles(increment
As Byte=1)
88 Declare Sub initplayfield()
89 Declare Sub drop_shadow()
92 Sub resizewindow(w
As UShort
= game
.w
, h
As Short
= -1, t
As String = game
.title
)
93 Dim As Integer oldw
, oldh
: ScreenInfo oldw
, oldh
94 Dim As Integer oldx
, oldy
: ScreenControl GET_WINDOW_POS
, oldx
, oldy
97 If settings
.show_score
Then h
+= SCORE_INDICATOR_SIZE
98 If settings
.show_speed
Then h
+= SPEED_INDICATOR_SIZE
100 If oldw
= w
And oldh
= h
Then
103 ScreenRes w
, h
, 16, 2
104 If oldx
> 0 And oldy
> 0 Then ScreenControl SET_WINDOW_POS
, oldx
, oldy
110 Function asctonumber(ch
As UByte
) As UByte
111 If ch
=46 Then : Return 0
112 ElseIf ch
=33 Then : Return 254 'start=!=254
113 ElseIf ch
=Asc("@") Then : Return 253 'exit=@=253
114 ElseIf ch
>=48 And ch
<=57 Then : Return ch
-48
115 ElseIf ch
>=65 And ch
<=90 Then : Return ch
-65+10
116 ElseIf ch
>=97 And ch
<=122 Then : Return ch
-97+36
121 Function getImgWidth(filename
As String) As Short
122 Open filename
For Input
As #
2
123 If Err
>0 Then Return 0
130 ReDim Shared
inputsindex(0) As Short
131 ReDim Shared
inputs(0,2) As UByte
132 'inputs and inputsindex are linked arrays. inputsindex shows individual inputs' ends
133 ReDim Shared
goals(0,2) As UByte
136 Sub end_shape(shapes() As UByte
, index
As Byte = False)
137 shapes(UBound(shapes
), 0) = 255
138 shapes(UBound(shapes
), 1) = 255
139 shapes(UBound(shapes
), 2) = 255
141 inputsindex(UBound(inputsindex
)) = UBound(shapes
)
142 ReDim Preserve inputsindex(UBound(inputsindex
) + 1)
144 ReDim Preserve shapes(UBound(shapes
) + 1, 2)
149 Dim As Short strt
, stp
, a
, offset
150 If UBound(inputsindex
) = 1 Then strt
= 0 Else strt
= inputsindex(UBound(inputsindex
) - 1 - 1) + 1 'skip "255" point
151 stp
= inputsindex(UBound(inputsindex
) - 1) - 1 'leave out "255" point
153 ReDim Preserve inputs(UBound(inputs
) + offset
+ 1, 2)
155 'mirror one axis and swap x and y to rotate
156 inputs(a
+ offset
+ 2, 1) = inputs(a
, 0)
157 inputs(strt
+ stp
- a
+ offset
+ 2, 0) = inputs(a
, 1)
158 inputs(a
+ offset
+ 2, 2) = inputs(a
, 2)
163 Sub loadshapes(shapes() As UByte
, index
As Byte = False)
165 If index
Then ReDim inputsindex(0)
168 Do Until l
= "}" Or Eof(1)
172 end_shape(shapes(), index
)
173 If inputrotate
And index
Then
176 end_shape(shapes(), index
)
180 For a
= 0 To Len(l
) - 1
181 shapes(UBound(shapes
), 0) = a
182 shapes(UBound(shapes
), 1) = b
183 If l
[a
]=46 Then : shapes(UBound(shapes
), 2) = 0
184 Else : shapes(UBound(shapes
), 2) = asctonumber(l
[a
])
186 ReDim Preserve shapes(UBound(shapes
) + 1, 2)
190 If Len(l
) > maxgoalsw
Then maxgoalsw
= Len(l
)
191 If b
> maxgoalsh
Then maxgoalsh
= b
196 end_shape(shapes(), index
)
197 If inputrotate
And index
Then
200 end_shape(shapes(), index
)
203 If index
Then ReDim Preserve inputsindex(UBound(inputsindex
) - 1)
207 Declare Sub gameOver()
209 Dim Shared
playfield(0 to columns
-1,0 to rows
-1) as UByte
210 Dim Shared
originalplayfield(0 to columns
-1,0 to rows
-1) as UByte
212 ReDim Shared
nextshape() As UByte
214 Function block
.isblocked(x
as Byte, y
As Byte=0, typ
As UByte
=0, mode
As Byte=False) As Byte
215 Dim As Short strt
, stp
, a
218 If typ
=1 Then strt
=0 Else strt
=inputsindex(typ
-1-1)+1 'preskace se ona 255 tacka
219 stp
=inputsindex(typ
-1)-1 'izostavlja se ona 255 tacka
220 'mode=True = ispituje se origin
222 failed
=inputs(a
,2)<>0 And _
223 playfield(x
+inputs(a
,0),y
+inputs(a
,1))<>254 And _
224 playfield(x
+inputs(a
,0),y
+inputs(a
,1))<>253
225 If Not mode
Then failed
=failed
And playfield(x
+inputs(a
,0),y
+inputs(a
,1))<>0
226 failed
=failed
Or y
+inputs(a
,1)>=rows _
228 Or x
+inputs(a
,0)>=columns _
230 If failed
Then Exit For
237 this
.dropping
= False
238 If randominputs
Then 'permutovati brojeve od 1 do playabletiles
240 ReDim randomtable(playabletiles
) As UByte
241 For a
= 1 To playabletiles
242 randomtable(a
)=fix(rnd
*playabletiles
)+1
249 ReDim startpositions(0) As xy
250 Dim posnumber
As UShort
=0
252 Dim starttyp
As UByte
253 this
.typ
=Fix(RND
*(UBound(inputsindex
)+1))+1
256 For y
=0 to rows
-1 : For x
=0 to columns
-1
257 If originalplayfield(x
,y
)=254 Then
258 If Not this
.isblocked(x
,y
,this
.typ
,True) Then 'dodaj na listu
259 ReDim Preserve startpositions(posnumber
) As xy
260 startpositions(posnumber
)=Type(x
,y
)
266 this
.typ
=nextshape(this
.typ
)
267 If this
.typ
=starttyp
Then
272 Loop Until posnumber
>0
273 posnumber
=fix(rnd
*posnumber
)
274 this
.x
=startpositions(posnumber
).x
275 this
.y
=startpositions(posnumber
).y
279 If Not this
.shadow
Then drop_shadow()
283 'constructor bi se pokretao kod samog deklarisanja, pre playfielda
286 Function getshapewidthheight(typ
As UByte
,geth
As Byte = False) As Short
287 Dim As Short strt
, stp
, a
, maxwidth
=0, maxheight
=0
289 If typ
=1 Then strt
=0 Else strt
=inputsindex(typ
-1-1)+1 'preskace se ona 255 tacka
290 stp
=inputsindex(typ
-1)-1 'izostavlja se ona 255 tacka
292 If maxwidth
<inputs(a
,0) Then maxwidth
=inputs(a
,0)
293 If maxheight
<inputs(a
,1) Then maxheight
=inputs(a
,1)
295 If geth
Then Return maxheight
300 Function block
.move(x
as Byte, y
As Byte=0, typ
As UByte
=0) As Byte 'successful?True/False
306 dw
=(getshapewidthheight(this
.typ
)-getshapewidthheight(typ
)) / 2
310 dh
=(getshapewidthheight(this
.typ
,True)-getshapewidthheight(typ
,True)) / 2
316 this
.imprint(True, False) 'just erase oldx i oldy
318 this
.x
=x
+ this
.x
+ dw
319 this
.y
=y
+ this
.y
+ dh
321 this
.x
=(this
.x
+ columns
) Mod columns
322 If Not gravity
Then this
.y
=(this
.y
+ rows
) Mod rows
325 failed
=failed
Or y
+inputs(a
,1)>=rows _
327 Or x
+inputs(a
,0)>=columns _
332 failed
=this
.isblocked(this
.x
,this
.y
,typ
)
340 If not this
.shadow
Then drop_shadow()
347 Sub markshape(shapestart
As Short
,shapeend
As Short
,x
As Short
,y
As Short
)
349 For q
=shapestart
To shapeend
-1
352 If goals(q
,2)<>0 And playfield(mx
,my
)<>0 And playfield(mx
,my
)<100 Then
353 playfield(mx
,my
)+=100
359 Function matchshape(x
As Short
,y
As Short
) As Byte
360 Dim As Byte fullshape
,foundshape
=False
361 Dim As Short mx
,my
,shapestart
=0,p
=0,q
363 Dim goalscolors(100) As UByte
'za randomgoals '!max 100 randomgolova
365 For p
=0 To UBound(goals
)
366 If goals(p
,0)=255 And goals(p
,1)=255 And goals(p
,2)=255 Then '255,255,255=end
367 If fullshape
=True Then
368 print #
3, "Marking shape"
369 markshape(shapestart
,p
,x
,y
)
374 For a
=0 To UBound(goalscolors
) : goalscolors(a
)=0 : Next a
375 ElseIf goals(p
,2)<>254 Then
376 'do nothing with fullshape variable if 254(joker)
377 '254="!"=matches also empty space (useful when tiles surrounding matched shape should be destroyed)
380 If mx
<0 Or mx
>columns
-1 Or my
<0 Or my
>rows
-1 Then
382 ElseIf goals(p
,2)=255 Then '255 matches everything except empty space
383 fullshape
= fullshape
And _
384 (playfield(mx
,my
)<>0) And _
385 (playfield(mx
,my
)<>254) And _
386 (playfield(mx
,my
)<>253)
387 ElseIf goals(p
,2)<>0 Then
389 If goalscolors(goals(p
,2))=0 Then
390 If (playfield(mx
,my
)<>0) And _
391 (playfield(mx
,my
)<>254) And _
392 (playfield(mx
,my
)<>253)Then
393 goalscolors(goals(p
,2))=playfield(mx
,my
)
398 fullshape
= fullshape
And (playfield(mx
,my
)=goalscolors(goals(p
,2)) _
399 Or playfield(mx
,my
)=goalscolors(goals(p
,2))+100)
401 fullshape
= fullshape
And (playfield(mx
,my
)=goals(p
,2) _
402 Or playfield(mx
,my
)=goals(p
,2)+100)
412 Dim As Byte x
, y
, gap
, removed=False, scoremulti=0, existsnextvariation=False, gotonextvariation=True
413 For y
=0 To rows
-1 + maxgoalsh
: For x
=0 To columns
-1 + maxgoalsw
414 If matchshape(x
,y
) Then
416 game
.speed_timer
= Timer() 'delay speedup
419 If gravity
Then 'remove >100 (marked shapes)
422 For y
=rows
-1 To 0 Step
-1
423 If playfield(x
,y
)>=100 And playfield(x
,y
)<>254 And playfield(x
,y
)<>253 Then
426 If playfield(x
,y
)=254 Then
427 If originalplayfield(x
,y
)=254 Or originalplayfield(x
,y
)=253 Then
428 playfield(x
,y
+gap
)=originalplayfield(x
,y
)
432 Else playfield(x
,y
+gap
)=playfield(x
,y
)
436 If originalplayfield(x
,y
)=254 Or originalplayfield(x
,y
)=253 Then
437 playfield(x
,y
)=originalplayfield(x
,y
)
443 removed=removed or gap>0
445 If removed Then checksituation()
447 For y
=0 To rows
-1 : For x
=0 To columns
-1
448 If playfield(x
,y
)>100 And playfield(x
,y
)<>254 And playfield(x
,y
)<>253 Then
449 If originalplayfield(x
,y
)=254 Or originalplayfield(x
,y
)=254 Then
450 playfield(x
,y
)=originalplayfield(x
,y
)
459 For y
=0 To rows
-1 : For x
=0 To columns
-1
460 If originalplayfield(x
,y
)=253 Then
461 existsnextvariation
=True
462 If playfield(x
,y
)=253 Then gotonextvariation
=False
465 If existsnextvariation
And gotonextvariation
Then
466 loadgame(VARPATH
+"/"+nextvariation
)
474 Sub putshape(x
As Short
, y
As Short
, typ
As UByte
, nodel
As Byte, noshadow
As Byte)
475 Dim As Short strt
, stp
, a
477 'skip the 255-point that marks the end of the previous shape
478 If typ
= 1 Then strt
= 0 Else strt
=inputsindex(typ
- 1 - 1) + 1
479 stp
= inputsindex(typ
- 1) - 1 'leave out 255-point
480 For a
= strt
To stp
: If inputs(a
, 2) <> 0 Then
484 'don't overwrite blocks with shadow
485 o
= playfield(x
+ inputs(a
, 0), y
+ inputs(a
, 1))
486 If o
= 0 Or o
= 254 Then o
= 253
487 ElseIf randominputs
Then
488 o
= randomtable(inputs(a
, 2))
493 o
= originalplayfield(x
+ inputs(a
, 0), y
+ inputs(a
, 1))
494 'preserve special tiles, but don't restore blocks (if any) from the beginning
495 If Not (o
= 254 Or o
= 253) Then o
= 0
498 playfield(x
+ inputs(a
, 0), y
+ inputs(a
, 1)) = o
503 Sub block
.imprint(remove As Byte = True, place As Byte = True, noshadow As Byte = True)
504 If (Not (settings
.show_shadow
And gravity
) Or noshadow
) And this
.shadow
Then Return
505 If remove Then putshape(this.oldx, this.oldy, this.oldtyp, False, noshadow) 'delete old shape
506 If place
Then putshape(this
.x
, this
.y
, this
.typ
, True, noshadow
) 'put new shape
511 If Not this
.move(0,1) Then
516 If Not this
.shadow
Then game
.tim
= Timer()
521 ReDim playfield(0 To columns
-1,0 To rows
-1) As UByte
523 For y
=0 To rows
-1 : For x
=0 To columns
-1
524 playfield(x
,y
)=originalplayfield(x
,y
)
529 Declare Sub drawplayfield()
531 Sub loadTiles(increment
As Byte)
532 settings
.tileset
+= increment
533 If settings
.tileset
> UBound(tilesfiles
) Then settings
.tileset
= 0
534 If settings
.tileset
< 0 Then settings
.tileset
= UBound(tilesfiles
)
536 Dim tilesfile
As String
537 tilesfile
=GFXPATH
& "/" & tilesfiles(settings
.tileset
)
538 tilewidth
= getImgWidth(tilesfile
)
539 game
.w
= tilewidth
*columns
: game
.h
= tilewidth
*rows
540 tilesimg
= ImageCreate(tilewidth
, tilewidth
*(3+numberoftiles
))
541 BLoad tilesfile
, tilesimg
542 scoreimg
= ImageCreate(122,20)
543 BLoad GFXPATH
+"/brojke.bmp", scoreimg
552 Dim As Byte numberstarted
=False
554 Dim xpx
As UShort
= tilewidth
*columns
555 Line(0,0)-(xpx
,16),RGB(0,0,0),BF
556 For a
=0 To 9 'max 10 digits - traze se otpozadi
557 If 10^a
> score
Then Exit For
558 digit
=Fix((score Mod
10^
(a
+1)) / 10^a
)
561 Put (xpx
,1),scoreimg
,(13,0)-(17,14),PSet
564 Put (xpx
,1),scoreimg
,(0,0)-(12,14),PSet
567 Put (xpx
,1),scoreimg
,(-8+digit
*13,0)-(-8+12+digit
*13,14),PSet
575 If settings
.show_score
Then y
+= SCORE_INDICATOR_SIZE
576 Line (0, y
) - (game
.w
, y
+ 7), RGB(22, 22, 22), BF
' background
577 Line (0, y
) - (game
.w
* game
.speed
/ 10, y
+ 3), RGB(222, 222, 222), BF
578 Line (0, y
+ 4) - (game
.w
* (Timer() - game
.speed_timer
) / SPEEDUP_TIME
, y
+ 7), RGB(166, 166, 233), BF
583 ' Prevent too much redraws
584 If Timer() - lastdrawplayfield
< DRAWPLAYFIELD_DELAY
Then
585 lazydrawplayfield
= Timer()
589 shadow
.imprint(False, True, False)
591 Dim As Short offsetx
=0,offsety
=0,offsetpx
=0,offsetpy
=0
592 If settings
.show_score
Then offsetpy
+= SCORE_INDICATOR_SIZE
593 If settings
.show_speed
Then offsetpy
+= SPEED_INDICATOR_SIZE
595 for y
=0 to rows
-1 : for x
=0 to columns
-1
596 If playfield(x
,y
)=0 Then : t
=0
597 ElseIf playfield(x
,y
)=254 Then : t
=1
598 ElseIf playfield(x
,y
)=253 Then : t
=2
599 Else : t
=playfield(x
,y
)+2
601 Put (offsetpx
+(offsetx
+x
)*tilewidth
, offsetpy
+(offsety
+y
)*tilewidth
), _
602 tilesimg
,(0,t
*tilewidth
) - Step(tilewidth
-1,tilewidth
-1),PSet
605 shadow
.imprint(True, False, False)
607 If settings
.show_score
Then drawscore()
608 If settings
.show_speed
Then drawspeed()
613 ' Prevent too much redraws
614 lastdrawplayfield
= Timer()
615 lazydrawplayfield
= -1
621 Dim l
As String, n
As UByte
=0
622 Do Until l
="}" Or Eof(1)
624 ReDim Preserve tilesfiles(n
)
628 ReDim Preserve tilesfiles(n
-2)
633 Dim l
As String, n
As UByte
635 ReDim nextshape(UBound(inputsindex
) + 1) As UByte
636 For n
= 0 To UBound(inputsindex
) Step
4
637 nextshape(n
+ 1) = n
+ 2
638 nextshape(n
+ 2) = n
+ 3
639 nextshape(n
+ 3) = n
+ 4
640 nextshape(n
+ 4) = n
+ 1
644 ReDim nextshape(Len(l
)) As UByte
645 For n
= 0 To Len(l
) 'nextshape(0) is not used
646 nextshape(n
+1)=asctonumber(l
[n
])
654 Dim l
As String, n
As UByte
655 Dim position
As Integer = Seek(1)
657 Do Until l
="}" Or Eof(1)
660 If Len(l
)>columns
Then columns
=Len(l
)
662 ReDim originalplayfield(0 to columns
-1,0 to rows
-1) as UByte
666 Do Until l
="}" Or Eof(1)
671 If l
[a
]=46 Then : originalplayfield(a
,b
-1)=0
672 Else : originalplayfield(a
,b
-1)=asctonumber(l
[a
])
676 originalplayfield(a
,b
-1)=n
677 If n
>numberoftiles
And n
<100 Then numberoftiles
=n
680 If playabletiles
>numberoftiles
Then numberoftiles
=playabletiles
691 Do Until l
="}" Or Eof(1)
693 wrap
=wrap
Or l
="wrap"
694 gravity
=gravity
Or l
="gravity"
695 inputrotate
=inputrotate
Or l
="inputrotate"
696 randominputs
=randominputs
Or l
="randominputs"
697 randomgoals
=randomgoals
Or l
="randomgoals"
698 If Left(l
,6)="tiles:" Then playabletiles
=CInt(Mid(l
,7))
704 If Not (settings
.show_shadow
And gravity
) Then Return
707 shadow
.typ
= blok
.typ
709 Do : Loop While shadow
.move(0,1)
728 If l
="}" Then Exit Do
729 ReDim Preserve help(UBound(help
) + 1)
730 help(UBound(help
)) = l
735 Function loadgame(filename
As String) As Byte
736 If filename
= "" Then Return False
737 Dim l
As String, loadedcycle
As Byte
738 Open filename
For Input
As #
1
739 If Err
>0 Then Print
"Error opening the file":End
749 Line Input #
1,nextvariation
755 loadshapes(inputs(),True)
766 If Not loadedcycle
Then loadcycle()
774 settings
.show_score
= Not settings
.show_score
782 ImageDestroy(tilesimg
)
783 ImageDestroy(scoreimg
)
791 Sub drop_but_dont_fix(y
As Integer)
792 If Int(y
/ tilewidth
- blok
.y
) <= 0 Then Return
793 If blok
.move(0,1) Then
801 Function windowmouse(mode
As String) As String
803 Static pressed
As Integer = 0
804 If (ScreenEvent(@e
)) Then
806 Case EVENT_MOUSE_BUTTON_PRESS
807 If mode
= "gameover" Then Return " " 'Space=end gameover
808 If settings
.play_mouse
Then
810 If settings
.first_button_turning
And Int(e
.y
/ tilewidth
- blok
.y
) <= 0 Then
811 Return " " 'Space = turn
813 drop_but_dont_fix(e
.y
)
818 If e
.button
=2 Then Return " " 'Space = turn
820 If Not settings
.play_mouse
Or e
.button
>2 Then Return Chr(27) 'Esc = open menu
821 Case EVENT_MOUSE_BUTTON_RELEASE
822 If settings
.play_mouse
Then
823 If e
.button
=1 And blok
.dropping
Then Return Chr(13) 'Enter = drop
825 Case EVENT_WINDOW_CLOSE
827 Case EVENT_MOUSE_MOVE
828 If e
.x
> 0 And e
.x
< game
.w
And settings
.play_mouse
And mode
<> "gameover" Then
829 While Int(e
.x
/ tilewidth
- blok
.x
) <> 0 And blok
.move(Sgn(Int(e
.x
/ tilewidth
- blok
.x
)))
831 If blok
.dropping
Then drop_but_dont_fix(e
.y
)
840 Dim As Short starty
= 0, y
= 0, endy
841 Dim As Byte scoredrawn
= False
843 scoredrawn
= settings
.show_score
844 If settings
.show_score
Then starty
+= SCORE_INDICATOR_SIZE
846 endy
= game
.h
+ starty
- 6
847 If settings
.show_speed
Then endy
+= SPEED_INDICATOR_SIZE
852 If Timer() - tim2
> 0.5 Then
854 If keypress
= "" Then keypress
= windowmouse("gameover")
856 While InKey() <> "" : Wend 'prevents exit from gameover screen for 0.5 seconds
860 If Timer() - game
.tim
> 0.03 Then
862 Line (0, y
) - (game
.w
, y
+ 6), RGB(0, 0, 0), BF
863 Put(game
.w
/ 2 - 47 / 2, y
+ 1), scoreimg
,(52, 15) - (99, 19), PSet
869 If y
> SCORE_INDICATOR_SIZE
+ 4 And Not scoredrawn
Then
873 Loop Until keypress
<>""
880 If Not loadgame(Command
) Then
881 If Not loadgame(openloader(VARPATH
)) Then End
884 game
.speed_timer
= game
.tim
886 If lazydrawplayfield
> 0 And Timer() - lazydrawplayfield
> DRAWPLAYFIELD_DELAY
Then
887 lazydrawplayfield
= -1
891 If keypress
= "" Then keypress
= windowmouse("play")
893 Case Chr(255) + "K" 'left
896 Case Chr(255) + "M" 'right
900 blok
.move(0,0,nextshape(blok
.typ
)) 'cycle
902 Case Chr(255) + "H" 'move up or rotate
904 blok
.move(0,0,nextshape(blok
.typ
)) 'cycle
909 Case Chr(255) + "P" 'down
919 Case Chr(13) 'Enter = fix or drop
921 Do : score
+=1 : Loop While blok
.move(0,1)
929 Case "o", "O" 'settings
930 game
.menu_timer
= Timer()
932 'make up for lost time
933 game
.tim
+= Timer() - game
.menu_timer
934 game
.speed_timer
+= Timer() - game
.menu_timer
935 resizewindow() : drawplayfield()
937 game
.menu_timer
= Timer()
938 If Not loadgame(openloader(VARPATH
)) Then
939 resizewindow() 'restore window size and title
940 'make up for lost time
941 game
.tim
+= Timer() - game
.menu_timer
942 game
.speed_timer
+= Timer() - game
.menu_timer
945 Case Chr(255)+";" 'F1
946 game
.menu_timer
= Timer()
948 'make up for lost time
949 game
.tim
+= Timer() - game
.menu_timer
950 game
.speed_timer
+= Timer() - game
.menu_timer
951 Case Chr(255)+"<" 'F2
956 game
.menu_timer
= Timer()
958 'make up for lost time
959 game
.tim
+= Timer() - game
.menu_timer
960 game
.speed_timer
+= Timer() - game
.menu_timer
963 If gravity
And Timer() - game
.tim
> SPEED
/ game
.speed
then
967 'speedup based on time
968 If gravity
And game
.speed
< MAX_SPEED
And Timer() > game
.speed_timer
+ SPEEDUP_TIME
Then
969 game
.speed_timer
= Timer()