Codebase list raincat / f6da700
New upstream version 1.2.1 Scott Talbert 10 months ago
17 changed file(s) with 118 addition(s) and 116 deletion(s). Raw diff Collapse all Expand all
0 *.o
1 *.hi
2 dist
66 ----------------------
77 ./raincat
88
9 COMPILATION:
10 ----------------------
11 runhaskell Setup.lhs --user configure
12 runhaskell Setup.lhs build
13 runhaskell Setup.lhs install
14
15 Alternative method: cabal install Raincat
916
1017 CHANGELOG:
1118 ----------
19 Version 1.2:
20 - Ported to SDL2
1221 Version 1.1:
1322 - Changed initial item placement from click to select, click to place
1423 to drag n' drop.
2736 Runtimes for the following libraries are assumed to be installed:
2837 GLUT
2938 OpenGL
30 SDL
31 SDL_image
32 SDL_mixer
39 SDL2
40 SDL2_image
41 SDL2_mixer
3342
3443
3544 TROUBLESHOOTING:
5968 -------------------
6069 Mikhail Pobolovets - Programmer
6170 Sergei Trofimovich - Programmer
71 Raahul Kumar - Programmer
72 Alvaro F. García - Programmer
00 name: Raincat
1 version: 1.1.1.2
1 version: 1.2.1
22 cabal-version: >= 1.8
33 build-type: Simple
44 license: BSD3
2121 Sergei Trofimovich
2222
2323 stability: stable
24 tested-with: GHC==6.12.1
24 tested-with: GHC==7.6.2
2525 data-files: LICENSE README
2626 data/effects/*.png data/cat/cat-walk/*.png data/cat/cat-idle/*.png
2727 data/music/*.ogg data/levels/skyline/*.lvl data/levels/movement1/*.lvl
5454 time,
5555 GLUT,
5656 OpenGL,
57 SDL,
58 SDL-image,
59 SDL-mixer
60
57 sdl2,
58 sdl2-image,
59 sdl2-mixer
6160 other-modules:
6261 Cat.Cat
6362 Error.Error
7675 Menu.PostVictory
7776 Nxt.Audio
7877 Nxt.Graphics
79 Nxt.Input
8078 Nxt.Types
8179 Panels.ItemPanel
8280 Panels.MainPanel
8381 Panels.MessagePanel
82 Paths_Raincat
8483 Program.Program
8584 Rain.Rain
8685 Settings.CatSettings
8988 Settings.RainSettings
9089 Settings.UISettings
9190 Settings.WorldSettings
92 UI.ItemPanel
9391 World.World
(No changes)
134134 updateCatVel c@(Cat (catPosX, catPosY) _ catDir _ _ _ _) (newVelX, newVelY) =
135135 c {catPos = (catPosX + newVelX, catPosY + newVelY), catVelocity = (newVelX, newVelY),
136136 catDirection = newDir}
137 where newDir = if newVelX < 0.0
138 then DirLeft
139 else if newVelX > 0.0
140 then DirRight
141 else catDir
137 where newDir
138 | newVelX < 0.0 = DirLeft
139 | newVelX > 0.0 = DirRight
140 | otherwise = catDir
142141
143142 -- updateCatPos
144143 updateCatPos :: Cat -> Nxt.Types.Vector2d -> Cat
11 (gameDraw) where
22
33 import Data.Maybe
4 import Data.Foldable (forM_)
45 import Graphics.UI.GLUT as Glut
56 import Data.IORef
67 import World.World
9394 -- drawItems
9495 drawItems :: WorldState -> IO ()
9596 drawItems worldState = do
96 let itemlist = (MainPanel.itemList (mainPanel worldState))
97 corklist = (MainPanel.corkList (mainPanel worldState))
98 tarplist = (MainPanel.tarpList (mainPanel worldState))
97 let itemlist = MainPanel.itemList (mainPanel worldState)
98 corklist = MainPanel.corkList (mainPanel worldState)
99 tarplist = MainPanel.tarpList (mainPanel worldState)
99100
100101 mapM_ drawItem itemlist
101102 mapM_ drawItem corklist
107108 let (mousex, mousey) = translateMousePos mousePos winW winH
108109
109110 let placingItem' = MainPanel.placingItem $ mainPanel worldState
110 (when (isJust placingItem') $
111 drawItemAt (mousex - cameraX) (mousey - cameraY) (fromJust placingItem'))
111 forM_ placingItem'
112 (drawItemAt (mousex - cameraX) (mousey - cameraY))
112113
113114 -- drawPanels
114115 drawPanels :: WorldState -> IO ()
128129
129130 -- message panel: message
130131 let messagePanelStr = messageDisplay (messagePanel worldState)
131 (when (messagePanelStr /= "") $
132 when (messagePanelStr /= "") $
132133 sequence_
133134 [drawRect UISettings.messagePanelRect UISettings.messagePanelColor,
134 drawString 80.0 739.0 messagePanelStr (Color4 0.0 0.0 0.0 1.0)])
135 drawString 80.0 739.0 messagePanelStr (Color4 0.0 0.0 0.0 1.0)]
135136
136137 -- drawDebug
137138 {-
7878
7979 -- quit key
8080 keyboardAct _ (Char 'q') Down =
81 exitWith ExitSuccess
81 exitSuccess
8282
8383 -- left mouse button
8484 keyboardAct keysStateRef (MouseButton LeftButton) Down = do
4747
4848 -- update camera pos
4949 let (cameraX, cameraY) = cameraPos $ mainPanel worldState
50 cameraX' = if leftKeyDown keys' && cameraX < 0.0
51 then cameraX + WorldSettings.cameraSpeed
52 else
53 if rightKeyDown keys' && cameraX > -(fromIntegral $ levelWidth lvl :: Double) + fromGLdouble screenResWidth
54 then cameraX - WorldSettings.cameraSpeed
55 else cameraX
56 cameraY' = if upKeyDown keys' && cameraY > 0.0
57 then cameraY - WorldSettings.cameraSpeed
58 else
59 if downKeyDown keys' && cameraY < (fromIntegral $ levelHeight lvl :: Double) - fromGLdouble screenResHeight
60 then cameraY + WorldSettings.cameraSpeed
61 else cameraY
62
50 cameraX'
51 | leftKeyDown keys' && cameraX < 0.0 =
52 cameraX + WorldSettings.cameraSpeed
53 | rightKeyDown keys' &&
54 cameraX >
55 (-(fromIntegral $ levelWidth lvl :: Double)) +
56 fromGLdouble screenResWidth
57 = cameraX - WorldSettings.cameraSpeed
58 | otherwise = cameraX
59 cameraY'
60 | upKeyDown keys' && cameraY > 0.0 =
61 cameraY - WorldSettings.cameraSpeed
62 | downKeyDown keys' &&
63 cameraY <
64 (fromIntegral $ levelHeight lvl :: Double) -
65 fromGLdouble screenResHeight
66 = cameraY + WorldSettings.cameraSpeed
67 | otherwise = cameraY
6368 -- update rain
6469 rain' <- updateRain worldState
6570
6671 -- update go/stop state
67 let goStopState' = if catItemName c == "Hurt" && isJust (catItemDuration c) && fromJust (catItemDuration c) == 1
72 let goStopState' = if catItemName c == "Hurt" && (catItemDuration c == Just 1)
6873 then GoState
6974 else goStopState $ goStopButton $ itemPanel worldState
7075 where c = cat mainpanel
116121 -- update fire hydrants
117122 let _ = if catItemName cat' == "Wrench"
118123 then foldr (\fh fhList -> if rectIntersect (catHitbox cat') (fireHydrantRect fh)
119 then case (fireHydrantDir fh) of
124 then case fireHydrantDir fh of
120125 DirLeft -> if fst (catPos cat') > (rectX (fireHydrantRect fh) + rectWidth (fireHydrantRect fh))
121126 then (fh {fireHydrantDisabled = True}):fhList
122127 else fh:fhList
129134 let fireHydrants' = updateFireHydrants goStopState' cat' worldState
130135
131136 -- update game state (menu, post victory)
132 let gameState' = if escKeyDown keys'
133 then MainMenuState
134 else if catItemName cat' == "Win" && isJust (catItemDuration cat') && fromJust (catItemDuration cat') == 1
135 then PostVictoryState
136 else GameRunningState
137 let gameState'
138 | escKeyDown keys' = MainMenuState
139 | catItemName cat' == "Win" && (catItemDuration cat' == Just 1) =
140 PostVictoryState
141 | otherwise = GameRunningState
137142
138143 -- update panels
139144 let mainPanel' = mainpanel {cameraPos = (cameraX', cameraY'), raindrops = rain', cat = cat', curItem = item',
163168 updateFireHydrants StopState theCat worldState =
164169 let fireHydrantsL = if catItemName theCat == "Wrench"
165170 then foldr (\fh fhList -> if rectIntersect (catHitbox theCat) (fireHydrantRect fh)
166 then case (fireHydrantDir fh) of
171 then case fireHydrantDir fh of
167172 DirLeft -> if fst (catPos theCat) > (rectX (fireHydrantRect fh) + rectWidth (fireHydrantRect fh))
168173 then (fh {fireHydrantDisabled = True}):fhList
169174 else fh:fhList
228233 else countValid) True itemButList
229234
230235 let placeItem = forceItemEval && lMousePrevDown keys && not (lMouseDown keys) && not curItemIntersects && mousex < maxWorldX && itemName item' /= "Eraser" && itemCountValid && isJust (placingItem mainpanel)
231 let placingItem' = if placeItem || not (lMouseDown keys)
232 then Nothing
233 else if lMouseDown keys && itemName item' /= "Eraser" && itemCountValid
234 then if isJust (placingItem mainpanel)
235 then placingItem mainpanel
236 else Just item'
237 else Nothing
236 let placingItem'
237 | placeItem || not (lMouseDown keys) = Nothing
238 | lMouseDown keys && itemName item' /= "Eraser" && itemCountValid =
239 if isJust (placingItem mainpanel) then placingItem mainpanel else
240 Just item'
241 | otherwise = Nothing
238242
239243 -- placing new item in world
240244 let (itemList', corkList', tarpList') = if placeItem
241 then case (itemName item') of
245 then case itemName item' of
242246 "Cork" -> (itemListE, item':corkListE, tarpListE)
243247 "Tarp" -> (itemListE, corkListE, item':tarpListE)
244248 "Eraser" -> (itemListE, corkListE, tarpListE)
307311
308312 -- gravity
309313 (velXg, velYg) <- get
310 put (if catitemname /= "UpsUmbrellaActive" && catitemname /= "Hurt" && catitemname /= "Win"
314 put (if catitemname `notElem` ["UpsUmbrellaActive", "Hurt", "Win"]
311315 then (velXg, velYg + gravity)
312316 else (velXg, velYg))
313317
364368
365369 catWetFromFireHydrant = isJust catTouchedFireHydrant &&
366370 let fh = fromJust catTouchedFireHydrant
367 in if fireHydrantDisabled fh || catitemname == "Shield"
368 then False
369 else case fireHydrantDir fh of
371 in (not (fireHydrantDisabled fh || catitemname == "Shield") &&
372 (case fireHydrantDir fh of
370373 DirLeft -> if catitemname == "Poncho"
371374 then case catdirection of
372375 DirLeft -> False
376379 then case catdirection of
377380 DirRight -> False
378381 _ -> rectX catrect + rectWidth catrect < rectX (fireHydrantRect fh) + rectWidth (fireHydrantRect fh)
379 else rectX catrect + rectWidth catrect > rectX (fireHydrantRect fh) + 100
382 else rectX catrect + rectWidth catrect > rectX (fireHydrantRect fh) + 100))
380383
381384 catIsWet = catWetFromPuddle || catWetFromRain || catWetFromFireHydrant
382385
483486 catRectResponse (catX, catY) (catVelX, catVelY) catDir (Rect catRX catRY catRW catRH) (Rect rectx recty rectwidth rectheight) =
484487 let displaceY = (recty + rectheight) - catY
485488 displaceDownY = (recty + rectheight) - (catRY + catRH)
486 displaceX = if catVelX < 0.0
487 then (rectx + rectwidth) - catRX
488 else if catVelX > 0.0
489 then rectx - (catRX + catRW)
490 else 0.0
489 displaceX
490 | catVelX < 0.0 = (rectx + rectwidth) - catRX
491 | catVelX > 0.0 = rectx - (catRX + catRW)
492 | otherwise = 0.0
491493 oppDir = case catDir of
492494 DirLeft -> DirRight
493495 DirRight -> DirLeft
4646 translateMousePos (MousePos x y) winW winH =
4747 let x' = fromIntegral x
4848 sW' = fromGLdouble screenResWidth :: Double
49 wW' = (fromIntegral (fromGLsizei winW))
49 wW' = fromIntegral (fromGLsizei winW)
5050 y' = fromIntegral y
5151 sH' = fromGLdouble screenResHeight :: Double
52 wH' = (fromIntegral (fromGLsizei winH))
52 wH' = fromIntegral (fromGLsizei winH)
5353 in (x' * (sW' / wW'),
5454 sH' - ((sH' - y') * (sH' / wH')))
5555
5959 -- Hair Dryer
6060 hairDryerEffect :: Cat -> Cat
6161 hairDryerEffect cat =
62 let (velX, velY) = (catVelocity cat)
62 let (velX, velY) = catVelocity cat
6363 in updateCatVel cat (-velX, velY)
6464
6565 -- Speed Boots
6868 let speedBootsTex = speedBootsTextures $ catAnimations cat
6969 vel = (case catDirection cat of
7070 DirRight -> CatSettings.catSpeedVelX
71 DirLeft -> (-CatSettings.catSpeedVelX),
71 DirLeft -> -CatSettings.catSpeedVelX,
7272 snd $ catVelocity cat)
7373 in updateCatVel (cat {catTexture = speedBootsTex, catItemName = "SpeedBoots",
7474 catItemDuration = Just CatSettings.catSpeedDuration}) vel
129129 let skateboardTex = skateboardTextures $ catAnimations cat
130130 vel = (case catDirection cat of
131131 DirRight -> CatSettings.catSkateVelX
132 DirLeft -> (-CatSettings.catSkateVelX),
133 snd (catVelocity cat))
132 -- DirLeft -> (-CatSettings.catSkateVelX),
133 -- snd (catVelocity cat))
134 DirLeft -> -CatSettings.catSkateVelX,snd (catVelocity cat))
134135 in updateCatVel (cat {catTexture = skateboardTex, catItemName = "Skateboard",
135136 catItemDuration = Just CatSettings.catSkateDuration}) vel
136137
2727
2828 mainLoop
2929
30 exitWith ExitSuccess
30 exitSuccess
3030 else c
3131 cat' = updateCatItemDuration $ updateCatAnim catLaser
3232
33 let gameState' = if catPos cat' == (540.0, 340.0) && isJust (catItemDuration cat') && fromJust (catItemDuration cat') == 1
33 let gameState' = if catPos cat' == (540.0, 340.0) && (catItemDuration cat' == Just 1)
3434 then MainMenuState
3535 else PostVictoryState
3636
33 loadMusic,
44 playMusic) where
55
6 import qualified Graphics.UI.SDL.Mixer.General as SDL.Mixer
7 import qualified Graphics.UI.SDL.Mixer.Music as SDL.Mixer.Music
8 import qualified Graphics.UI.SDL.Mixer.Types as SDL.Mixer.Types
6 import qualified SDL.Mixer
97
10 type Music = SDL.Mixer.Types.Music
8 type Music = SDL.Mixer.Music
119
1210 -- initAudio
1311 initAudio :: IO ()
14 initAudio = SDL.Mixer.openAudio 44100 SDL.Mixer.AudioS16Sys 2 4096
12 initAudio =
13 let audio = SDL.Mixer.Audio
14 { SDL.Mixer.audioFrequency = 44100
15 , SDL.Mixer.audioFormat = SDL.Mixer.FormatS16_Sys
16 , SDL.Mixer.audioOutput = SDL.Mixer.Stereo }
17 in SDL.Mixer.openAudio audio 4096
1518
1619 -- loadMusic
1720 loadMusic :: String -> IO Music
18 loadMusic = SDL.Mixer.Music.loadMUS
21 loadMusic = SDL.Mixer.load
1922
2023 -- playMusic
2124 playMusic :: Music -> IO ()
2225 playMusic m = do
23 SDL.Mixer.Music.setMusicVolume 50
24 SDL.Mixer.Music.playMusic m (-1)
26 SDL.Mixer.setMusicVolume 50
27 SDL.Mixer.playMusic SDL.Mixer.Forever m
2528
0 {-# LANGUAGE CPP #-}
01 module Nxt.Graphics
12 (begin,
23 end,
1920 import Control.Monad
2021 import Graphics.UI.GLUT as GLUT hiding (windowSize, windowTitle)
2122 import Graphics.Rendering.OpenGL as GL
22 import Graphics.UI.SDL.Image as SDLImage
23 import Graphics.UI.SDL.Types
24 import Graphics.UI.SDL.Video
23 import qualified SDL.Image as SDLImage hiding (loadTexture)
24 import qualified SDL.Vect
25 import qualified SDL.Video
2526 import Nxt.Types hiding (rectX, rectY, rectWidth, rectHeight)
2627 import Unsafe.Coerce
2728
7374 -- loadTexture (only specified to load PNGs)
7475 loadTexture :: String -> IO Nxt.Types.Texture
7576 loadTexture textureFilePath = do
76 surface <- SDLImage.loadTyped textureFilePath SDLImage.PNG
77
78 let width = fromIntegral (surfaceGetWidth surface)
79 let height = fromIntegral (surfaceGetHeight surface)
77 surface <- SDLImage.load textureFilePath
78
79 SDL.Vect.V2 rawWidth rawHeight <- SDL.Video.surfaceDimensions surface
80 let width = fromIntegral rawWidth
81 let height = fromIntegral rawHeight
8082 let surfaceSize = TextureSize2D width height
8183
8284 textureObj <- liftM head (genObjectNames 1)
8486 textureWrapMode Texture2D S $= (Repeated, Repeat)
8587 textureWrapMode Texture2D T $= (Repeated, Repeat)
8688 textureFilter Texture2D $= ((Nearest, Nothing), Nearest)
87 surfacePixels <- surfaceGetPixels surface
89 surfacePixels <- SDL.Video.surfacePixels surface
8890
8991 let pixelData = PixelData RGBA UnsignedByte surfacePixels
90 texImage2D Nothing NoProxy 0 RGBA' surfaceSize 0 pixelData
91
92 freeSurface surface
92 texImage2D
93 #if MIN_VERSION_OpenGL(2,9,0)
94 Texture2D
95 #else
96 Nothing
97 #endif
98 NoProxy 0 RGBA' surfaceSize 0 pixelData
99
100 SDL.Video.freeSurface surface
93101
94102 return (Nxt.Types.Texture width height textureObj)
95103
+0
-13
src/Nxt/Input.hs less more
0 module Nxt.Input
1 (InputState) where
2
3
4
5 data InputState = InputState
6 {
7 up :: Bool,
8 left :: Bool,
9 down :: Bool,
10 right :: Bool
11 }
12
+0
-11
src/UI/ItemPanel.hs less more
0 module UI.ItemPanel
1 (ItemPanel(ItemPanel),
2 itemButtonList) where
3
4 import Item.Items
5
6 data ItemPanel = ItemPanel
7 {
8 itemButtonlist :: [ItemButton]
9 }
10
118118 -- free previous level's textures
119119 -- mapM_ (\(_, oldBg) -> freeTexture oldBg) (levelBackgrounds lvlData)
120120
121 let lvlPos = case (drop (length dataPath) levelPath) of
121 let lvlPos = case drop (length dataPath) levelPath of
122122 "/data/levels/water1/water1.lvl" -> [(0.0, 0.0), (1024.0, 0.0)]
123123 "/data/levels/movement1/movement1.lvl" -> [(-15.0, -265.0), (1009.0, -265.0), (2033, -265.0)]
124124 "/data/levels/water2/water2.lvl" -> [(0.0, -200.0), (1024.0, -200.0)]
131131 "/data/levels/pinball/pinball.lvl" -> [(110.0, -330.0), (1134.0, -330.0)]
132132 _ -> []
133133
134 lvlBgs <- case (drop (length dataPath) levelPath) of
134 lvlBgs <- case drop (length dataPath) levelPath of
135135 "/data/levels/water1/water1.lvl" -> sequence [Nxt.Graphics.loadTexture (dataPath ++ "/data/levels/water1/water1_0_0.png"),
136136 Nxt.Graphics.loadTexture (dataPath ++ "/data/levels/water1/water1_1_0.png")]
137137 "/data/levels/movement1/movement1.lvl" -> sequence [Nxt.Graphics.loadTexture (dataPath ++ "/data/levels/movement1/movement1_0_0.png"),