int SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { SDL_Renderer *renderer; SDL_Rect full_rect; CHECK_TEXTURE_MAGIC(texture, -1); if (!pixels) { return SDL_InvalidParamError("pixels"); } if (!pitch) { return SDL_InvalidParamError("pitch"); } if (!rect) { full_rect.x = 0; full_rect.y = 0; full_rect.w = texture->w; full_rect.h = texture->h; rect = &full_rect; } if (texture->yuv) { return SDL_UpdateTextureYUV(texture, rect, pixels, pitch); } else if (texture->native) { return SDL_UpdateTextureNative(texture, rect, pixels, pitch); } else { renderer = texture->renderer; return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch); } }
SDL_RWops * SDL_RWFromConstMem(const void *mem, int size) { SDL_RWops *rwops = NULL; if (!mem) { SDL_InvalidParamError("mem"); return rwops; } if (!size) { SDL_InvalidParamError("size"); return rwops; } rwops = SDL_AllocRW(); if (rwops != NULL) { rwops->size = mem_size; rwops->seek = mem_seek; rwops->read = mem_read; rwops->write = mem_writeconst; rwops->close = mem_close; rwops->hidden.mem.base = (Uint8 *) mem; rwops->hidden.mem.here = rwops->hidden.mem.base; rwops->hidden.mem.stop = rwops->hidden.mem.base + size; rwops->type = SDL_RWOPS_MEMORY_RO; } return rwops; }
/* * Copy a block of pixels of one format to another format */ int SDL_ConvertPixels(int width, int height, Uint32 src_format, const void * src, int src_pitch, Uint32 dst_format, void * dst, int dst_pitch) { SDL_Surface src_surface, dst_surface; SDL_PixelFormat src_fmt, dst_fmt; SDL_BlitMap src_blitmap, dst_blitmap; SDL_Rect rect; void *nonconst_src = (void *) src; /* Check to make sure we are blitting somewhere, so we don't crash */ if (!dst) { return SDL_InvalidParamError("dst"); } if (!dst_pitch) { return SDL_InvalidParamError("dst_pitch"); } if (SDL_ISPIXELFORMAT_FOURCC(src_format) && SDL_ISPIXELFORMAT_FOURCC(dst_format)) { return SDL_ConvertPixels_YUV_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch); } else if (SDL_ISPIXELFORMAT_FOURCC(src_format)) { return SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch); } else if (SDL_ISPIXELFORMAT_FOURCC(dst_format)) { return SDL_ConvertPixels_RGB_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch); } /* Fast path for same format copy */ if (src_format == dst_format) { int i; const int bpp = SDL_BYTESPERPIXEL(src_format); width *= bpp; for (i = height; i--;) { SDL_memcpy(dst, src, width); src = (const Uint8*)src + src_pitch; dst = (Uint8*)dst + dst_pitch; } return 0; } if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src, src_pitch, &src_surface, &src_fmt, &src_blitmap)) { return -1; } if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch, &dst_surface, &dst_fmt, &dst_blitmap)) { return -1; } /* Set up the rect and go! */ rect.x = 0; rect.y = 0; rect.w = width; rect.h = height; return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect); }
void SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata) { SDL_Hint *hint; SDL_HintWatch *entry; const char *value; if (!name || !*name) { SDL_InvalidParamError("name"); return; } if (!callback) { SDL_InvalidParamError("callback"); return; } SDL_DelHintCallback(name, callback, userdata); entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry)); if (!entry) { SDL_OutOfMemory(); return; } entry->callback = callback; entry->userdata = userdata; for (hint = SDL_hints; hint; hint = hint->next) { if (SDL_strcmp(name, hint->name) == 0) { break; } } if (!hint) { /* Need to add a hint entry for this watcher */ hint = (SDL_Hint *)SDL_malloc(sizeof(*hint)); if (!hint) { SDL_OutOfMemory(); SDL_free(entry); return; } hint->name = SDL_strdup(name); hint->value = NULL; hint->priority = SDL_HINT_DEFAULT; hint->callbacks = NULL; hint->next = SDL_hints; SDL_hints = hint; } /* Add it to the callbacks for this hint */ entry->next = hint->callbacks; hint->callbacks = entry; /* Now call it with the current value */ value = SDL_GetHint(name); callback(userdata, name, value, value); }
SDL_bool SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) { int Amin, Amax, Bmin, Bmax; if (!A) { SDL_InvalidParamError("A"); return SDL_FALSE; } if (!B) { SDL_InvalidParamError("B"); return SDL_FALSE; } if (!result) { SDL_InvalidParamError("result"); return SDL_FALSE; } /* Special cases for empty rects */ if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) { result->w = 0; result->h = 0; return SDL_FALSE; } /* Horizontal intersection */ Amin = A->x; Amax = Amin + A->w; Bmin = B->x; Bmax = Bmin + B->w; if (Bmin > Amin) Amin = Bmin; result->x = Amin; if (Bmax < Amax) Amax = Bmax; result->w = Amax - Amin; /* Vertical intersection */ Amin = A->y; Amax = Amin + A->h; Bmin = B->y; Bmax = Bmin + B->h; if (Bmin > Amin) Amin = Bmin; result->y = Amin; if (Bmax < Amax) Amax = Bmax; result->h = Amax - Amin; return !SDL_RectEmpty(result); }
int SDL_TLSSet(SDL_TLSID id, const void *value, void (*destructor)(void *)) { SDL_TLSData *storage; if (id == 0) { return SDL_InvalidParamError("id"); } storage = SDL_SYS_GetTLSData(); if (!storage || (id > storage->limit)) { unsigned int i, oldlimit, newlimit; oldlimit = storage ? storage->limit : 0; newlimit = (id + TLS_ALLOC_CHUNKSIZE); storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage)+(newlimit-1)*sizeof(storage->array[0])); if (!storage) { return SDL_OutOfMemory(); } storage->limit = newlimit; for (i = oldlimit; i < newlimit; ++i) { storage->array[i].data = NULL; storage->array[i].destructor = NULL; } if (SDL_SYS_SetTLSData(storage) != 0) { return -1; } } storage->array[id-1].data = SDL_const_cast(void*, value); storage->array[id-1].destructor = destructor; return 0; }
SDL_bool SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B) { int Amin, Amax, Bmin, Bmax; if (!A) { SDL_InvalidParamError("A"); return SDL_FALSE; } if (!B) { SDL_InvalidParamError("B"); return SDL_FALSE; } /* Special cases for empty rects */ if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) { return SDL_FALSE; } /* Horizontal intersection */ Amin = A->x; Amax = Amin + A->w; Bmin = B->x; Bmax = Bmin + B->w; if (Bmin > Amin) Amin = Bmin; if (Bmax < Amax) Amax = Bmax; if (Amax <= Amin) return SDL_FALSE; /* Vertical intersection */ Amin = A->y; Amax = Amin + A->h; Bmin = B->y; Bmax = Bmin + B->h; if (Bmin > Amin) Amin = Bmin; if (Bmax < Amax) Amax = Bmax; if (Amax <= Amin) return SDL_FALSE; return SDL_TRUE; }
int SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key) { int flags; if (!surface) { return SDL_InvalidParamError("surface"); } if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) { return SDL_InvalidParamError("key"); } if (flag & SDL_RLEACCEL) { SDL_SetSurfaceRLE(surface, 1); } flags = surface->map->info.flags; if (flag) { surface->map->info.flags |= SDL_COPY_COLORKEY; surface->map->info.colorkey = key; if (surface->format->palette) { surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT; ++surface->format->palette->version; if (!surface->format->palette->version) { surface->format->palette->version = 1; } } } else { if (surface->format->palette) { surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_OPAQUE; ++surface->format->palette->version; if (!surface->format->palette->version) { surface->format->palette->version = 1; } } surface->map->info.flags &= ~SDL_COPY_COLORKEY; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return 0; }
void X11_SetTextInputRect(_THIS, SDL_Rect *rect) { if (!rect) { SDL_InvalidParamError("rect"); return; } #ifdef SDL_USE_IME SDL_IME_UpdateTextRect(rect); #endif }
void Android_SetTextInputRect(_THIS, SDL_Rect *rect) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; if (!rect) { SDL_InvalidParamError("rect"); return; } videodata->textRect = *rect; }
/* Load all the data from an SDL data stream */ void * SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc) { const int FILE_CHUNK_SIZE = 1024; Sint64 size; size_t size_read, size_total; void *data = NULL, *newdata; if (!src) { SDL_InvalidParamError("src"); return NULL; } size = SDL_RWsize(src); if (size < 0) { size = FILE_CHUNK_SIZE; } data = SDL_malloc((size_t)(size + 1)); size_total = 0; for (;;) { if ((((Sint64)size_total) + FILE_CHUNK_SIZE) > size) { size = (size_total + FILE_CHUNK_SIZE); newdata = SDL_realloc(data, (size_t)(size + 1)); if (!newdata) { SDL_free(data); data = NULL; SDL_OutOfMemory(); goto done; } data = newdata; } size_read = SDL_RWread(src, (char *)data+size_total, 1, (size_t)(size-size_total)); if (size_read == 0) { break; } size_total += size_read; } if (datasize) { *datasize = size_total; } ((char *)data)[size_total] = '\0'; done: if (freesrc && src) { SDL_RWclose(src); } return data; }
/* * Add or update an entry into the Mappings Database with a priority */ static int SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority) { char *pchGUID; SDL_JoystickGUID jGUID; SDL_bool is_xinput_mapping = SDL_FALSE; SDL_bool is_emscripten_mapping = SDL_FALSE; SDL_bool existing = SDL_FALSE; ControllerMapping_t *pControllerMapping; if (!mappingString) { return SDL_InvalidParamError("mappingString"); } pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString); if (!pchGUID) { return SDL_SetError("Couldn't parse GUID from %s", mappingString); } if (!SDL_strcasecmp(pchGUID, "xinput")) { is_xinput_mapping = SDL_TRUE; } if (!SDL_strcasecmp(pchGUID, "emscripten")) { is_emscripten_mapping = SDL_TRUE; } jGUID = SDL_JoystickGetGUIDFromString(pchGUID); SDL_free(pchGUID); pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority); if (!pControllerMapping) { return -1; } if (existing) { return 0; } else { if (is_xinput_mapping) { s_pXInputMapping = pControllerMapping; } if (is_emscripten_mapping) { s_pEmscriptenMapping = pControllerMapping; } return 1; } }
/* * Copy a block of pixels of one format to another format */ int SDL_ConvertPixels(int width, int height, Uint32 src_format, const void * src, int src_pitch, Uint32 dst_format, void * dst, int dst_pitch) { SDL_Surface src_surface, dst_surface; SDL_PixelFormat src_fmt, dst_fmt; SDL_BlitMap src_blitmap, dst_blitmap; SDL_Rect rect; void *nonconst_src = (void *) src; /* Check to make sure we are bliting somewhere, so we don't crash */ if (!dst) { return SDL_InvalidParamError("dst"); } if (!dst_pitch) { return SDL_InvalidParamError("dst_pitch"); } /* Fast path for same format copy */ if (src_format == dst_format) { int bpp; if (SDL_ISPIXELFORMAT_FOURCC(src_format)) { switch (src_format) { case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: case SDL_PIXELFORMAT_YUY2: case SDL_PIXELFORMAT_UYVY: case SDL_PIXELFORMAT_YVYU: bpp = 2; break; default: return SDL_SetError("Unknown FOURCC pixel format"); } } else { bpp = SDL_BYTESPERPIXEL(src_format); } width *= bpp; while (height-- > 0) { SDL_memcpy(dst, src, width); src = (Uint8*)src + src_pitch; dst = (Uint8*)dst + dst_pitch; } return 0; } if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src, src_pitch, &src_surface, &src_fmt, &src_blitmap)) { return -1; } if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch, &dst_surface, &dst_fmt, &dst_blitmap)) { return -1; } /* Set up the rect and go! */ rect.x = 0; rect.y = 0; rect.w = width; rect.h = height; return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect); }
/* * Convert a surface into the specified pixel format. */ SDL_Surface * SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, Uint32 flags) { SDL_Surface *convert; Uint32 copy_flags; SDL_Color copy_color; SDL_Rect bounds; if (!surface) { SDL_InvalidParamError("surface"); return NULL; } if (!format) { SDL_InvalidParamError("format"); return NULL; } /* Check for empty destination palette! (results in empty image) */ if (format->palette != NULL) { int i; for (i = 0; i < format->palette->ncolors; ++i) { if ((format->palette->colors[i].r != 0xFF) || (format->palette->colors[i].g != 0xFF) || (format->palette->colors[i].b != 0xFF)) break; } if (i == format->palette->ncolors) { SDL_SetError("Empty destination palette"); return (NULL); } } /* Create a new surface with the desired format */ convert = SDL_CreateRGBSurface(flags, surface->w, surface->h, format->BitsPerPixel, format->Rmask, format->Gmask, format->Bmask, format->Amask); if (convert == NULL) { return (NULL); } /* Copy the palette if any */ if (format->palette && convert->format->palette) { SDL_memcpy(convert->format->palette->colors, format->palette->colors, format->palette->ncolors * sizeof(SDL_Color)); convert->format->palette->ncolors = format->palette->ncolors; } /* Save the original copy flags */ copy_flags = surface->map->info.flags; copy_color.r = surface->map->info.r; copy_color.g = surface->map->info.g; copy_color.b = surface->map->info.b; copy_color.a = surface->map->info.a; surface->map->info.r = 0xFF; surface->map->info.g = 0xFF; surface->map->info.b = 0xFF; surface->map->info.a = 0xFF; surface->map->info.flags = 0; SDL_InvalidateMap(surface->map); /* Copy over the image data */ bounds.x = 0; bounds.y = 0; bounds.w = surface->w; bounds.h = surface->h; SDL_LowerBlit(surface, &bounds, convert, &bounds); /* Clean up the original surface, and update converted surface */ convert->map->info.r = copy_color.r; convert->map->info.g = copy_color.g; convert->map->info.b = copy_color.b; convert->map->info.a = copy_color.a; convert->map->info.flags = (copy_flags & ~(SDL_COPY_COLORKEY | SDL_COPY_BLEND | SDL_COPY_RLE_DESIRED | SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY)); surface->map->info.r = copy_color.r; surface->map->info.g = copy_color.g; surface->map->info.b = copy_color.b; surface->map->info.a = copy_color.a; surface->map->info.flags = copy_flags; SDL_InvalidateMap(surface->map); if (copy_flags & SDL_COPY_COLORKEY) { SDL_bool set_colorkey_by_color = SDL_FALSE; if (surface->format->palette) { if (format->palette && surface->format->palette->ncolors <= format->palette->ncolors && (SDL_memcmp(surface->format->palette->colors, format->palette->colors, surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) { /* The palette is identical, just set the same colorkey */ SDL_SetColorKey(convert, 1, surface->map->info.colorkey); } else if (format->Amask) { /* The alpha was set in the destination from the palette */ } else { set_colorkey_by_color = SDL_TRUE; } } else { set_colorkey_by_color = SDL_TRUE; } if (set_colorkey_by_color) { SDL_Surface *tmp; SDL_Surface *tmp2; int converted_colorkey = 0; /* Create a dummy surface to get the colorkey converted */ tmp = SDL_CreateRGBSurface(0, 1, 1, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask); /* Share the palette, if any */ if (surface->format->palette) { SDL_SetSurfacePalette(tmp, surface->format->palette); } SDL_FillRect(tmp, NULL, surface->map->info.colorkey); tmp->map->info.flags &= ~SDL_COPY_COLORKEY; /* Convertion of the colorkey */ tmp2 = SDL_ConvertSurface(tmp, format, 0); /* Get the converted colorkey */ SDL_memcpy(&converted_colorkey, tmp2->pixels, tmp2->format->BytesPerPixel); SDL_FreeSurface(tmp); SDL_FreeSurface(tmp2); /* Set the converted colorkey on the new surface */ SDL_SetColorKey(convert, 1, converted_colorkey); /* This is needed when converting for 3D texture upload */ SDL_ConvertColorkeyToAlpha(convert); } } SDL_SetClipRect(convert, &surface->clip_rect); /* Enable alpha blending by default if the new surface has an * alpha channel or alpha modulation */ if ((surface->format->Amask && format->Amask) || (copy_flags & SDL_COPY_MODULATE_ALPHA)) { SDL_SetSurfaceBlendMode(convert, SDL_BLENDMODE_BLEND); } if ((copy_flags & SDL_COPY_RLE_DESIRED) || (flags & SDL_RLEACCEL)) { SDL_SetSurfaceRLE(convert, SDL_RLEACCEL); } /* We're ready to go! */ return (convert); }
SDL_bool SDL_DXGIGetOutputInfo(int displayIndex, int *adapterIndex, int *outputIndex) { #if !HAVE_DXGI_H if (adapterIndex) *adapterIndex = -1; if (outputIndex) *outputIndex = -1; SDL_SetError("SDL was compiled without DXGI support due to missing dxgi.h header"); return SDL_FALSE; #else SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex); void *pDXGIDLL; char *displayName; int nAdapter, nOutput; IDXGIFactory *pDXGIFactory; IDXGIAdapter *pDXGIAdapter; IDXGIOutput* pDXGIOutput; if (!adapterIndex) { SDL_InvalidParamError("adapterIndex"); return SDL_FALSE; } if (!outputIndex) { SDL_InvalidParamError("outputIndex"); return SDL_FALSE; } *adapterIndex = -1; *outputIndex = -1; if (!pData) { SDL_SetError("Invalid display index"); return SDL_FALSE; } if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) { SDL_SetError("Unable to create DXGI interface"); return SDL_FALSE; } displayName = WIN_StringToUTF8(pData->DeviceName); nAdapter = 0; while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter))) { nOutput = 0; while (*adapterIndex == -1 && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) { DXGI_OUTPUT_DESC outputDesc; if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) { char *outputName = WIN_StringToUTF8(outputDesc.DeviceName); if (SDL_strcmp(outputName, displayName) == 0) { *adapterIndex = nAdapter; *outputIndex = nOutput; } SDL_free(outputName); } IDXGIOutput_Release(pDXGIOutput); nOutput++; } IDXGIAdapter_Release(pDXGIAdapter); nAdapter++; } SDL_free(displayName); /* free up the DXGI factory */ IDXGIFactory_Release(pDXGIFactory); SDL_UnloadObject(pDXGIDLL); if (*adapterIndex == -1) { return SDL_FALSE; } else { return SDL_TRUE; } #endif }
void SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) { int Amin, Amax, Bmin, Bmax; if (!A) { SDL_InvalidParamError("A"); return; } if (!B) { SDL_InvalidParamError("B"); return; } if (!result) { SDL_InvalidParamError("result"); return; } /* Special cases for empty Rects */ if (SDL_RectEmpty(A)) { if (SDL_RectEmpty(B)) { /* A and B empty */ return; } else { /* A empty, B not empty */ *result = *B; return; } } else { if (SDL_RectEmpty(B)) { /* A not empty, B empty */ *result = *A; return; } } /* Horizontal union */ Amin = A->x; Amax = Amin + A->w; Bmin = B->x; Bmax = Bmin + B->w; if (Bmin < Amin) Amin = Bmin; result->x = Amin; if (Bmax > Amax) Amax = Bmax; result->w = Amax - Amin; /* Vertical union */ Amin = A->y; Amax = Amin + A->h; Bmin = B->y; Bmax = Bmin + B->h; if (Bmin < Amin) Amin = Bmin; result->y = Amin; if (Bmax > Amax) Amax = Bmax; result->h = Amax - Amin; }
/* * Add or update an entry into the Mappings Database */ int SDL_GameControllerAddMapping(const char *mappingString) { char *pchGUID; char *pchName; char *pchMapping; SDL_JoystickGUID jGUID; ControllerMapping_t *pControllerMapping; SDL_bool is_xinput_mapping = SDL_FALSE; SDL_bool is_emscripten_mapping = SDL_FALSE; if (!mappingString) { return SDL_InvalidParamError("mappingString"); } pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString); if (!pchGUID) { return SDL_SetError("Couldn't parse GUID from %s", mappingString); } if (!SDL_strcasecmp(pchGUID, "xinput")) { is_xinput_mapping = SDL_TRUE; } if (!SDL_strcasecmp(pchGUID, "emscripten")) { is_emscripten_mapping = SDL_TRUE; } jGUID = SDL_JoystickGetGUIDFromString(pchGUID); SDL_free(pchGUID); pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString); if (!pchName) { return SDL_SetError("Couldn't parse name from %s", mappingString); } pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString); if (!pchMapping) { SDL_free(pchName); return SDL_SetError("Couldn't parse %s", mappingString); } pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID); if (pControllerMapping) { /* Update existing mapping */ SDL_free(pControllerMapping->name); pControllerMapping->name = pchName; SDL_free(pControllerMapping->mapping); pControllerMapping->mapping = pchMapping; /* refresh open controllers */ SDL_PrivateGameControllerRefreshMapping(pControllerMapping); return 0; } else { pControllerMapping = SDL_malloc(sizeof(*pControllerMapping)); if (!pControllerMapping) { SDL_free(pchName); SDL_free(pchMapping); return SDL_OutOfMemory(); } if (is_xinput_mapping) { s_pXInputMapping = pControllerMapping; } if (is_emscripten_mapping) { s_pEmscriptenMapping = pControllerMapping; } pControllerMapping->guid = jGUID; pControllerMapping->name = pchName; pControllerMapping->mapping = pchMapping; pControllerMapping->next = s_pSupportedControllers; s_pSupportedControllers = pControllerMapping; return 1; } }
SDL_bool SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip, SDL_Rect * result) { int minx = 0; int miny = 0; int maxx = 0; int maxy = 0; int x, y, i; if (!points) { SDL_InvalidParamError("points"); return SDL_FALSE; } if (count < 1) { SDL_InvalidParamError("count"); return SDL_FALSE; } if (clip) { SDL_bool added = SDL_FALSE; const int clip_minx = clip->x; const int clip_miny = clip->y; const int clip_maxx = clip->x+clip->w-1; const int clip_maxy = clip->y+clip->h-1; /* Special case for empty rectangle */ if (SDL_RectEmpty(clip)) { return SDL_FALSE; } for (i = 0; i < count; ++i) { x = points[i].x; y = points[i].y; if (x < clip_minx || x > clip_maxx || y < clip_miny || y > clip_maxy) { continue; } if (!added) { /* Special case: if no result was requested, we are done */ if (result == NULL) { return SDL_TRUE; } /* First point added */ minx = maxx = x; miny = maxy = y; added = SDL_TRUE; continue; } if (x < minx) { minx = x; } else if (x > maxx) { maxx = x; } if (y < miny) { miny = y; } else if (y > maxy) { maxy = y; } } if (!added) { return SDL_FALSE; } } else { /* Special case: if no result was requested, we are done */ if (result == NULL) { return SDL_TRUE; } /* No clipping, always add the first point */ minx = maxx = points[0].x; miny = maxy = points[0].y; for (i = 1; i < count; ++i) { x = points[i].x; y = points[i].y; if (x < minx) { minx = x; } else if (x > maxx) { maxx = x; } if (y < miny) { miny = y; } else if (y > maxy) { maxy = y; } } } if (result) { result->x = minx; result->y = miny; result->w = (maxx-minx)+1; result->h = (maxy-miny)+1; } return SDL_TRUE; }
SDL_bool SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, int *Y2) { int x = 0; int y = 0; int x1, y1; int x2, y2; int rectx1; int recty1; int rectx2; int recty2; int outcode1, outcode2; if (!rect) { SDL_InvalidParamError("rect"); return SDL_FALSE; } if (!X1) { SDL_InvalidParamError("X1"); return SDL_FALSE; } if (!Y1) { SDL_InvalidParamError("Y1"); return SDL_FALSE; } if (!X2) { SDL_InvalidParamError("X2"); return SDL_FALSE; } if (!Y2) { SDL_InvalidParamError("Y2"); return SDL_FALSE; } /* Special case for empty rect */ if (SDL_RectEmpty(rect)) { return SDL_FALSE; } x1 = *X1; y1 = *Y1; x2 = *X2; y2 = *Y2; rectx1 = rect->x; recty1 = rect->y; rectx2 = rect->x + rect->w - 1; recty2 = rect->y + rect->h - 1; /* Check to see if entire line is inside rect */ if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 && y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) { return SDL_TRUE; } /* Check to see if entire line is to one side of rect */ if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) { return SDL_FALSE; } if (y1 == y2) { /* Horizontal line, easy to clip */ if (x1 < rectx1) { *X1 = rectx1; } else if (x1 > rectx2) { *X1 = rectx2; } if (x2 < rectx1) { *X2 = rectx1; } else if (x2 > rectx2) { *X2 = rectx2; } return SDL_TRUE; } if (x1 == x2) { /* Vertical line, easy to clip */ if (y1 < recty1) { *Y1 = recty1; } else if (y1 > recty2) { *Y1 = recty2; } if (y2 < recty1) { *Y2 = recty1; } else if (y2 > recty2) { *Y2 = recty2; } return SDL_TRUE; } /* More complicated Cohen-Sutherland algorithm */ outcode1 = ComputeOutCode(rect, x1, y1); outcode2 = ComputeOutCode(rect, x2, y2); while (outcode1 || outcode2) { if (outcode1 & outcode2) { return SDL_FALSE; } if (outcode1) { if (outcode1 & CODE_TOP) { y = recty1; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); } else if (outcode1 & CODE_BOTTOM) { y = recty2; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); } else if (outcode1 & CODE_LEFT) { x = rectx1; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); } else if (outcode1 & CODE_RIGHT) { x = rectx2; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); } x1 = x; y1 = y; outcode1 = ComputeOutCode(rect, x, y); } else { if (outcode2 & CODE_TOP) { y = recty1; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); } else if (outcode2 & CODE_BOTTOM) { y = recty2; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); } else if (outcode2 & CODE_LEFT) { x = rectx1; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); } else if (outcode2 & CODE_RIGHT) { x = rectx2; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); } x2 = x; y2 = y; outcode2 = ComputeOutCode(rect, x, y); } } *X1 = x1; *Y1 = y1; *X2 = x2; *Y2 = y2; return SDL_TRUE; }
int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) { size_t len = _len; const Uint8 *data = (const Uint8 *) _data; const size_t packet_size = queue ? queue->packet_size : 0; SDL_DataQueuePacket *orighead; SDL_DataQueuePacket *origtail; size_t origlen; size_t datalen; if (!queue) { return SDL_InvalidParamError("queue"); } orighead = queue->head; origtail = queue->tail; origlen = origtail ? origtail->datalen : 0; while (len > 0) { SDL_DataQueuePacket *packet = queue->tail; SDL_assert(!packet || (packet->datalen <= packet_size)); if (!packet || (packet->datalen >= packet_size)) { /* tail packet missing or completely full; we need a new packet. */ packet = queue->pool; if (packet != NULL) { /* we have one available in the pool. */ queue->pool = packet->next; } else { /* Have to allocate a new one! */ packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + packet_size); if (packet == NULL) { /* uhoh, reset so we've queued nothing new, free what we can. */ if (!origtail) { packet = queue->head; /* whole queue. */ } else { packet = origtail->next; /* what we added to existing queue. */ origtail->next = NULL; origtail->datalen = origlen; } queue->head = orighead; queue->tail = origtail; queue->pool = NULL; SDL_FreeDataQueueList(packet); /* give back what we can. */ return SDL_OutOfMemory(); } } packet->datalen = 0; packet->startpos = 0; packet->next = NULL; SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0)); if (queue->tail == NULL) { queue->head = packet; } else { queue->tail->next = packet; } queue->tail = packet; } datalen = SDL_min(len, packet_size - packet->datalen); SDL_memcpy(packet->data + packet->datalen, data, datalen); data += datalen; len -= datalen; packet->datalen += datalen; queue->queued_bytes += datalen; } return 0; }
SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, const SDL_Rect * rects, SDL_Rect *span) { int i; int span_y1, span_y2; int rect_y1, rect_y2; if (width < 1) { SDL_InvalidParamError("width"); return SDL_FALSE; } if (height < 1) { SDL_InvalidParamError("height"); return SDL_FALSE; } if (!rects) { SDL_InvalidParamError("rects"); return SDL_FALSE; } if (!span) { SDL_InvalidParamError("span"); return SDL_FALSE; } if (numrects < 1) { SDL_InvalidParamError("numrects"); return SDL_FALSE; } /* Initialize to empty rect */ span_y1 = height; span_y2 = 0; for (i = 0; i < numrects; ++i) { rect_y1 = rects[i].y; rect_y2 = rect_y1 + rects[i].h; /* Clip out of bounds rectangles, and expand span rect */ if (rect_y1 < 0) { span_y1 = 0; } else if (rect_y1 < span_y1) { span_y1 = rect_y1; } if (rect_y2 > height) { span_y2 = height; } else if (rect_y2 > span_y2) { span_y2 = rect_y2; } } if (span_y2 > span_y1) { span->x = 0; span->y = span_y1; span->w = width; span->h = (span_y2 - span_y1); return SDL_TRUE; } return SDL_FALSE; }