SDL

Форк
0
/
testrelative.c 
216 строк · 6.0 Кб
1
/*
2
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
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

23
static SDLTest_CommonState *state;
24
static int i, done;
25
static SDL_FRect rect;
26
static SDL_Event event;
27
static SDL_bool warp;
28

29
static 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
    SDLTest_DrawString(renderer, 0.f, 0.f, "Relative Mode: Enabled");
36
}
37

38
static void CenterMouse()
39
{
40
    /* Warp the mouse back to the center of the window with input focus to use the
41
     * center point for calculating future motion deltas.
42
     *
43
     * NOTE: DO NOT DO THIS IN REAL APPS/GAMES!
44
     *
45
     *       This is an outdated method of handling relative pointer motion, and
46
     *       may not work properly, if at all, on some platforms. It is here *only*
47
     *       for testing the warp emulation code path internal to SDL.
48
     *
49
     *       Relative mouse mode should be used instead!
50
     */
51
    SDL_Window *window = SDL_GetKeyboardFocus();
52
    if (window) {
53
        int w, h;
54
        float cx, cy;
55

56
        SDL_GetWindowSize(window, &w, &h);
57
        cx = (float)w / 2.f;
58
        cy = (float)h / 2.f;
59

60
        SDL_WarpMouseInWindow(window, cx, cy);
61
    }
62
}
63

64
static void loop(void)
65
{
66
    /* Check for events */
67
    while (SDL_PollEvent(&event)) {
68
        SDLTest_CommonEvent(state, &event, &done);
69
        switch (event.type) {
70
        case SDL_EVENT_WINDOW_FOCUS_GAINED:
71
            if (warp) {
72
                /* This should activate relative mode for warp emulation, unless disabled via a hint. */
73
                CenterMouse();
74
            }
75
            break;
76
        case SDL_EVENT_KEY_DOWN:
77
            if (event.key.key == SDLK_C) {
78
                /* If warp emulation is active, showing the cursor should turn
79
                 * relative mode off, and it should re-activate after a warp
80
                 * when hidden again.
81
                 */
82
                if (SDL_CursorVisible()) {
83
                    SDL_HideCursor();
84
                } else {
85
                    SDL_ShowCursor();
86
                }
87
            }
88
            break;
89
        case SDL_EVENT_MOUSE_MOTION:
90
        {
91
            rect.x += event.motion.xrel;
92
            rect.y += event.motion.yrel;
93

94
            if (warp) {
95
                CenterMouse();
96
            }
97
        } break;
98
        default:
99
            break;
100
        }
101
    }
102

103
    for (i = 0; i < state->num_windows; ++i) {
104
        SDL_Rect viewport;
105
        SDL_Renderer *renderer = state->renderers[i];
106
        if (state->windows[i] == NULL) {
107
            continue;
108
        }
109

110
        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
111
        SDL_RenderClear(renderer);
112

113
        /* Wrap the cursor rectangle at the screen edges to keep it visible */
114
        SDL_GetRenderViewport(renderer, &viewport);
115
        if (rect.x < viewport.x) {
116
            rect.x += viewport.w;
117
        }
118
        if (rect.y < viewport.y) {
119
            rect.y += viewport.h;
120
        }
121
        if (rect.x > viewport.x + viewport.w) {
122
            rect.x -= viewport.w;
123
        }
124
        if (rect.y > viewport.y + viewport.h) {
125
            rect.y -= viewport.h;
126
        }
127

128
        DrawRects(renderer);
129

130
        SDL_RenderPresent(renderer);
131
    }
132
#ifdef SDL_PLATFORM_EMSCRIPTEN
133
    if (done) {
134
        emscripten_cancel_main_loop();
135
    }
136
#endif
137
}
138

139
int main(int argc, char *argv[])
140
{
141
    /* Enable standard application logging */
142
    SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
143

144
    /* Initialize test framework */
145
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
146
    if (!state) {
147
        return 1;
148
    }
149

150
    /* Parse commandline */
151
    for (i = 1; i < argc;) {
152
        int consumed;
153

154
        consumed = SDLTest_CommonArg(state, i);
155
        if (consumed == 0) {
156
            consumed = -1;
157
            if (SDL_strcasecmp(argv[i], "--warp") == 0) {
158
                warp = SDL_TRUE;
159
                consumed = 1;
160
            }
161
        }
162

163
        if (consumed < 0) {
164
            static const char *options[] = {
165
                "[--warp]",
166
                NULL
167
            };
168
            SDLTest_CommonLogUsage(state, argv[0], options);
169
            return 1;
170
        }
171
        i += consumed;
172
    }
173

174
    if (!SDLTest_CommonInit(state)) {
175
        return 2;
176
    }
177

178
    /* Create the windows and initialize the renderers */
179
    for (i = 0; i < state->num_windows; ++i) {
180
        SDL_Renderer *renderer = state->renderers[i];
181
        SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
182
        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
183
        SDL_RenderClear(renderer);
184
    }
185

186
    /* If warp mode is activated, the cursor will be repeatedly warped back to
187
     * the center of the window to simulate the behavior of older games. The cursor
188
     * is initially hidden in this case to trigger the warp emulation unless it has
189
     * been explicitly disabled via a hint.
190
     *
191
     * Otherwise, try to activate relative mode.
192
     */
193
    if (warp) {
194
        SDL_HideCursor();
195
    } else {
196
        for (i = 0; i < state->num_windows; ++i) {
197
            SDL_SetWindowRelativeMouseMode(state->windows[i], SDL_TRUE);
198
        }
199
    }
200

201
    rect.x = DEFAULT_WINDOW_WIDTH / 2;
202
    rect.y = DEFAULT_WINDOW_HEIGHT / 2;
203
    rect.w = 10;
204
    rect.h = 10;
205
    /* Main render loop */
206
    done = 0;
207
#ifdef SDL_PLATFORM_EMSCRIPTEN
208
    emscripten_set_main_loop(loop, 0, 1);
209
#else
210
    while (!done) {
211
        loop();
212
    }
213
#endif
214
    SDLTest_CommonQuit(state);
215
    return 0;
216
}
217

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.