diff options
author | Andrew Cady <d@jerkface.net> | 2015-12-17 22:44:06 -0500 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2015-12-17 22:44:06 -0500 |
commit | 11bc93662f77a13f4842066fcf40f83b3d3e2ece (patch) | |
tree | 1d7f3341e8ffacec33f72b6ac599b01358180a2f | |
parent | 9cd1f630d077de4851fc8783ff80e62b7ef3bf3e (diff) |
Fix GHC/HLint warnings. No semantic changes.
-rw-r--r-- | axis.hs | 76 |
1 files changed, 53 insertions, 23 deletions
@@ -2,20 +2,14 @@ | |||
2 | {-# LANGUAGE FlexibleContexts #-} | 2 | {-# LANGUAGE FlexibleContexts #-} |
3 | import Prelude () | 3 | import Prelude () |
4 | import BasePrelude | 4 | import BasePrelude |
5 | import Data.Time.Clock | 5 | -- import Data.Time.Clock |
6 | import Control.Monad | 6 | import Control.Monad |
7 | import qualified Graphics.UI.SDL as SDL | 7 | import qualified Graphics.UI.SDL as SDL |
8 | import AlsaSeq | 8 | import AlsaSeq |
9 | import qualified Data.Set as Set | 9 | import qualified Data.Set as Set |
10 | import qualified Graphics.UI.SDL.TTF as SDL.TTF | 10 | import qualified Graphics.UI.SDL.TTF as SDL.TTF |
11 | import Data.String | ||
12 | import Graphics.UI.SDL.Keysym as SDL.Keysym | 11 | import Graphics.UI.SDL.Keysym as SDL.Keysym |
13 | import Graphics.UI.SDL.Primitives as SDL.Primitive | 12 | import Graphics.UI.SDL.Primitives as SDL.Primitive |
14 | import Data.Int (Int16) | ||
15 | import qualified System.Exit as Exit | ||
16 | import Data.List (elemIndex, elemIndices, filter, groupBy, length, reverse, sort) | ||
17 | import GHC.Word | ||
18 | import Data.Bits | ||
19 | import qualified Sound.ALSA.Sequencer.Event as Event | 13 | import qualified Sound.ALSA.Sequencer.Event as Event |
20 | import qualified Graphics.UI.SDL.Utilities as SDL.Util | 14 | import qualified Graphics.UI.SDL.Utilities as SDL.Util |
21 | import qualified Data.Map as Map | 15 | import qualified Data.Map as Map |
@@ -27,25 +21,34 @@ import qualified Sound.ALSA.Sequencer.Address | |||
27 | 21 | ||
28 | import AlsaShutUp | 22 | import AlsaShutUp |
29 | 23 | ||
24 | smartShowPitch :: Word8 -> String | ||
30 | smartShowPitch = showPitch -- TODO: use flat for Eb, Bb; use unicode flat/sharp chars | 25 | smartShowPitch = showPitch -- TODO: use flat for Eb, Bb; use unicode flat/sharp chars |
31 | 26 | ||
27 | _USE_HEXAGONS, _LABEL_WHILE_PLAYING, _LABEL_ALL_KEYS :: Bool | ||
32 | _USE_HEXAGONS = True | 28 | _USE_HEXAGONS = True |
33 | _LABEL_WHILE_PLAYING = True | 29 | _LABEL_WHILE_PLAYING = True |
34 | _LABEL_ALL_KEYS = False | 30 | _LABEL_ALL_KEYS = False |
35 | 31 | ||
32 | _AXIS_ROWS, _AXIS_UNIQUE_COLS, _AXIS_TOPLEFT_PITCH, _AXIS_BOTTOMLEFT_PITCH, _AXIS_TOPRIGHT_PITCH :: Word8 | ||
36 | _AXIS_ROWS = 7 + 4 | 33 | _AXIS_ROWS = 7 + 4 |
37 | _AXIS_UNIQUE_COLS = 7 | 34 | _AXIS_UNIQUE_COLS = 7 |
35 | |||
36 | _AXIS_COLS_REPEAT :: Integer | ||
38 | _AXIS_COLS_REPEAT = 2 | 37 | _AXIS_COLS_REPEAT = 2 |
38 | |||
39 | _AXIS_TOPLEFT_PITCH = 81 + (7 * (_AXIS_ROWS - 7) `div` 2) | 39 | _AXIS_TOPLEFT_PITCH = 81 + (7 * (_AXIS_ROWS - 7) `div` 2) |
40 | _AXIS_BOTTOMLEFT_PITCH = _AXIS_TOPLEFT_PITCH - (_AXIS_ROWS * 7) | 40 | _AXIS_BOTTOMLEFT_PITCH = _AXIS_TOPLEFT_PITCH - (_AXIS_ROWS * 7) |
41 | _AXIS_TOPRIGHT_PITCH = _AXIS_TOPLEFT_PITCH + _AXIS_UNIQUE_COLS `div` 2 | 41 | _AXIS_TOPRIGHT_PITCH = _AXIS_TOPLEFT_PITCH + _AXIS_UNIQUE_COLS `div` 2 |
42 | 42 | ||
43 | _KEY_BORDER_COLOR, _KEY_ON_COLOR, _KB_BG_COLOR, _KEY_TEXT_COLOR :: SDL.Color | ||
44 | |||
43 | --_KEY_BORDER_COLOR = (SDL.Color 0 0 255) | 45 | --_KEY_BORDER_COLOR = (SDL.Color 0 0 255) |
44 | _KEY_BORDER_COLOR = SDL.Color 0 0 0 | 46 | _KEY_BORDER_COLOR = SDL.Color 0 0 0 |
45 | _KEY_ON_COLOR = SDL.Color 0xAA 0x00 0xFF | 47 | _KEY_ON_COLOR = SDL.Color 0xAA 0x00 0xFF |
46 | _KB_BG_COLOR = SDL.Color 0 0 0 | 48 | _KB_BG_COLOR = SDL.Color 0 0 0 |
47 | _KEY_TEXT_COLOR = SDL.Color 128 128 0 | 49 | _KEY_TEXT_COLOR = SDL.Color 128 128 0 |
48 | 50 | ||
51 | _KEY_BORDER_COLOR_PIXEL, _KB_BG_COLOR_PIXEL :: SDL.Pixel | ||
49 | _KEY_BORDER_COLOR_PIXEL = colorToPixel _KEY_BORDER_COLOR | 52 | _KEY_BORDER_COLOR_PIXEL = colorToPixel _KEY_BORDER_COLOR |
50 | _KB_BG_COLOR_PIXEL = colorToPixel _KB_BG_COLOR | 53 | _KB_BG_COLOR_PIXEL = colorToPixel _KB_BG_COLOR |
51 | 54 | ||
@@ -69,6 +72,7 @@ http://en.wikipedia.org/wiki/Enhanced_Graphics_Adapter | |||
69 | 15 – bright white (#FFFFFF) 111111 63 | 72 | 15 – bright white (#FFFFFF) 111111 63 |
70 | -} | 73 | -} |
71 | 74 | ||
75 | _CGA :: [SDL.Color] | ||
72 | _CGA = [ SDL.Color 0x00 0x00 0x00, --black | 76 | _CGA = [ SDL.Color 0x00 0x00 0x00, --black |
73 | SDL.Color 0x00 0x00 0xAA, --blue | 77 | SDL.Color 0x00 0x00 0xAA, --blue |
74 | SDL.Color 0x00 0xAA 0x00, --green | 78 | SDL.Color 0x00 0xAA 0x00, --green |
@@ -86,23 +90,32 @@ _CGA = [ SDL.Color 0x00 0x00 0x00, --black | |||
86 | SDL.Color 0xFF 0xFF 0x55, --bright yellow | 90 | SDL.Color 0xFF 0xFF 0x55, --bright yellow |
87 | SDL.Color 0xFF 0xFF 0xFF] --bright white | 91 | SDL.Color 0xFF 0xFF 0xFF] --bright white |
88 | 92 | ||
93 | _CHAN_TO_COLOR :: [SDL.Color] | ||
89 | _CHAN_TO_COLOR = _KEY_ON_COLOR : tail _CGA | 94 | _CHAN_TO_COLOR = _KEY_ON_COLOR : tail _CGA |
90 | 95 | ||
96 | _drawHexircle :: Bool -> SDL.Surface -> Int16 -> Int16 -> Int16 -> SDL.Pixel -> IO Bool | ||
91 | _drawHexircle f v x y s c = | 97 | _drawHexircle f v x y s c = |
92 | if _USE_HEXAGONS | 98 | if _USE_HEXAGONS |
93 | then _drawHexagonSDL f v x y s c | 99 | then _drawHexagonSDL f v x y s c |
94 | else (if f then SDL.Primitive.filledCircle else SDL.Primitive.circle) v x y (s * 7 `div` 9) c | 100 | else (if f then SDL.Primitive.filledCircle else SDL.Primitive.circle) v x y (s * 7 `div` 9) c |
95 | 101 | ||
102 | drawHexircle :: SDL.Surface -> Int16 -> Int16 -> Int16 -> SDL.Pixel -> IO Bool | ||
96 | drawHexircle = _drawHexircle False | 103 | drawHexircle = _drawHexircle False |
104 | |||
105 | drawFilledHexircle :: SDL.Surface -> Int16 -> Int16 -> Int16 -> SDL.Pixel -> IO Bool | ||
97 | drawFilledHexircle = _drawHexircle True | 106 | drawFilledHexircle = _drawHexircle True |
107 | |||
108 | colorToPixel :: SDL.Color -> SDL.Pixel | ||
98 | colorToPixel x = let (SDL.Color r g b) = x in rgbColor r g b | 109 | colorToPixel x = let (SDL.Color r g b) = x in rgbColor r g b |
99 | 110 | ||
111 | inMajorC :: (Eq a, Num a) => a -> Bool | ||
100 | inMajorC pclass = not (pclass == 1 || pclass == 3 || pclass == 6 || pclass == 8 || pclass == 10) | 112 | inMajorC pclass = not (pclass == 1 || pclass == 3 || pclass == 6 || pclass == 8 || pclass == 10) |
101 | 113 | ||
102 | -- TODO: color schemes with per-key {bg, border, hilightcolor, textcolor} | 114 | -- TODO: color schemes with per-key {bg, border, hilightcolor, textcolor} |
103 | -- TODO: try hilighting like in the app, where only part of the key is colored | 115 | -- TODO: try hilighting like in the app, where only part of the key is colored |
104 | -- TODO: idea: for the channels, draw a dot. offset the dot from the center of the key at an angle determined by the channel number | 116 | -- TODO: idea: for the channels, draw a dot. offset the dot from the center of the key at an angle determined by the channel number |
105 | 117 | ||
118 | pitchToColor :: Integral a => a -> SDL.Color | ||
106 | pitchToColor p = | 119 | pitchToColor p = |
107 | case p `mod` 12 of | 120 | case p `mod` 12 of |
108 | 2 -> SDL.Color 0xC0 0xC0 0xFF -- D | 121 | 2 -> SDL.Color 0xC0 0xC0 0xFF -- D |
@@ -133,6 +146,7 @@ smartDrawKeys colsRepeat reallyErase beforeKeys_ nowKeys_ videoSurface font axis | |||
133 | (if showLabel then Just text else Nothing) | 146 | (if showLabel then Just text else Nothing) |
134 | chans | 147 | chans |
135 | 148 | ||
149 | allKeysOff :: (Enum b, Integral a, Integral a1, Integral a2, Num b) => b -> Bool -> SDL.Surface -> SDL.TTF.Font -> [(a1, a2)] -> a -> IO () | ||
136 | allKeysOff colsRepeat reallyErase videoSurface font axis_key_locations axis_key_size = do | 150 | allKeysOff colsRepeat reallyErase videoSurface font axis_key_locations axis_key_size = do |
137 | let indices = [0 .. length axis_key_locations - 1] | 151 | let indices = [0 .. length axis_key_locations - 1] |
138 | showLabel = not reallyErase && _LABEL_ALL_KEYS | 152 | showLabel = not reallyErase && _LABEL_ALL_KEYS |
@@ -157,10 +171,10 @@ allKeysOff colsRepeat reallyErase videoSurface font axis_key_locations axis_key_ | |||
157 | 171 | ||
158 | -- Next order of business: | 172 | -- Next order of business: |
159 | 173 | ||
160 | --drawKey :: (Integral a1, Integral a2, Integral a) => Int -> SDL.Surface -> SDL.TTF.Font -> [(a1, a2)] -> a -> SDL.Color -> t -> Maybe String -> [Int] -> IO () | 174 | drawKey :: (Integral a, Integral a1, Integral a2) => Int -> SDL.Surface -> SDL.TTF.Font -> [(a1, a2)] -> a -> SDL.Color -> Maybe String -> [Event.Channel] -> IO () |
161 | drawKey idx videoSurface font axis_key_locations axis_key_size fillColor text channels = do | 175 | drawKey idx videoSurface font axis_key_locations axis_key_size fillColor text channels = do |
162 | let (x, y) = axis_key_locations !! idx | 176 | let (x, y) = axis_key_locations !! idx |
163 | drawFilledHexircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) (colorToPixel fillColor) | 177 | void $ drawFilledHexircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) (colorToPixel fillColor) |
164 | let len = length channels | 178 | let len = length channels |
165 | let channels' = sort channels | 179 | let channels' = sort channels |
166 | Control.Monad.when (len /= 0) $ | 180 | Control.Monad.when (len /= 0) $ |
@@ -181,12 +195,18 @@ drawKey idx videoSurface font axis_key_locations axis_key_size fillColor text ch | |||
181 | (Just t) -> centerText videoSurface x y font _KEY_TEXT_COLOR fillColor t | 195 | (Just t) -> centerText videoSurface x y font _KEY_TEXT_COLOR fillColor t |
182 | _ -> return () | 196 | _ -> return () |
183 | 197 | ||
184 | fi = fromIntegral | 198 | rgbColor :: Word8 -> Word8 -> Word8 -> SDL.Pixel |
185 | rgbColor r g b = SDL.Pixel (shiftL (fi r) 24 .|. shiftL (fi g) 16 .|. shiftL (fi b) 8 .|. fi 255) | 199 | rgbColor r g b = SDL.Pixel (shiftL (fi r) 24 .|. shiftL (fi g) 16 .|. shiftL (fi b) 8 .|. fi 255) |
200 | where | ||
201 | fi = fromIntegral | ||
202 | fi :: Word8 -> Word32 | ||
186 | 203 | ||
204 | chooseFontSize :: Integral a => a -> a -> a | ||
187 | chooseFontSize h w = 30 * d `div` 1024 where d = min h w | 205 | chooseFontSize h w = 30 * d `div` 1024 where d = min h w |
188 | 206 | ||
207 | _SDL_DIGITS :: Set.Set SDLKey | ||
189 | _SDL_DIGITS = Set.fromList [SDL.SDLK_1, SDL.SDLK_2, SDL.SDLK_3, SDL.SDLK_4, SDL.SDLK_5, SDL.SDLK_6, SDL.SDLK_7, SDL.SDLK_8, SDL.SDLK_9, SDL.SDLK_0] | 208 | _SDL_DIGITS = Set.fromList [SDL.SDLK_1, SDL.SDLK_2, SDL.SDLK_3, SDL.SDLK_4, SDL.SDLK_5, SDL.SDLK_6, SDL.SDLK_7, SDL.SDLK_8, SDL.SDLK_9, SDL.SDLK_0] |
209 | |||
190 | firstDigitDown :: Set.Set SDL.Keysym.SDLKey -> Maybe Integer | 210 | firstDigitDown :: Set.Set SDL.Keysym.SDLKey -> Maybe Integer |
191 | firstDigitDown k = if Set.null digitsDown then Nothing else Just $ (-48 +) $ fromIntegral $ SDL.Util.fromEnum $ Set.findMin digitsDown | 211 | firstDigitDown k = if Set.null digitsDown then Nothing else Just $ (-48 +) $ fromIntegral $ SDL.Util.fromEnum $ Set.findMin digitsDown |
192 | where digitsDown = Set.intersection _SDL_DIGITS k | 212 | where digitsDown = Set.intersection _SDL_DIGITS k |
@@ -207,6 +227,7 @@ data Env = Env { | |||
207 | _setVideoMode :: Int -> Int -> IO SDL.Surface | 227 | _setVideoMode :: Int -> Int -> IO SDL.Surface |
208 | } | 228 | } |
209 | 229 | ||
230 | main :: IO () | ||
210 | main = | 231 | main = |
211 | withAlsaInit $ \h public private q publicAddr privateAddr -> do | 232 | withAlsaInit $ \h public private q publicAddr privateAddr -> do |
212 | cmdlineAlsaConnect h public -- fail early if bad command lines | 233 | cmdlineAlsaConnect h public -- fail early if bad command lines |
@@ -218,7 +239,7 @@ main = | |||
218 | warpMouse = do | 239 | warpMouse = do |
219 | _ <- SDL.warpMouse (fromIntegral (sWidth `div` 2)) (fromIntegral (sHeight `div` 2)) | 240 | _ <- SDL.warpMouse (fromIntegral (sWidth `div` 2)) (fromIntegral (sHeight `div` 2)) |
220 | return () | 241 | return () |
221 | setVideoMode w h = SDL.setVideoMode w h 32 [SDL.HWSurface, SDL.Resizable, SDL.DoubleBuf] | 242 | setVideoMode wid hei = SDL.setVideoMode wid hei 32 [SDL.HWSurface, SDL.Resizable, SDL.DoubleBuf] |
222 | _ <- setVideoMode sWidth sHeight | 243 | _ <- setVideoMode sWidth sHeight |
223 | 244 | ||
224 | _ <- SDL.TTF.init | 245 | _ <- SDL.TTF.init |
@@ -228,7 +249,7 @@ main = | |||
228 | -- pixelFormat or the faked one, so fuck it. See colorToPixel let pixelFormat = | 249 | -- pixelFormat or the faked one, so fuck it. See colorToPixel let pixelFormat = |
229 | -- SDL.surfaceGetPixelFormat videoSurface pixelFormat <- SDL.surfaceGetPixelFormat <$> | 250 | -- SDL.surfaceGetPixelFormat videoSurface pixelFormat <- SDL.surfaceGetPixelFormat <$> |
230 | -- SDL.createRGBSurfaceEndian [] 1 1 24 | 251 | -- SDL.createRGBSurfaceEndian [] 1 1 24 |
231 | shutUp | 252 | void $ shutUp |
232 | putStrLn "Initialized." | 253 | putStrLn "Initialized." |
233 | 254 | ||
234 | (_, ()) <- execRWST mainLoop | 255 | (_, ()) <- execRWST mainLoop |
@@ -236,13 +257,14 @@ main = | |||
236 | (LoopState True _AXIS_COLS_REPEAT Set.empty Set.empty (sWidth, sHeight) font) | 257 | (LoopState True _AXIS_COLS_REPEAT Set.empty Set.empty (sWidth, sHeight) font) |
237 | return () | 258 | return () |
238 | 259 | ||
260 | setFont :: (MonadIO m, MonadState LoopState m) => (Int, Int) -> m () | ||
239 | setFont resolution' = do | 261 | setFont resolution' = do |
240 | font <- gets _sdlFont | ||
241 | let (w, h) = resolution' | 262 | let (w, h) = resolution' |
242 | fontSize = chooseFontSize w h | 263 | fontSize = chooseFontSize w h |
243 | font' <- liftIO $ SDL.TTF.openFont "LiberationMono-Bold.ttf" fontSize | 264 | font' <- liftIO $ SDL.TTF.openFont "LiberationMono-Bold.ttf" fontSize |
244 | modify $ \s -> s { _sdlFont = font' } | 265 | modify $ \s -> s { _sdlFont = font' } |
245 | 266 | ||
267 | parseEvents :: RWST Env () LoopState IO (Bool, Set.Set SDLKey, MidiPitchSet, (Int, Int), Integer) | ||
246 | parseEvents = do | 268 | parseEvents = do |
247 | Env h q publicAddr setVideoMode <- ask | 269 | Env h q publicAddr setVideoMode <- ask |
248 | LoopState _ colsRepeat midiKeysDown keysDown resolution _ <- get | 270 | LoopState _ colsRepeat midiKeysDown keysDown resolution _ <- get |
@@ -264,22 +286,22 @@ mainLoop = do | |||
264 | Env h q publicAddr setVideoMode <- ask | 286 | Env h q publicAddr setVideoMode <- ask |
265 | LoopState firstLoop _ midiKeysDown keysDown _ _ <- get | 287 | LoopState firstLoop _ midiKeysDown keysDown _ _ <- get |
266 | 288 | ||
267 | (restartVideo, keysDown', midiKeysDown', resolution', colsRepeat') <- parseEvents | 289 | (restartVideo, keysDown', midiKeysDown', resolution, colsRepeat) <- parseEvents |
268 | 290 | ||
269 | when restartVideo $ do | 291 | when restartVideo $ do |
270 | let (w, h) = resolution' | 292 | let (wid, hei) = resolution |
271 | void $ liftIO $ setVideoMode w h | 293 | void $ liftIO $ setVideoMode wid hei |
272 | setFont resolution' | 294 | setFont resolution |
273 | 295 | ||
274 | font' <- gets _sdlFont | 296 | font <- gets _sdlFont |
275 | 297 | ||
276 | videoSurface <- liftIO SDL.getVideoSurface | 298 | videoSurface <- liftIO SDL.getVideoSurface |
277 | videoClipRect <- liftIO $ SDL.getClipRect videoSurface | 299 | videoClipRect <- liftIO $ SDL.getClipRect videoSurface |
278 | let (axis_key_size, axis_key_locations) = getKeyLocations colsRepeat' videoClipRect | 300 | let (axis_key_size, axis_key_locations) = getKeyLocations colsRepeat videoClipRect |
279 | 301 | ||
280 | let _ALL_PITCHES = Set.fromList $ map (\p -> (Event.Channel 1, Event.Pitch p)) | 302 | let _ALL_PITCHES = Set.fromList $ map (\p -> (Event.Channel 1, Event.Pitch p)) |
281 | [_AXIS_BOTTOMLEFT_PITCH .. _AXIS_TOPRIGHT_PITCH] | 303 | [_AXIS_BOTTOMLEFT_PITCH .. _AXIS_TOPRIGHT_PITCH] |
282 | keysOFF really = allKeysOff colsRepeat' really videoSurface font' axis_key_locations axis_key_size | 304 | keysOFF really = allKeysOff colsRepeat really videoSurface font axis_key_locations axis_key_size |
283 | allKeysOFF = keysOFF False | 305 | allKeysOFF = keysOFF False |
284 | allKeysReallyOFF = keysOFF True | 306 | allKeysReallyOFF = keysOFF True |
285 | 307 | ||
@@ -303,11 +325,11 @@ mainLoop = do | |||
303 | -- let chord = show $ pitchList midiKeysDown' | 325 | -- let chord = show $ pitchList midiKeysDown' |
304 | -- let chord = show $ map (\i->elemIndices i pitchIndex) $ pitchList midiKeysDown' | 326 | -- let chord = show $ map (\i->elemIndices i pitchIndex) $ pitchList midiKeysDown' |
305 | -- textBand videoSurface videoClipRect (SDL.Rect 0 70 0 70) font chord | 327 | -- textBand videoSurface videoClipRect (SDL.Rect 0 70 0 70) font chord |
306 | liftIO $ smartDrawKeys colsRepeat' False midiKeysDown midiKeysDown' videoSurface font' axis_key_locations axis_key_size | 328 | liftIO $ smartDrawKeys colsRepeat False midiKeysDown midiKeysDown' videoSurface font axis_key_locations axis_key_size |
307 | 329 | ||
308 | when restartVideo $ do | 330 | when restartVideo $ do |
309 | liftIO allKeysOFF | 331 | liftIO allKeysOFF |
310 | liftIO $ smartDrawKeys colsRepeat' False Set.empty midiKeysDown' videoSurface font' axis_key_locations axis_key_size | 332 | liftIO $ smartDrawKeys colsRepeat False Set.empty midiKeysDown' videoSurface font axis_key_locations axis_key_size |
311 | 333 | ||
312 | when (keysDown' /= keysDown) $ do | 334 | when (keysDown' /= keysDown) $ do |
313 | when (keyDown SDL.SDLK_BACKSPACE keysDown') $ liftIO allKeysOFF | 335 | when (keyDown SDL.SDLK_BACKSPACE keysDown') $ liftIO allKeysOFF |
@@ -331,14 +353,17 @@ mainLoop = do | |||
331 | let delay = 1000 `div` framerate -- TODO: subtract delta | 353 | let delay = 1000 `div` framerate -- TODO: subtract delta |
332 | liftIO $ SDL.delay delay | 354 | liftIO $ SDL.delay delay |
333 | unless (keyDown SDL.SDLK_ESCAPE keysDown) $ do | 355 | unless (keyDown SDL.SDLK_ESCAPE keysDown) $ do |
334 | put (LoopState False colsRepeat' midiKeysDown' keysDown' resolution' font') | 356 | put (LoopState False colsRepeat midiKeysDown' keysDown' resolution font) |
335 | mainLoop | 357 | mainLoop |
336 | 358 | ||
359 | zipzip :: [[b]] -> [[b]] | ||
337 | zipzip ls = if null (head ls) then [] else map head ls : zipzip (map tail ls) | 360 | zipzip ls = if null (head ls) then [] else map head ls : zipzip (map tail ls) |
338 | 361 | ||
362 | drawHexagonSDL, drawFilledHexagonSDL :: SDL.Surface -> Int16 -> Int16 -> Integer -> SDL.Pixel -> IO Bool | ||
339 | drawHexagonSDL = _drawHexagonSDL False | 363 | drawHexagonSDL = _drawHexagonSDL False |
340 | drawFilledHexagonSDL = _drawHexagonSDL True | 364 | drawFilledHexagonSDL = _drawHexagonSDL True |
341 | 365 | ||
366 | _drawHexagonSDL :: Integral a => Bool -> SDL.Surface -> Int16 -> Int16 -> a -> SDL.Pixel -> IO Bool | ||
342 | _drawHexagonSDL filled videoSurface centerx centery radius pixel = do | 367 | _drawHexagonSDL filled videoSurface centerx centery radius pixel = do |
343 | let r = fromIntegral radius | 368 | let r = fromIntegral radius |
344 | let points = map (\(x, y) -> (centerx + x, centery + y)) $ | 369 | let points = map (\(x, y) -> (centerx + x, centery + y)) $ |
@@ -346,6 +371,7 @@ _drawHexagonSDL filled videoSurface centerx centery radius pixel = do | |||
346 | map (\i -> (r * cos(pi/3 * (i)), r * sin(pi/3 * (i)))) [0 .. 5] | 371 | map (\i -> (r * cos(pi/3 * (i)), r * sin(pi/3 * (i)))) [0 .. 5] |
347 | (if not filled then SDL.Primitive.polygon else SDL.Primitive.filledPolygon) videoSurface points pixel | 372 | (if not filled then SDL.Primitive.polygon else SDL.Primitive.filledPolygon) videoSurface points pixel |
348 | 373 | ||
374 | centerText :: (Integral a, Integral a1) => SDL.Surface -> a -> a1 -> SDL.TTF.Font -> SDL.Color -> t -> String -> IO () | ||
349 | centerText videoSurface x y font fgColor bgColor text = do | 375 | centerText videoSurface x y font fgColor bgColor text = do |
350 | --fontSurface <- SDL.TTF.renderUTF8Shaded font text (SDL.Color 0 255 0) (SDL.Color 80 80 80) -- useful for testing | 376 | --fontSurface <- SDL.TTF.renderUTF8Shaded font text (SDL.Color 0 255 0) (SDL.Color 80 80 80) -- useful for testing |
351 | --fontSurface <- SDL.TTF.renderUTF8Shaded font text fgColor bgColor | 377 | --fontSurface <- SDL.TTF.renderUTF8Shaded font text fgColor bgColor |
@@ -355,12 +381,14 @@ centerText videoSurface x y font fgColor bgColor text = do | |||
355 | _ <- SDL.blitSurface fontSurface (Just fontClipRect) videoSurface (Just (SDL.Rect (fromIntegral(x) - w `div` 2) (fromIntegral(y) - h `div` 2) w h)) | 381 | _ <- SDL.blitSurface fontSurface (Just fontClipRect) videoSurface (Just (SDL.Rect (fromIntegral(x) - w `div` 2) (fromIntegral(y) - h `div` 2) w h)) |
356 | return () | 382 | return () |
357 | 383 | ||
384 | pitchIndex :: (Enum b, Num b) => b -> [Word8] | ||
358 | pitchIndex colsRepeat = concatMap (const unique) [0 .. colsRepeat - 1] | 385 | pitchIndex colsRepeat = concatMap (const unique) [0 .. colsRepeat - 1] |
359 | where | 386 | where |
360 | toprow = map (\i -> if i `mod` 2 == 0 then _AXIS_TOPLEFT_PITCH + i `div` 2 else _AXIS_TOPLEFT_PITCH - 3 + i `div` 2) [0 .. _AXIS_UNIQUE_COLS - 1] | 387 | toprow = map (\i -> if i `mod` 2 == 0 then _AXIS_TOPLEFT_PITCH + i `div` 2 else _AXIS_TOPLEFT_PITCH - 3 + i `div` 2) [0 .. _AXIS_UNIQUE_COLS - 1] |
361 | colfrom top = map ((+ top) . (* (-7))) [0 .. _AXIS_ROWS - 1] | 388 | colfrom top = map ((+ top) . (* (-7))) [0 .. _AXIS_ROWS - 1] |
362 | unique = concatMap colfrom toprow | 389 | unique = concatMap colfrom toprow |
363 | 390 | ||
391 | getKeyLocations :: (Integral a, Integral t, Integral t1, Integral t2) => a -> SDL.Rect -> (t, [(t1, t2)]) | ||
364 | getKeyLocations colsRepeat (SDL.Rect offx offy totalw totalh) = | 392 | getKeyLocations colsRepeat (SDL.Rect offx offy totalw totalh) = |
365 | let (key_height, key_width, xys) = getKeyLocationsAbs colsRepeat | 393 | let (key_height, key_width, xys) = getKeyLocationsAbs colsRepeat |
366 | 394 | ||
@@ -388,6 +416,7 @@ getKeyLocations colsRepeat (SDL.Rect offx offy totalw totalh) = | |||
388 | in | 416 | in |
389 | (floor(kw/2 * 15/16), map (\(x, y) -> (floor(scale * x + centerx + kw/2), floor(scale * y + centery + kh/2))) $ concat $ zipzip xys) | 417 | (floor(kw/2 * 15/16), map (\(x, y) -> (floor(scale * x + centerx + kw/2), floor(scale * y + centery + kh/2))) $ concat $ zipzip xys) |
390 | 418 | ||
419 | getKeyLocationsAbs :: Integral a => a -> (Double, Double, [[(Double, Double)]]) | ||
391 | getKeyLocationsAbs colsRepeat = | 420 | getKeyLocationsAbs colsRepeat = |
392 | let kb_rows = fromIntegral _AXIS_ROWS :: Double | 421 | let kb_rows = fromIntegral _AXIS_ROWS :: Double |
393 | kb_cols = fromIntegral colsRepeat * fromIntegral _AXIS_UNIQUE_COLS :: Double | 422 | kb_cols = fromIntegral colsRepeat * fromIntegral _AXIS_UNIQUE_COLS :: Double |
@@ -415,6 +444,7 @@ getKeyLocationsAbs colsRepeat = | |||
415 | (kh, kw, xys) | 444 | (kh, kw, xys) |
416 | 445 | ||
417 | -- clear a band the width of the videoClipRect and print the text within it, centered | 446 | -- clear a band the width of the videoClipRect and print the text within it, centered |
447 | textBand :: SDL.Surface -> SDL.Rect -> SDL.Rect -> SDL.TTF.Font -> [Char] -> IO () | ||
418 | textBand videoSurface videoClipRect (SDL.Rect _ y _ h) font text = do | 448 | textBand videoSurface videoClipRect (SDL.Rect _ y _ h) font text = do |
419 | let (SDL.Rect vx _ vw _) = videoClipRect | 449 | let (SDL.Rect vx _ vw _) = videoClipRect |
420 | _ <- SDL.fillRect videoSurface (Just (SDL.Rect 0 y vw h)) (SDL.Pixel 0) | 450 | _ <- SDL.fillRect videoSurface (Just (SDL.Rect 0 y vw h)) (SDL.Pixel 0) |