1 /************************************************************************************
2 
3 	AstroMenace
4 	Hardcore 3D space scroll-shooter with spaceship upgrade possibilities.
5 	Copyright (c) 2006-2019 Mikhail Kurinnoi, Viewizard
6 
7 
8 	AstroMenace is free software: you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation, either version 3 of the License, or
11 	(at your option) any later version.
12 
13 	AstroMenace is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with AstroMenace. If not, see <https://www.gnu.org/licenses/>.
20 
21 
22 	Website: https://viewizard.com/
23 	Project: https://github.com/viewizard/astromenace
24 	E-mail: viewizard@viewizard.com
25 
26 *************************************************************************************/
27 
28 // TODO move to SDL_GetTicks() usage
29 
30 /*
31 
32 Note, this code should not interact with mouse, caller should
33 care about all mouse interaction.
34 This code should care about cursor draw only, that mean cursor
35 itself and drag object (if drag and drop are used).
36 
37 */
38 
39 #include "cursor.h"
40 #include "../assets/texture.h"
41 
42 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
43 namespace viewizard {
44 namespace astromenace {
45 
46 namespace {
47 
48 bool ShowGameCursorStatus{true};
49 
50 eCursorStatus CursorStatus{eCursorStatus::Undefined};
51 float CursorBlinking{1.0f};
52 float CursorBlinkingLastTime{0.0f};
53 
54 GLtexture CursorFront{0};
55 GLtexture CursorShadow{0};
56 GLtexture DraggingItemIcon{0};
57 
58 } // unnamed namespace
59 
60 
61 /*
62  * Cursor initialization.
63  * Should be called after vw_InitTimeThread(0) and LoadAllGameAssets().
64  */
CursorInit(bool ShowSystemCursor)65 void CursorInit(bool ShowSystemCursor)
66 {
67 	if (!ShowSystemCursor)
68 		SDL_ShowCursor(SDL_DISABLE);
69 
70 	CursorBlinkingLastTime = vw_GetTimeThread(0);
71 
72 	CursorFront = GetPreloadedTextureAsset("menu/cursor.tga");
73 	CursorShadow = GetPreloadedTextureAsset("menu/cursor_shadow.tga");
74 }
75 
76 /*
77  * Release cursor.
78  */
CursorRelease()79 void CursorRelease()
80 {
81 	if (SDL_ShowCursor(SDL_QUERY) == SDL_DISABLE)
82 		SDL_ShowCursor(SDL_ENABLE);
83 }
84 
85 /*
86  * Update cursor.
87  */
CursorUpdate()88 void CursorUpdate()
89 {
90 	SetCursorStatus(eCursorStatus::Undefined);
91 
92 	CursorBlinking -= vw_GetTimeThread(0) - CursorBlinkingLastTime;
93 	if (CursorBlinking < 0.3f)
94 		CursorBlinking = 1.0f;
95 	CursorBlinkingLastTime = vw_GetTimeThread(0);
96 }
97 
98 /*
99  * Draw dragging item icon.
100  */
DrawDraggingItemIcon(int X,int Y)101 static void DrawDraggingItemIcon(int X, int Y)
102 {
103 	if (!DraggingItemIcon)
104 		return;
105 
106 	// we use "fixed" icon size for now
107 	constexpr int IconWidth{128};
108 	constexpr int IconHeight{64};
109 
110 	sRECT SrcRect(0, 0, IconWidth, IconHeight);
111 	sRECT DstRect(X - IconWidth / 2, Y - IconHeight / 2,
112 		      X + IconWidth / 2, Y + IconHeight / 2);
113 
114 	vw_Draw2D(DstRect, SrcRect, DraggingItemIcon, true);
115 }
116 
117 /*
118  * Draw cursor.
119  */
CursorDraw()120 void CursorDraw()
121 {
122 	if (!ShowGameCursorStatus)
123 		return;
124 
125 	int MouseX, MouseY;
126 	vw_GetMousePos(MouseX, MouseY);
127 
128 	sRECT SrcRect(0, 0, 64, 64);
129 	sRECT DstRect(MouseX-12, MouseY-13, MouseX+64-12, MouseY+64-13);
130 
131 	switch (CursorStatus) {
132 	case eCursorStatus::Undefined:
133 		vw_Draw2D(DstRect, SrcRect, CursorShadow, true);
134 		vw_Draw2D(DstRect, SrcRect, CursorFront, true, 0.80f, 0.0f, sRGBCOLOR{0.8f, 0.7f, 0.0f});
135 		break;
136 
137 	case eCursorStatus::ActionAllowed:
138 		vw_Draw2D(DstRect, SrcRect, CursorShadow, true);
139 		vw_Draw2D(DstRect, SrcRect, CursorFront, true, CursorBlinking, 0.0f, sRGBCOLOR{eRGBCOLOR::green});
140 		break;
141 
142 	case eCursorStatus::ActionProhibited:
143 		vw_Draw2D(DstRect, SrcRect, CursorShadow, true);
144 		vw_Draw2D(DstRect, SrcRect, CursorFront, true, CursorBlinking, 0.0f, sRGBCOLOR{1.0f, 0.2f, 0.0f});
145 		break;
146 
147 	case eCursorStatus::DraggingItem:
148 		DrawDraggingItemIcon(MouseX, MouseY);
149 		vw_Draw2D(DstRect, SrcRect, CursorShadow, true);
150 		vw_Draw2D(DstRect, SrcRect, CursorFront, true, 0.80f, 0.0f, sRGBCOLOR{eRGBCOLOR::green});
151 		break;
152 	}
153 }
154 
155 /*
156  * Set cursor status.
157  */
SetCursorStatus(eCursorStatus Status)158 void SetCursorStatus(eCursorStatus Status)
159 {
160 	CursorStatus = Status;
161 }
162 
163 /*
164  * Get cursor status.
165  */
GetCursorStatus()166 eCursorStatus GetCursorStatus()
167 {
168 	return CursorStatus;
169 }
170 
171 /*
172  * Set cursor dragging item icon texture.
173  */
SetCursorDraggingItemIcon(GLtexture Icon)174 void SetCursorDraggingItemIcon(GLtexture Icon)
175 {
176 	DraggingItemIcon = Icon;
177 }
178 
179 /*
180  * Тoggle whether or not the cursor is shown.
181  */
SetShowGameCursor(bool Toggle)182 void SetShowGameCursor(bool Toggle)
183 {
184 	ShowGameCursorStatus = Toggle;
185 }
186 
187 /*
188  * Get is cursor shown or not.
189  */
GetShowGameCursor()190 bool GetShowGameCursor()
191 {
192 	return ShowGameCursorStatus;
193 }
194 
195 } // astromenace namespace
196 } // viewizard namespace
197