Atlas - testmouse.c

Home / ext / SDL / test Lines: 1 | Size: 10018 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#include <SDL3/SDL.h> 14#include <SDL3/SDL_main.h> 15#include <SDL3/SDL_test.h> 16 17#ifdef SDL_PLATFORM_EMSCRIPTEN 18#include <emscripten/emscripten.h> 19#endif 20 21#include <stdlib.h> /* exit() */ 22 23#ifdef SDL_PLATFORM_3DS 24/* For mouse-based tests, we want to have the window on the touch screen */ 25#define SCREEN_X 40 26#define SCREEN_Y 240 27#define SCREEN_WIDTH 320 28#define SCREEN_HEIGHT 240 29#elif defined(SDL_PLATFORM_IOS) 30#define SCREEN_WIDTH 320 31#define SCREEN_HEIGHT 480 32#else 33#define SCREEN_WIDTH 640 34#define SCREEN_HEIGHT 480 35#endif 36 37static SDL_Window *window; 38 39typedef struct _Object 40{ 41 struct _Object *next; 42 43 float x1, y1, x2, y2; 44 Uint8 r, g, b; 45 46 bool isRect; 47} Object; 48 49static Object *active = NULL; 50static Object *objects = NULL; 51static int buttons = 0; 52static bool isRect = false; 53 54static bool wheel_x_active = false; 55static bool wheel_y_active = false; 56static float wheel_x = SCREEN_WIDTH * 0.5f; 57static float wheel_y = SCREEN_HEIGHT * 0.5f; 58 59struct mouse_loop_data { 60 bool done; 61 SDL_Renderer *renderer; 62}; 63 64static void DrawObject(SDL_Renderer *renderer, Object *object) 65{ 66 SDL_SetRenderDrawColor(renderer, object->r, object->g, object->b, 255); 67 68 if (object->isRect) { 69 SDL_FRect rect; 70 71 if (object->x1 > object->x2) { 72 rect.x = object->x2; 73 rect.w = object->x1 - object->x2; 74 } else { 75 rect.x = object->x1; 76 rect.w = object->x2 - object->x1; 77 } 78 79 if (object->y1 > object->y2) { 80 rect.y = object->y2; 81 rect.h = object->y1 - object->y2; 82 } else { 83 rect.y = object->y1; 84 rect.h = object->y2 - object->y1; 85 } 86 87 SDL_RenderFillRect(renderer, &rect); 88 } else { 89 SDL_RenderLine(renderer, object->x1, object->y1, object->x2, object->y2); 90 } 91} 92 93static void DrawObjects(SDL_Renderer *renderer) 94{ 95 Object *next = objects; 96 while (next) { 97 DrawObject(renderer, next); 98 next = next->next; 99 } 100} 101 102static void AppendObject(Object *object) 103{ 104 if (objects) { 105 Object *next = objects; 106 while (next->next) { 107 next = next->next; 108 } 109 next->next = object; 110 } else { 111 objects = object; 112 } 113} 114 115static void loop(void *arg) 116{ 117 struct mouse_loop_data *loop_data = (struct mouse_loop_data *)arg; 118 SDL_Event event; 119 SDL_Renderer *renderer = loop_data->renderer; 120 float fx, fy; 121 SDL_MouseButtonFlags flags; 122 123 /* Check for events */ 124 while (SDL_PollEvent(&event)) { 125 switch (event.type) { 126 case SDL_EVENT_MOUSE_WHEEL: 127 if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { 128 event.wheel.x *= -1; 129 event.wheel.y *= -1; 130 } 131 if (event.wheel.x != 0.0f) { 132 wheel_x_active = true; 133 /* "positive to the right and negative to the left" */ 134 wheel_x += event.wheel.x * 10.0f; 135 } 136 if (event.wheel.y != 0.0f) { 137 wheel_y_active = true; 138 /* "positive away from the user and negative towards the user" */ 139 wheel_y -= event.wheel.y * 10.0f; 140 } 141 break; 142 143 case SDL_EVENT_MOUSE_MOTION: 144 if (!active) { 145 break; 146 } 147 148 active->x2 = event.motion.x; 149 active->y2 = event.motion.y; 150 break; 151 152 case SDL_EVENT_MOUSE_BUTTON_DOWN: 153 if (!active) { 154 active = SDL_calloc(1, sizeof(*active)); 155 active->x1 = active->x2 = event.button.x; 156 active->y1 = active->y2 = event.button.y; 157 active->isRect = isRect; 158 } 159 160 switch (event.button.button) { 161 case SDL_BUTTON_LEFT: 162 active->r = 255; 163 buttons |= SDL_BUTTON_LMASK; 164 break; 165 case SDL_BUTTON_MIDDLE: 166 active->g = 255; 167 buttons |= SDL_BUTTON_MMASK; 168 break; 169 case SDL_BUTTON_RIGHT: 170 active->b = 255; 171 buttons |= SDL_BUTTON_RMASK; 172 break; 173 case SDL_BUTTON_X1: 174 active->r = 255; 175 active->b = 255; 176 buttons |= SDL_BUTTON_X1MASK; 177 break; 178 case SDL_BUTTON_X2: 179 active->g = 255; 180 active->b = 255; 181 buttons |= SDL_BUTTON_X2MASK; 182 break; 183 } 184 break; 185 186 case SDL_EVENT_MOUSE_BUTTON_UP: 187 if (!active) { 188 break; 189 } 190 191 switch (event.button.button) { 192 case SDL_BUTTON_LEFT: 193 buttons &= ~SDL_BUTTON_LMASK; 194 break; 195 case SDL_BUTTON_MIDDLE: 196 buttons &= ~SDL_BUTTON_MMASK; 197 break; 198 case SDL_BUTTON_RIGHT: 199 buttons &= ~SDL_BUTTON_RMASK; 200 break; 201 case SDL_BUTTON_X1: 202 buttons &= ~SDL_BUTTON_X1MASK; 203 break; 204 case SDL_BUTTON_X2: 205 buttons &= ~SDL_BUTTON_X2MASK; 206 break; 207 } 208 209 if (buttons == 0) { 210 AppendObject(active); 211 active = NULL; 212 } 213 break; 214 215 case SDL_EVENT_KEY_DOWN: 216 if (event.key.scancode == SDL_SCANCODE_ESCAPE) { 217 loop_data->done = true; 218 break; 219 } 220 if (event.key.key == SDLK_C) { 221 int x, y, w, h; 222 SDL_GetWindowPosition(window, &x, &y); 223 SDL_GetWindowSize(window, &w, &h); 224 w /= 2; 225 h /= 2; 226 227 if (event.key.mod & SDL_KMOD_ALT) { 228 SDL_WarpMouseGlobal((float)(x + w), (float)(y + h)); 229 } else { 230 SDL_WarpMouseInWindow(window, (float)w, (float)h); 231 } 232 } 233 SDL_FALLTHROUGH; 234 case SDL_EVENT_KEY_UP: 235 switch (event.key.key) { 236 case SDLK_LSHIFT: 237 isRect = event.key.down; 238 if (active) { 239 active->isRect = isRect; 240 } 241 break; 242 default: 243 break; 244 } 245 break; 246 247 case SDL_EVENT_QUIT: 248 loop_data->done = true; 249 break; 250 251 default: 252 break; 253 } 254 } 255 256 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); 257 SDL_RenderClear(renderer); 258 259 /* Mouse wheel */ 260 SDL_SetRenderDrawColor(renderer, 0, 255, 128, 255); 261 if (wheel_x_active) { 262 SDL_RenderLine(renderer, wheel_x, 0.0f, wheel_x, (float)SCREEN_HEIGHT); 263 } 264 if (wheel_y_active) { 265 SDL_RenderLine(renderer, 0.0f, wheel_y, (float)SCREEN_WIDTH, wheel_y); 266 } 267 268 /* Objects from mouse clicks */ 269 DrawObjects(renderer); 270 if (active) { 271 DrawObject(renderer, active); 272 } 273 274 flags = SDL_GetGlobalMouseState(&fx, &fy); 275 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 276 SDL_RenderDebugTextFormat(renderer, 0, 0, "Global Mouse State: x=%f y=%f flags=%" SDL_PRIu32, fx, fy, flags); 277 278 SDL_RenderPresent(renderer); 279 280#ifdef SDL_PLATFORM_EMSCRIPTEN 281 if (loop_data->done) { 282 emscripten_cancel_main_loop(); 283 } 284#endif 285} 286 287int main(int argc, char *argv[]) 288{ 289 struct mouse_loop_data loop_data; 290 SDLTest_CommonState *state; 291#ifdef SDL_PLATFORM_3DS 292 SDL_PropertiesID props; 293#endif 294 295 /* Initialize test framework */ 296 state = SDLTest_CommonCreateState(argv, 0); 297 if (!state) { 298 return 1; 299 } 300 301 /* Parse commandline */ 302 if (!SDLTest_CommonDefaultArgs(state, argc, argv)) { 303 return 1; 304 } 305 306 /* Initialize SDL (Note: video is required to start event loop) */ 307 if (!SDL_Init(SDL_INIT_VIDEO)) { 308 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError()); 309 exit(1); 310 } 311 312 /* Create a window to display joystick axis position */ 313#ifdef SDL_PLATFORM_3DS 314 props = SDL_CreateProperties(); 315 SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, "Mouse Test"); 316 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SCREEN_X); 317 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SCREEN_Y); 318 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, SCREEN_WIDTH); 319 SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, SCREEN_HEIGHT); 320 SDL_SetNumberProperty(props, "flags", 0); 321 window = SDL_CreateWindowWithProperties(props); 322#else 323 window = SDL_CreateWindow("Mouse Test", SCREEN_WIDTH, SCREEN_HEIGHT, 0); 324#endif 325 if (!window) { 326 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s", SDL_GetError()); 327 return 0; 328 } 329 330 loop_data.done = false; 331 332 loop_data.renderer = SDL_CreateRenderer(window, NULL); 333 if (!loop_data.renderer) { 334 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s", SDL_GetError()); 335 SDL_DestroyWindow(window); 336 return 0; 337 } 338 339 /* Main render loop */ 340#ifdef SDL_PLATFORM_EMSCRIPTEN 341 emscripten_set_main_loop_arg(loop, &loop_data, 0, 1); 342#else 343 while (loop_data.done == false) { 344 loop(&loop_data); 345 } 346#endif 347 348 while (active) { 349 Object *next = active->next; 350 SDL_free(active); 351 active = next; 352 } 353 SDL_DestroyRenderer(loop_data.renderer); 354 SDL_DestroyWindow(window); 355 356 SDL_Quit(); 357 SDLTest_CommonDestroyState(state); 358 359 return 0; 360} 361
[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.