22 #include "C4Version.h"
30 static void sdlToC4MCBtn(
const SDL_MouseButtonEvent &e, int32_t& button,
DWORD& flags)
33 flags = SDL_GetModState();
38 if (e.state == SDL_PRESSED)
43 case SDL_BUTTON_RIGHT:
44 if (e.state == SDL_PRESSED)
49 case SDL_BUTTON_MIDDLE:
50 if (e.state == SDL_PRESSED)
56 if (e.state == SDL_PRESSED)
62 if (e.state == SDL_PRESSED)
73 Active(false), pWindow(nullptr), fQuitMsgReceived(false),
76 MainThread (pthread_self()),
92 if (SDL_Init(SDL_INIT_VIDEO) != 0)
94 LogF(
"SDL_Init: %s", SDL_GetError());
101 return DoInit (argc, argv);
123 while (SDL_PollEvent(&event))
125 HandleSDLEvent(event);
130 #define SDL_SCANCODE_KEYCODE \
131 X(SDL_SCANCODE_LSHIFT, K_SHIFT_L) \
132 X(SDL_SCANCODE_RSHIFT, K_SHIFT_R) \
133 X(SDL_SCANCODE_LCTRL, K_CONTROL_L) \
134 X(SDL_SCANCODE_RCTRL, K_CONTROL_R) \
135 X(SDL_SCANCODE_LALT, K_ALT_L) \
136 X(SDL_SCANCODE_RALT, K_ALT_R) \
137 X(SDL_SCANCODE_F1, K_F1) \
138 X(SDL_SCANCODE_F2, K_F2) \
139 X(SDL_SCANCODE_F3, K_F3) \
140 X(SDL_SCANCODE_F4, K_F4) \
141 X(SDL_SCANCODE_F5, K_F5) \
142 X(SDL_SCANCODE_F6, K_F6) \
143 X(SDL_SCANCODE_F7, K_F7) \
144 X(SDL_SCANCODE_F8, K_F8) \
145 X(SDL_SCANCODE_F9, K_F9) \
146 X(SDL_SCANCODE_F10, K_F10) \
147 X(SDL_SCANCODE_F11, K_F11) \
148 X(SDL_SCANCODE_F12, K_F12) \
149 X(SDL_SCANCODE_KP_PLUS, K_ADD) \
150 X(SDL_SCANCODE_KP_MINUS, K_SUBTRACT) \
151 X(SDL_SCANCODE_KP_MULTIPLY, K_MULTIPLY) \
152 X(SDL_SCANCODE_ESCAPE, K_ESCAPE) \
153 X(SDL_SCANCODE_PAUSE, K_PAUSE) \
154 X(SDL_SCANCODE_TAB, K_TAB) \
155 X(SDL_SCANCODE_RETURN, K_RETURN) \
156 X(SDL_SCANCODE_DELETE, K_DELETE) \
157 X(SDL_SCANCODE_INSERT, K_INSERT) \
158 X(SDL_SCANCODE_BACKSPACE, K_BACK) \
159 X(SDL_SCANCODE_SPACE, K_SPACE) \
160 X(SDL_SCANCODE_UP, K_UP) \
161 X(SDL_SCANCODE_DOWN, K_DOWN) \
162 X(SDL_SCANCODE_LEFT, K_LEFT) \
163 X(SDL_SCANCODE_RIGHT, K_RIGHT) \
164 X(SDL_SCANCODE_HOME, K_HOME) \
165 X(SDL_SCANCODE_END, K_END) \
166 X(SDL_SCANCODE_SCROLLLOCK, K_SCROLL) \
167 X(SDL_SCANCODE_MENU, K_MENU) \
168 X(SDL_SCANCODE_PAGEUP, K_PAGEUP) \
169 X(SDL_SCANCODE_PAGEDOWN, K_PAGEDOWN) \
170 X(SDL_SCANCODE_1, K_1) \
171 X(SDL_SCANCODE_2, K_2) \
172 X(SDL_SCANCODE_3, K_3) \
173 X(SDL_SCANCODE_4, K_4) \
174 X(SDL_SCANCODE_5, K_5) \
175 X(SDL_SCANCODE_6, K_6) \
176 X(SDL_SCANCODE_7, K_7) \
177 X(SDL_SCANCODE_8, K_8) \
178 X(SDL_SCANCODE_9, K_9) \
179 X(SDL_SCANCODE_0, K_0) \
180 X(SDL_SCANCODE_A, K_A) \
181 X(SDL_SCANCODE_B, K_B) \
182 X(SDL_SCANCODE_C, K_C) \
183 X(SDL_SCANCODE_D, K_D) \
184 X(SDL_SCANCODE_E, K_E) \
185 X(SDL_SCANCODE_F, K_F) \
186 X(SDL_SCANCODE_G, K_G) \
187 X(SDL_SCANCODE_H, K_H) \
188 X(SDL_SCANCODE_I, K_I) \
189 X(SDL_SCANCODE_J, K_J) \
190 X(SDL_SCANCODE_K, K_K) \
191 X(SDL_SCANCODE_L, K_L) \
192 X(SDL_SCANCODE_M, K_M) \
193 X(SDL_SCANCODE_N, K_N) \
194 X(SDL_SCANCODE_O, K_O) \
195 X(SDL_SCANCODE_P, K_P) \
196 X(SDL_SCANCODE_Q, K_Q) \
197 X(SDL_SCANCODE_R, K_R) \
198 X(SDL_SCANCODE_S, K_S) \
199 X(SDL_SCANCODE_T, K_T) \
200 X(SDL_SCANCODE_U, K_U) \
201 X(SDL_SCANCODE_V, K_V) \
202 X(SDL_SCANCODE_W, K_W) \
203 X(SDL_SCANCODE_X, K_X) \
204 X(SDL_SCANCODE_Y, K_Y) \
205 X(SDL_SCANCODE_Z, K_Z) \
206 X(SDL_SCANCODE_MINUS, K_MINUS) \
207 X(SDL_SCANCODE_EQUALS, K_EQUAL) \
208 X(SDL_SCANCODE_LEFTBRACKET, K_LEFT_BRACKET) \
209 X(SDL_SCANCODE_RIGHTBRACKET, K_RIGHT_BRACKET) \
210 X(SDL_SCANCODE_SEMICOLON, K_SEMICOLON) \
211 X(SDL_SCANCODE_APOSTROPHE, K_APOSTROPHE) \
212 X(SDL_SCANCODE_GRAVE, K_GRAVE_ACCENT) \
213 X(SDL_SCANCODE_BACKSLASH, K_BACKSLASH) \
214 X(SDL_SCANCODE_COMMA, K_COMMA) \
215 X(SDL_SCANCODE_PERIOD, K_PERIOD) \
216 X(SDL_SCANCODE_SLASH, K_SLASH) \
217 X(SDL_SCANCODE_CAPSLOCK, K_CAPS) \
218 X(SDL_SCANCODE_NUMLOCKCLEAR, K_NUM) \
219 X(SDL_SCANCODE_KP_7, K_NUM7) \
220 X(SDL_SCANCODE_KP_8, K_NUM8) \
221 X(SDL_SCANCODE_KP_9, K_NUM9) \
222 X(SDL_SCANCODE_KP_4, K_NUM4) \
223 X(SDL_SCANCODE_KP_5, K_NUM5) \
224 X(SDL_SCANCODE_KP_6, K_NUM6) \
225 X(SDL_SCANCODE_KP_1, K_NUM1) \
226 X(SDL_SCANCODE_KP_2, K_NUM2) \
227 X(SDL_SCANCODE_KP_3, K_NUM3) \
228 X(SDL_SCANCODE_KP_0, K_NUM0) \
229 X(SDL_SCANCODE_KP_PERIOD, K_DECIMAL) \
230 X(SDL_SCANCODE_NONUSBACKSLASH, K_86) \
231 X(SDL_SCANCODE_KP_ENTER, K_NUM_RETURN) \
232 X(SDL_SCANCODE_KP_DIVIDE, K_DIVIDE) \
233 X(SDL_SCANCODE_LGUI, K_WIN_L) \
234 X(SDL_SCANCODE_RGUI, K_WIN_R) \
235 X(SDL_SCANCODE_PRINTSCREEN, K_PRINT) \
237 static C4KeyCode sdl_scancode_to_keycode(SDL_Scancode scancode)
241 #define X(sdl, oc) case sdl: return oc;
250 SDL_Scancode scancode;
253 #define X(sdl, oc) case oc: scancode = sdl; break;
259 return SDL_GetScancodeName(scancode);
262 void C4AbstractApp::HandleSDLEvent(SDL_Event& e)
277 e.key.keysym.mod & (KMOD_LALT | KMOD_RALT),
278 e.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL),
279 e.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT),
280 e.key.repeat > 0,
nullptr);
285 e.key.keysym.mod & (KMOD_LALT | KMOD_RALT),
286 e.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL),
287 e.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT),
false,
nullptr);
289 case SDL_MOUSEMOTION:
292 case SDL_MOUSEBUTTONUP:
293 case SDL_MOUSEBUTTONDOWN:
295 sdlToC4MCBtn(e.button, button, flags);
299 flags = e.wheel.y > 0 ? (+32) << 16 : (
DWORD) (-32) << 16;
300 flags += SDL_GetModState();
302 SDL_GetMouseState(&x, &y);
305 case SDL_CONTROLLERAXISMOTION:
306 case SDL_CONTROLLERBUTTONDOWN:
307 case SDL_CONTROLLERBUTTONUP:
310 case SDL_JOYDEVICEADDED:
311 case SDL_CONTROLLERDEVICEADDED:
312 case SDL_CONTROLLERDEVICEREMOVED:
315 case SDL_WINDOWEVENT:
317 auto window =
static_cast<C4Window*
>(SDL_GetWindowData(SDL_GetWindowFromID(e.window.windowID),
"C4Window"));
318 window->HandleSDLEvent(e.window);
323 static int modeCount = 0;
325 static int bits_per_pixel(
int format)
330 int bbp = SDL_BITSPERPIXEL(format);
331 if (bbp == 24) bbp = 32;
339 modeCount = SDL_GetNumDisplayModes(iMonitor);
342 if (iIndex >= modeCount)
345 SDL_DisplayMode mode;
346 SDL_GetDisplayMode(iMonitor, iIndex, &mode);
349 *piBitDepth = bits_per_pixel(mode.format);
350 if (piRefreshRate) *piRefreshRate = mode.refresh_rate;
361 SDL_DisplayMode desktop_mode;
362 res = SDL_GetDesktopDisplayMode(iMonitor, &desktop_mode);
365 Error(SDL_GetError());
366 LogF(
"SDL_GetDesktopDisplayMode: %s", SDL_GetError());
370 iXRes = desktop_mode.w;
371 iYRes = desktop_mode.h;
374 res = SDL_SetWindowFullscreen(
pWindow->window, 0);
377 Error(SDL_GetError());
378 LogF(
"SDL_SetWindowFullscreen: %s", SDL_GetError());
386 SDL_DisplayMode mode;
387 if (iXRes < 0 || iYRes < 0)
389 res = SDL_SetWindowFullscreen(
pWindow->window, SDL_WINDOW_FULLSCREEN_DESKTOP);
392 Error(SDL_GetError());
393 LogF(
"SDL_SetWindowFullscreen: %s", SDL_GetError());
396 res = SDL_GetDesktopDisplayMode(iMonitor, &mode);
399 Error(SDL_GetError());
400 LogF(
"SDL_GetDesktopDisplayMode: %s", SDL_GetError());
407 for (
int i = 0; i < modeCount; ++i)
409 res = SDL_GetDisplayMode(iMonitor, i, &mode);
413 Error(SDL_GetError());
414 LogF(
"SDL_GetDisplayMode: %s", SDL_GetError());
418 if (mode.w == iXRes && mode.h == iYRes && (RefreshRate == 0 || mode.refresh_rate == RefreshRate) && bits_per_pixel(mode.format) ==
C4Draw::COLOR_DEPTH)
420 res = SDL_SetWindowDisplayMode(
pWindow->window, &mode);
423 Error(SDL_GetError());
424 LogF(
"SDL_SetWindowDisplayMode: %s", SDL_GetError());
427 res = SDL_SetWindowFullscreen(
pWindow->window, SDL_WINDOW_FULLSCREEN);
430 Error(SDL_GetError());
431 LogF(
"SDL_SetWindowFullscreen: %s", SDL_GetError());
439 Error(
"No such resolution available");
446 SDL_SetWindowFullscreen(
pWindow->window, 0);
451 return SDL_SetClipboardText(
text.c_str()) == 0;
456 char *
text = SDL_GetClipboardText();
457 std::string buf(
text);
464 return SDL_HasClipboardText();
469 SDL_ShowSimpleMessageBox(0, C4ENGINECAPTION, message,
pWindow ?
pWindow->window :
nullptr);
#define SDL_SCANCODE_KEYCODE
const char * KeycodeToString(C4KeyCode code)
C4Application Application
bool LogF(const char *strMessage,...)
const int32_t C4MC_Button_X1Double
const int32_t C4MC_Button_X2Up
const int32_t C4MC_Button_None
const int32_t C4MC_Button_RightDown
const int32_t C4MC_Button_MiddleUp
const int32_t C4MC_Button_RightUp
const int32_t C4MC_Button_MiddleDouble
const int32_t C4MC_Button_X1Up
const int32_t C4MC_Button_MiddleDown
const int32_t C4MC_Button_RightDouble
const int32_t C4MC_Button_LeftUp
const int32_t C4MC_Button_X1Down
const int32_t C4MC_Button_LeftDown
const int32_t C4MC_Button_LeftDouble
const int32_t C4MC_Button_X2Double
const int32_t C4MC_Button_X2Down
const int32_t C4MC_Button_Wheel
void MessageDialog(const char *message)
bool SetVideoMode(int iXRes, int iYRes, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen)
bool IsClipboardFull(bool fClipboard=true)
virtual void OnResolutionChanged(unsigned int iXRes, unsigned int iYRes)=0
bool GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor)
~C4AbstractApp() override
bool Copy(const std::string &text, bool fClipboard=true)
std::string Paste(bool fClipboard=true)
virtual bool DoInit(int argc, char *argv[])=0
void Error(const char *m)
bool Init(int argc, char *argv[])
C4GamePadControl * pGamePadControl
static constexpr int COLOR_DEPTH
virtual bool CharIn(const char *c)
bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType event_type, bool alt, bool ctrl, bool shift, bool repeated, class C4GUI::Dialog *for_dialog=nullptr, bool fPlrCtrlOnly=false, int32_t strength=-1)
void SetSize(unsigned int cx, unsigned int cy)
void MouseMove(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam, class C4Viewport *pVP)