Here is the snipd src from my conversion (03-07-15) regarding keyb input and input handling.
Please note that there are still bugs, e.g. faded blocks and timing and so on.
I hope it helps, anyway.
Please keep me noticed if you encounter problems.
(Please note i have removed lines that are already known to make it easier to find what you are looking for).
First startup:
Code:
;tetris clone example code
;by WolRon
;converted for blitz2(the AMIGA) by Cylon(at)eab
WBStartup
;SetErr:End:End SetErr
.
.init
DEFTYPE.l ;make sure all boolean vars are real fix (0/-1)!!
;set up graphics
;Graphics 800, 600
;SetBuffer BackBuffer()
; no doublebuffer yet !
;
#Width =$80000023
#Height =$80000024
#Dpth =$80000025
#Typ =$8000002D
#DisplayID =$80000032
#Overscan =$80000034
#AutoScroll =$80000039
#LikeWorkbench=$80000047
;NOTE:We use an AGA (classic chipset) screen mode Workbench!!!
._Display
ScreenTags1,"tetris test",#LikeWorkbench,True,#Width,800,#Height,600,#Dpth,5,#AutoScroll,True,0,0
Window1,0,0,800,600,$1900,"",2,1
ScreensBitMap1,1
WindowOutput1 ;Print to window
._Dims
;set up arrays
Dim Board (9, 22)
Dim BlockColor (99, 2) ;99 cols is enough? we use them as color index
Dim Piece (28, 3, 3)
Dim LineToErase (4)
._DataRead
;
._SetOrigins
EndOfGame = True
._DefKeys
;declare keys
;--------------------------------------------
;keyboard constants
#KEY_BSP=8 ;backspace
#KEY_RET=13 ;return
#KEY_ESC=27 ;escape
#KEY_CUP=28 ;cursor up
#KEY_CDN=29 ;cursor down
#KEY_CRT=30 ;cursor right
#KEY_CLT=31 ;cursor left
#KEY_DEL=127
#KEY_HLP=139
#KEY_F1 =129
#KEY_F2 =130
#KEY_F3 =131
#KEY_F4 =132
#KEY_F5 =133
#KEY_F6 =134
#KEY_F7 =135
#KEY_F8 =136
#KEY_F9 =137
#KEY_F10=138
;keyboard QUALIFIERs (extra keys)
#q_none =$ 0
#q_caps =$ 4
#q_control =$ 8
#q_shiftl =$ 1
#q_shiftr =$ 2
#q_altl =$10
#q_altr =$20
#q_amigal =$40
#q_amigar =$80
;--------------------------------------------
;adapt my constants to org src
KeyEsc =#KEY_ESC ;=27
KeyPause =Asc("p")
KeyRotate =Asc("x")
KeyRotateLeft =Asc("c")
KeyLeft =#KEY_CLT ;=31
KeyRight =#KEY_CRT ;=30
KeyDwn =#KEY_CDN ;=29
KeyInstantDrop =32 ;" " ;space
KeyN =Asc("n")
KeyQ =Asc("q")
._Macros
...
Code:
.funcs
._EraseBoard
Statement EraseBoard{}
!myshared
;erase board
!Origin {OrigBoardX, OrigBoardY + 75}
;Color 255, 0, 0 ;red
;Rect -3, -3, 255, 505, 0
Boxf xx-2,yy-2,xx+254,yy +504,#cblack
Box xx-3,yy-3,xx+255,yy +505,#cred
End Statement
Note: EraseBoard{} was added to avoid entire clear and redraw of screen (see main).
Code:
._DropPiece
Function DropPiece{}
!myshared
For yiter = 3 To 0 Step -1
For xiter = 0 To 3
If Piece(CurrentPiece + (CurPieceRot * 7), xiter, yiter) <> 0
If CurPieceY+yiter+1 > 22 Then Function Return False
If Board(CurPieceX+xiter, CurPieceY+yiter+1) <> 0 Then Function Return False
EndIf
Next
Next
CurPieceY = CurPieceY + 1
CalcGhostPosition {}
Function Return True
End Function
._PlacePiece
Function PlacePiece{}
!myshared
;Local outofbounds
For yiter = 0 To 3
For xiter = 0 To 3
If Piece(CurrentPiece + (CurPieceRot * 7), xiter, yiter) <> 0
Board(CurPieceX+xiter, CurPieceY+yiter) = CurrentPiece
If CurPieceY+yiter < 3 Then outofbounds = True;above the 10x20 playing area
EndIf
Next
Next
If outofbounds Then Function Return False
;check if any lines were created
CheckForLines {}
If NOT ClearLines
ResetPiece{}
EndIf
Function Return True
End Function
...
Now, the ProcessInputs{}:
Code:
._ProcessInputs
Statement ProcessInputs{ev.l}
!myshared
If ev = $400 ;keyboard event
;Stop ;or BeepScreen!
;BeepScreen1
inp.w=Asc(Inkey$) ;get input from window (!)
If NOT EndOfGame
Select inp ;switch keys
Case KeyRotate :RotatePiece{False} ;space key or X key
Case KeyRotateLeft :RotatePiece{True}; C key (Z key)
Case KeyInstantDrop:CurPieceY = GhostPieceY
Case KeyEsc :End
Default
;If (NOT KeyLeft) AND (NOT KeyRight)
If inp = NOT (KeyLeft OR KeyRight)
RepeatDelay = True
Else
If RepeatSpeed < NowTime
If RepeatDelay
RepeatSpeed = NowTime + 50 ;150
RepeatDelay = False
Else
RepeatSpeed = NowTime + 10 ;30
EndIf
If inp = KeyLeft Then MoveLeft{}
If inp = KeyRight Then MoveRight{}
EndIf
EndIf
If (inp = KeyEsc) OR (inp = KeyPause)
If GamePaused
;Stop
GamePaused = 0
LastDropTime = LastDropTime + Ticks - PauseTime ; MilliSecs() - PauseTime
Else
GamePaused = True
PauseTime = Ticks ;MilliSecs()
EndIf
EndIf
End Select
Else ;EndOfGame
Select inp
Case KeyQ :EndGame{} ;quit game
Case KeyN :StartNewGame{} ;new game
Case KeyEsc :End
End Select
EndIf
EndIf ;ev
End Statement
As you can see i've added an argument to the statement call! This argument is provided from within the main routine:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Main Game loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.main
DrawInfo{}
ResetTimer
Repeat
Delay_5;make it a levelspeed-loop!
;:Cls
EraseBoard{}
DrawBoard{}
If GamePaused
DrawPauseMessage{}
Else
DrawBoardBlocks{}
DrawNextPiece{}
If NOT ClearLines
If NOT EndOfGame Then DrawGhostPiece{}
DrawCurrentPiece{}
EndIf
EndIf
ProcessInputs{Event}
If EndOfGame=0
If ClearLines=0
If GamePaused=0
If Inkey$=Chr$(KeyDwn) ;****
DropDelay = 35
Else
DropDelay = DropSpeed
EndIf
NowTime = Ticks; MilliSecs()
If (NowTime > LastDropTime + DropDelay) OR KeyInstantDrop
LastDropTime = NowTime
If NOT DropPiece{}
If NOT PlacePiece{}
EndGame{}
EndIf
EndIf
EndIf
EndIf
Else
LineClearer{}
EndIf
Else
PrintGameOver{}
EndIf
;Flip no dbuffer
Until exit;Esc key
.mloop
.
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;; End of main loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
._colsdat
._piecedat
;piece descriptions
.eof
The
Event in main is the key part. It provides any input coming from mouse, keyboard, windowhandling and so on. You just have to filter what is coming in. We do this in processinputs{} by looking only for $400 type events, which are keyboard inputs.
Please also note the reduced timing values in main and processinputs{}!
(w.i.p.)