Atlas - testrelative.c
Home / ext / SDL / test Lines: 1 | Size: 6143 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely. 11*/ 12 13/* Simple program: Test relative mouse motion */ 14 15#include <SDL3/SDL_test.h> 16#include <SDL3/SDL_test_common.h> 17#include <SDL3/SDL_main.h> 18 19#ifdef SDL_PLATFORM_EMSCRIPTEN 20#include <emscripten/emscripten.h> 21#endif 22 23static SDLTest_CommonState *state; 24static int i, done; 25static SDL_FRect rect; 26static SDL_Event event; 27static bool warp; 28 29static void DrawRects(SDL_Renderer *renderer) 30{ 31 SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); 32 SDL_RenderFillRect(renderer, &rect); 33 34 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 35 36 if (SDL_GetWindowRelativeMouseMode(SDL_GetRenderWindow(renderer))) { 37 SDLTest_DrawString(renderer, 0.f, 0.f, "Relative Mode: Enabled"); 38 } else { 39 SDLTest_DrawString(renderer, 0.f, 0.f, "Relative Mode: Disabled"); 40 } 41} 42 43static void CenterMouse(void) 44{ 45 /* Warp the mouse back to the center of the window with input focus to use the 46 * center point for calculating future motion deltas. 47 * 48 * NOTE: DO NOT DO THIS IN REAL APPS/GAMES! 49 * 50 * This is an outdated method of handling relative pointer motion, and 51 * may not work properly, if at all, on some platforms. It is here *only* 52 * for testing the warp emulation code path internal to SDL. 53 * 54 * Relative mouse mode should be used instead! 55 */ 56 SDL_Window *window = SDL_GetKeyboardFocus(); 57 if (window) { 58 int w, h; 59 float cx, cy; 60 61 SDL_GetWindowSize(window, &w, &h); 62 cx = (float)w / 2.f; 63 cy = (float)h / 2.f; 64 65 SDL_WarpMouseInWindow(window, cx, cy); 66 } 67} 68 69static void loop(void) 70{ 71 /* Check for events */ 72 while (SDL_PollEvent(&event)) { 73 SDLTest_CommonEvent(state, &event, &done); 74 switch (event.type) { 75 case SDL_EVENT_WINDOW_FOCUS_GAINED: 76 if (warp) { 77 /* This should activate relative mode for warp emulation, unless disabled via a hint. */ 78 CenterMouse(); 79 } 80 break; 81 case SDL_EVENT_KEY_DOWN: 82 if (event.key.key == SDLK_C) { 83 /* If warp emulation is active, showing the cursor should turn 84 * relative mode off, and it should re-activate after a warp 85 * when hidden again. 86 */ 87 if (SDL_CursorVisible()) { 88 SDL_HideCursor(); 89 } else { 90 SDL_ShowCursor(); 91 } 92 } 93 break; 94 case SDL_EVENT_MOUSE_MOTION: 95 { 96 rect.x += event.motion.xrel; 97 rect.y += event.motion.yrel; 98 99 if (warp) { 100 CenterMouse(); 101 } 102 } break; 103 default: 104 break; 105 } 106 } 107 108 for (i = 0; i < state->num_windows; ++i) { 109 SDL_Rect viewport; 110 SDL_Renderer *renderer = state->renderers[i]; 111 if (state->windows[i] == NULL) { 112 continue; 113 } 114 115 SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); 116 SDL_RenderClear(renderer); 117 118 /* Wrap the cursor rectangle at the screen edges to keep it visible */ 119 SDL_GetRenderViewport(renderer, &viewport); 120 if (rect.x < viewport.x) { 121 rect.x += viewport.w; 122 } 123 if (rect.y < viewport.y) { 124 rect.y += viewport.h; 125 } 126 if (rect.x > viewport.x + viewport.w) { 127 rect.x -= viewport.w; 128 } 129 if (rect.y > viewport.y + viewport.h) { 130 rect.y -= viewport.h; 131 } 132 133 DrawRects(renderer); 134 135 SDL_RenderPresent(renderer); 136 } 137#ifdef SDL_PLATFORM_EMSCRIPTEN 138 if (done) { 139 emscripten_cancel_main_loop(); 140 } 141#endif 142} 143 144int main(int argc, char *argv[]) 145{ 146 /* Initialize test framework */ 147 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); 148 if (!state) { 149 return 1; 150 } 151 152 /* Parse commandline */ 153 for (i = 1; i < argc;) { 154 int consumed; 155 156 consumed = SDLTest_CommonArg(state, i); 157 if (consumed == 0) { 158 consumed = -1; 159 if (SDL_strcasecmp(argv[i], "--warp") == 0) { 160 warp = true; 161 consumed = 1; 162 } 163 } 164 165 if (consumed < 0) { 166 static const char *options[] = { 167 "[--warp]", 168 NULL 169 }; 170 SDLTest_CommonLogUsage(state, argv[0], options); 171 return 1; 172 } 173 i += consumed; 174 } 175 176 if (!SDLTest_CommonInit(state)) { 177 return 2; 178 } 179 180 /* Create the windows and initialize the renderers */ 181 for (i = 0; i < state->num_windows; ++i) { 182 SDL_Renderer *renderer = state->renderers[i]; 183 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); 184 SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); 185 SDL_RenderClear(renderer); 186 } 187 188 /* If warp mode is activated, the cursor will be repeatedly warped back to 189 * the center of the window to simulate the behavior of older games. The cursor 190 * is initially hidden in this case to trigger the warp emulation unless it has 191 * been explicitly disabled via a hint. 192 * 193 * Otherwise, try to activate relative mode. 194 */ 195 if (warp) { 196 SDL_HideCursor(); 197 } else { 198 for (i = 0; i < state->num_windows; ++i) { 199 SDL_SetWindowRelativeMouseMode(state->windows[i], true); 200 } 201 } 202 203 rect.x = DEFAULT_WINDOW_WIDTH / 2; 204 rect.y = DEFAULT_WINDOW_HEIGHT / 2; 205 rect.w = 10; 206 rect.h = 10; 207 /* Main render loop */ 208 done = 0; 209#ifdef SDL_PLATFORM_EMSCRIPTEN 210 emscripten_set_main_loop(loop, 0, 1); 211#else 212 while (!done) { 213 loop(); 214 } 215#endif 216 SDLTest_CommonQuit(state); 217 return 0; 218} 219[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.