packages feed

tetris-0.27177: Pad.hs

module Pad where

import Graphics.UI.GLUT hiding (Red, Green, Blue, rotate)
import Data.Bits ((.|.), (.&.), complement)

--------------------------------
-- Pad
padU,padL,padR,padD,padA,padB,padAll :: Int
padU	= 1
padL	= 2
padR	= 4
padD	= 8
padA	= 16
padB	= 32

padAll	= padU .|. padL .|. padR .|. padD .|. padA .|. padB

data Pad = Pad {
	pressed :: [Key],	-- 現在押されてるキー
	btn :: Int,			-- 押されてるボタン
	obtn :: Int,		-- 前回押されてたボタン
	trig :: Int,		-- 押された瞬間のボタン
	rpt :: Int,			-- 押され続けてるボタン
	rptc :: Int			-- リピート用カウンタ
}

newPad :: Pad
newPad = Pad {
	pressed = [],
	btn = 0,
	obtn = 0,
	trig = 0,
	rpt = 0,
	rptc = 0
}

calcPadState :: [Key] -> Int
calcPadState keys = foldl (\r x -> r .|. btnValue x) 0 keys
	where
		btnValue :: Key -> Int
		btnValue (Char 'i')	=	padU
		btnValue (Char 'j')	=	padL
		btnValue (Char 'k')	=	padD
		btnValue (Char 'l')	=	padR
		btnValue (Char ' ')	=	padA
		btnValue (Char 'z')	=	padB

		btnValue (SpecialKey KeyUp)		= padU
		btnValue (SpecialKey KeyLeft)	= padL
		btnValue (SpecialKey KeyRight)	= padR
		btnValue (SpecialKey KeyDown)	= padD

		btnValue _			=	0

repeatCnt1, repeatCnt2, repeatBtn :: Int
repeatCnt1 = 7		-- リピート初回の時間
repeatCnt2 = 1		-- リピート2回目以降の時間
repeatBtn = padL .|. padR		-- リピートで使うボタン

updatePad :: Pad -> Pad
updatePad pad =
	pad { btn = btn', obtn = obtn', trig = trg', rpt = rpt', rptc = rptc' }
	where
		btn' = calcPadState (pressed pad)
		obtn' = btn pad
		trg' = btn' .&. complement obtn'
		tmprptc
			| (btn' .&. repeatBtn) /= (obtn' .&. repeatBtn)	= 0
			| otherwise		= rptc pad + 1
		bRepeat = tmprptc >= repeatCnt1
		rptc'
			| bRepeat		= repeatCnt1 - repeatCnt2
			| otherwise		= tmprptc
		rpt'
			| bRepeat		= btn'
			| otherwise		= trg'