static int SW_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) { SDL_Rect *verts = (SDL_Rect *) SDL_AllocateRenderVertices(renderer, count * sizeof (SDL_Rect), 0, &cmd->data.draw.first); size_t i; if (!verts) { return -1; } cmd->data.draw.count = count; if (renderer->viewport.x || renderer->viewport.y) { const int x = renderer->viewport.x; const int y = renderer->viewport.y; for (i = 0; i < count; i++, verts++, rects++) { verts->x = (int)(x + rects->x); verts->y = (int)(y + rects->y); verts->w = SDL_max((int)rects->w, 1); verts->h = SDL_max((int)rects->h, 1); } } else { for (i = 0; i < count; i++, verts++, rects++) { verts->x = (int)rects->x; verts->y = (int)rects->y; verts->w = SDL_max((int)rects->w, 1); verts->h = SDL_max((int)rects->h, 1); } } return 0; }
static void UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) { static WORD s_XInputButtons[] = { XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT, XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y, XINPUT_GAMEPAD_GUIDE }; WORD wButtons = pXInputState->Gamepad.wButtons; Uint8 button; SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX); SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbLY))); SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX); SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbRY))); SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger * 65535 / 255) - 32768)); SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger * 65535 / 255) - 32768)); for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) { SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED); } UpdateXInputJoystickBatteryInformation( joystick, pBatteryInformation ); }
// Check the display bounds of the display referred to by 'video_display' and // set x and y to a location that places the window in the center of that // display. static void CenterWindow(int *x, int *y, int w, int h) { SDL_Rect bounds; if (SDL_GetDisplayBounds(video_display, &bounds) < 0) { fprintf(stderr, "CenterWindow: Failed to read display bounds " "for display #%d!\n", video_display); return; } *x = bounds.x + SDL_max((bounds.w - w) / 2, 0); *y = bounds.y + SDL_max((bounds.h - h) / 2, 0); }
static int SW_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Rect *final_rects; int i, status; if (!surface) { return -1; } final_rects = SDL_stack_alloc(SDL_Rect, count); if (!final_rects) { return SDL_OutOfMemory(); } if (renderer->viewport.x || renderer->viewport.y) { int x = renderer->viewport.x; int y = renderer->viewport.y; for (i = 0; i < count; ++i) { final_rects[i].x = (int)(x + rects[i].x); final_rects[i].y = (int)(y + rects[i].y); final_rects[i].w = SDL_max((int)rects[i].w, 1); final_rects[i].h = SDL_max((int)rects[i].h, 1); } } else { for (i = 0; i < count; ++i) { final_rects[i].x = (int)rects[i].x; final_rects[i].y = (int)rects[i].y; final_rects[i].w = SDL_max((int)rects[i].w, 1); final_rects[i].h = SDL_max((int)rects[i].h, 1); } } if (renderer->blendMode == SDL_BLENDMODE_NONE) { Uint32 color = SDL_MapRGBA(surface->format, renderer->r, renderer->g, renderer->b, renderer->a); status = SDL_FillRects(surface, final_rects, count, color); } else { status = SDL_BlendFillRects(surface, final_rects, count, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } SDL_stack_free(final_rects); return status; }
static Sint64 SDLCALL rw_seekfunc(SDL_RWops *context, Sint64 offset, int whence) { Sint64 newpos; if (context->type != SDL_RW_TAG_CURRENT) { return SDL_SetError("bad RWops type"); } switch (whence) { case RW_SEEK_SET: newpos = context->hidden.rwops.begin + offset; break; case RW_SEEK_CUR: newpos = context->hidden.rwops.current + offset; break; case RW_SEEK_END: newpos = context->hidden.rwops.end + offset; break; default: return SDL_SetError("Unknown value for seek 'whence'"); } context->hidden.rwops.current = SDL_max( SDL_min(newpos, context->hidden.rwops.end), context->hidden.rwops.begin ); return newpos - context->hidden.rwops.begin; }
static void handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height) { SDL_WindowData *wind = (SDL_WindowData *)data; SDL_Window *window = wind->sdlwindow; struct wl_region *region; /* wl_shell_surface spec states that this is a suggestion. Ignore if less than or greater than max/min size. */ if (width == 0 || height == 0) { return; } if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { if ((window->flags & SDL_WINDOW_RESIZABLE)) { if (window->max_w > 0) { width = SDL_min(width, window->max_w); } width = SDL_max(width, window->min_w); if (window->max_h > 0) { height = SDL_min(height, window->max_h); } height = SDL_max(height, window->min_h); } else { return; } } if (width == window->w && height == window->h) { return; } window->w = width; window->h = height; WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0); region = wl_compositor_create_region(wind->waylandData->compositor); wl_region_add(region, 0, 0, window->w, window->h); wl_surface_set_opaque_region(wind->surface, region); wl_region_destroy(region); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, window->w, window->h); }
void OpenGL::resize(unsigned width, unsigned height) { if(gltexture == 0) glGenTextures(1, &gltexture); glErrorCheck(); iwidth = SDL_max(width, iwidth ); iheight = SDL_max(height, iheight); if(buffer_surface) delete buffer_surface; buffer_surface = new Surface(iwidth, iheight, 0, 0, ibpp); // use OpenXcom's Surface class to get an aligned buffer with bonus SDL_Surface buffer = (uint32_t*) buffer_surface->getSurface()->pixels; glBindTexture(GL_TEXTURE_2D, gltexture); glErrorCheck(); glPixelStorei(GL_UNPACK_ROW_LENGTH, iwidth); glErrorCheck(); glTexImage2D(GL_TEXTURE_2D, /* mip-map level = */ 0, /* internal format = */ GL_RGB16_EXT, width, height, /* border = */ 0, /* format = */ GL_BGRA, iformat, buffer); glErrorCheck(); }
static void handle_configure_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states) { SDL_WindowData *wind = (SDL_WindowData *)data; SDL_Window *window = wind->sdlwindow; /* wl_shell_surface spec states that this is a suggestion. Ignore if less than or greater than max/min size. */ if (width == 0 || height == 0) { return; } if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { if ((window->flags & SDL_WINDOW_RESIZABLE)) { if (window->max_w > 0) { width = SDL_min(width, window->max_w); } width = SDL_max(width, window->min_w); if (window->max_h > 0) { height = SDL_min(height, window->max_h); } height = SDL_max(height, window->min_h); } else { return; } } if (width == window->w && height == window->h) { return; } window->w = width; window->h = height; }
SDL_GLContext SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) { /* max 14 values plus terminator. */ EGLint attribs[15]; int attr = 0; EGLContext egl_context, share_context = EGL_NO_CONTEXT; EGLint profile_mask = _this->gl_config.profile_mask; EGLint major_version = _this->gl_config.major_version; EGLint minor_version = _this->gl_config.minor_version; SDL_bool profile_es = (profile_mask == SDL_GL_CONTEXT_PROFILE_ES); if (!_this->egl_data) { /* The EGL library wasn't loaded, SDL_GetError() should have info */ return NULL; } if (_this->gl_config.share_with_current_context) { share_context = (EGLContext)SDL_GL_GetCurrentContext(); } /* Set the context version and other attributes. */ if ((major_version < 3 || (minor_version == 0 && profile_es)) && _this->gl_config.flags == 0 && (profile_mask == 0 || profile_es)) { /* Create a context without using EGL_KHR_create_context attribs. * When creating a GLES context without EGL_KHR_create_context we can * only specify the major version. When creating a desktop GL context * we can't specify any version, so we only try in that case when the * version is less than 3.0 (matches SDL's GLX/WGL behavior.) */ if (profile_es) { attribs[attr++] = EGL_CONTEXT_CLIENT_VERSION; attribs[attr++] = SDL_max(major_version, 1); } } else { #ifdef EGL_KHR_create_context /* The Major/minor version, context profiles, and context flags can * only be specified when this extension is available. */ if (SDL_EGL_HasExtension(_this, "EGL_KHR_create_context")) { attribs[attr++] = EGL_CONTEXT_MAJOR_VERSION_KHR; attribs[attr++] = major_version; attribs[attr++] = EGL_CONTEXT_MINOR_VERSION_KHR; attribs[attr++] = minor_version; /* SDL profile bits match EGL profile bits. */ if (profile_mask != 0 && profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { attribs[attr++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; attribs[attr++] = profile_mask; } /* SDL flags match EGL flags. */ if (_this->gl_config.flags != 0) { attribs[attr++] = EGL_CONTEXT_FLAGS_KHR; attribs[attr++] = _this->gl_config.flags; } } else #endif /* EGL_KHR_create_context */ { SDL_SetError("Could not create EGL context (context attributes are not supported)"); return NULL; } } attribs[attr++] = EGL_NONE; /* Bind the API */ if (profile_es) { _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API); } else { _this->egl_data->eglBindAPI(EGL_OPENGL_API); } egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display, _this->egl_data->egl_config, share_context, attribs); if (egl_context == EGL_NO_CONTEXT) { SDL_SetError("Could not create EGL context"); return NULL; } _this->egl_data->egl_swapinterval = 0; if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) { SDL_EGL_DeleteContext(_this, egl_context); SDL_SetError("Could not make EGL context current"); return NULL; } return (SDL_GLContext) egl_context; }
int SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) { clicks = SDL_max(clicks, 0); return SDL_PrivateSendMouseButton(window, mouseID, state, button, clicks); }
static int SDL_RendererEventWatch(void *userdata, SDL_Event *event) { SDL_Renderer *renderer = (SDL_Renderer *)userdata; if (event->type == SDL_WINDOWEVENT) { SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); if (window == renderer->window) { if (renderer->WindowEvent) { renderer->WindowEvent(renderer, &event->window); } if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { if (renderer->logical_w) { UpdateLogicalSize(renderer); } else { /* Window was resized, reset viewport */ int w, h; SDL_GetWindowSize(window, &w, &h); if (renderer->target) { renderer->viewport_backup.x = 0; renderer->viewport_backup.y = 0; renderer->viewport_backup.w = w; renderer->viewport_backup.h = h; } else { renderer->viewport.x = 0; renderer->viewport.y = 0; renderer->viewport.w = w; renderer->viewport.h = h; renderer->UpdateViewport(renderer); } } } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) { renderer->hidden = SDL_TRUE; } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) { if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)) { renderer->hidden = SDL_FALSE; } } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) { renderer->hidden = SDL_TRUE; } else if (event->window.event == SDL_WINDOWEVENT_RESTORED) { if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_HIDDEN)) { renderer->hidden = SDL_FALSE; } } } } else if (event->type == SDL_MOUSEMOTION) { if (renderer->logical_w) { event->motion.x -= renderer->viewport.x; event->motion.y -= renderer->viewport.y; event->motion.x = (int)(event->motion.x / renderer->scale.x); event->motion.y = (int)(event->motion.y / renderer->scale.y); if (event->motion.xrel > 0) { event->motion.xrel = SDL_max(1, (int)(event->motion.xrel / renderer->scale.x)); } else if (event->motion.xrel < 0) { event->motion.xrel = SDL_min(-1, (int)(event->motion.xrel / renderer->scale.x)); } if (event->motion.yrel > 0) { event->motion.yrel = SDL_max(1, (int)(event->motion.yrel / renderer->scale.y)); } else if (event->motion.yrel < 0) { event->motion.yrel = SDL_min(-1, (int)(event->motion.yrel / renderer->scale.y)); } } } else if (event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEBUTTONUP) { if (renderer->logical_w) { event->button.x -= renderer->viewport.x; event->button.y -= renderer->viewport.y; event->button.x = (int)(event->button.x / renderer->scale.x); event->button.y = (int)(event->button.y / renderer->scale.y); } } return 0; }
SDL_GLContext SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) { /* max 14 values plus terminator. */ EGLint attribs[15]; int attr = 0; EGLContext egl_context, share_context = EGL_NO_CONTEXT; EGLint profile_mask = _this->gl_config.profile_mask; EGLint major_version = _this->gl_config.major_version; EGLint minor_version = _this->gl_config.minor_version; SDL_bool profile_es = (profile_mask == SDL_GL_CONTEXT_PROFILE_ES); if (!_this->egl_data) { /* The EGL library wasn't loaded, SDL_GetError() should have info */ return NULL; } if (_this->gl_config.share_with_current_context) { share_context = (EGLContext)SDL_GL_GetCurrentContext(); } #if SDL_VIDEO_DRIVER_ANDROID if ((_this->gl_config.flags & SDL_GL_CONTEXT_DEBUG_FLAG) != 0) { /* If SDL_GL_CONTEXT_DEBUG_FLAG is set but EGL_KHR_debug unsupported, unset. * This is required because some Android devices like to complain about it * by "silently" failing, logging a hint which could be easily overlooked: * E/libEGL (26984): validate_display:255 error 3008 (EGL_BAD_DISPLAY) * The following explicitly checks for EGL_KHR_debug before EGL 1.5 */ int egl_version_major = _this->egl_data->egl_version_major; int egl_version_minor = _this->egl_data->egl_version_minor; if (((egl_version_major < 1) || (egl_version_major == 1 && egl_version_minor < 5)) && !SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_debug")) { /* SDL profile bits match EGL profile bits. */ _this->gl_config.flags &= ~SDL_GL_CONTEXT_DEBUG_FLAG; } } #endif /* Set the context version and other attributes. */ if ((major_version < 3 || (minor_version == 0 && profile_es)) && _this->gl_config.flags == 0 && (profile_mask == 0 || profile_es)) { /* Create a context without using EGL_KHR_create_context attribs. * When creating a GLES context without EGL_KHR_create_context we can * only specify the major version. When creating a desktop GL context * we can't specify any version, so we only try in that case when the * version is less than 3.0 (matches SDL's GLX/WGL behavior.) */ if (profile_es) { attribs[attr++] = EGL_CONTEXT_CLIENT_VERSION; attribs[attr++] = SDL_max(major_version, 1); } } else { #ifdef EGL_KHR_create_context /* The Major/minor version, context profiles, and context flags can * only be specified when this extension is available. */ if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context")) { attribs[attr++] = EGL_CONTEXT_MAJOR_VERSION_KHR; attribs[attr++] = major_version; attribs[attr++] = EGL_CONTEXT_MINOR_VERSION_KHR; attribs[attr++] = minor_version; /* SDL profile bits match EGL profile bits. */ if (profile_mask != 0 && profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { attribs[attr++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; attribs[attr++] = profile_mask; } /* SDL flags match EGL flags. */ if (_this->gl_config.flags != 0) { attribs[attr++] = EGL_CONTEXT_FLAGS_KHR; attribs[attr++] = _this->gl_config.flags; } } else #endif /* EGL_KHR_create_context */ { SDL_SetError("Could not create EGL context (context attributes are not supported)"); return NULL; } } if (_this->gl_config.no_error) { #ifdef EGL_KHR_create_context_no_error if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context_no_error")) { attribs[attr++] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR; attribs[attr++] = _this->gl_config.no_error; } else #endif { SDL_SetError("EGL implementation does not support no_error contexts"); return NULL; } } attribs[attr++] = EGL_NONE; /* Bind the API */ if (profile_es) { _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API); } else { _this->egl_data->eglBindAPI(EGL_OPENGL_API); } egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display, _this->egl_data->egl_config, share_context, attribs); if (egl_context == EGL_NO_CONTEXT) { SDL_EGL_SetError("Could not create EGL context", "eglCreateContext"); return NULL; } _this->egl_data->egl_swapinterval = 0; if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) { /* Save the SDL error set by SDL_EGL_MakeCurrent */ char errorText[1024]; SDL_strlcpy(errorText, SDL_GetError(), SDL_arraysize(errorText)); /* Delete the context, which may alter the value returned by SDL_GetError() */ SDL_EGL_DeleteContext(_this, egl_context); /* Restore the SDL error */ SDL_SetError("%s", errorText); return NULL; } return (SDL_GLContext) egl_context; }