static void PrepTextureForCopy(const SDL_RenderCommand *cmd) { const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const SDL_BlendMode blend = cmd->data.draw.blend; SDL_Texture *texture = cmd->data.draw.texture; SDL_Surface *surface = (SDL_Surface *) texture->driverdata; if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { SDL_SetSurfaceRLE(surface, 0); SDL_SetSurfaceColorMod(surface, r, g, b); } if ((texture->modMode & SDL_TEXTUREMODULATE_ALPHA) && surface->format->Amask) { SDL_SetSurfaceRLE(surface, 0); SDL_SetSurfaceAlphaMod(surface, a); } if ((blend == SDL_BLENDMODE_ADD) || (blend == SDL_BLENDMODE_MOD)) { SDL_SetSurfaceRLE(surface, 0); } SDL_SetSurfaceBlendMode(surface, blend); }
int SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key) { int flags; if (!surface) { return -1; } 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; } else { surface->map->info.flags &= ~SDL_COPY_COLORKEY; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return 0; }
static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { int bpp; Uint32 Rmask, Gmask, Bmask, Amask; if (!SDL_PixelFormatEnumToMasks (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { return SDL_SetError("Unknown texture format"); } texture->driverdata = SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, Bmask, Amask); SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g, texture->b); SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a); SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode); if (texture->access == SDL_TEXTUREACCESS_STATIC) { SDL_SetSurfaceRLE(texture->driverdata, 1); } if (!texture->driverdata) { return -1; } return 0; }
SDLImage::SDLImage(std::string filename, bool compressed): margins(0,0) { surf = BitmapHandler::loadBitmap(filename); if (surf == nullptr) { logGlobal->errorStream() << "Error: failed to load image "<<filename; return; } else { fullSize.x = surf->w; fullSize.y = surf->h; } if (compressed) { SDL_Surface *temp = surf; // add RLE flag if (surf->format->palette) { CSDL_Ext::setColorKey(temp,temp->format->palette->colors[0]); } SDL_SetSurfaceRLE(temp, SDL_RLEACCEL); // convert surface to enable RLE surf = SDL_ConvertSurface(temp, temp->format, temp->flags); SDL_FreeSurface(temp); } }
static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; SDL_Rect final_rect; if (!surface) { return -1; } if (renderer->viewport.x || renderer->viewport.y) { final_rect.x = (int)(renderer->viewport.x + dstrect->x); final_rect.y = (int)(renderer->viewport.y + dstrect->y); } else { final_rect.x = (int)dstrect->x; final_rect.y = (int)dstrect->y; } final_rect.w = (int)dstrect->w; final_rect.h = (int)dstrect->h; if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) { return SDL_BlitSurface(src, srcrect, surface, &final_rect); } else { /* If scaling is ever done, permanently disable RLE (which doesn't support scaling) * to avoid potentially frequent RLE encoding/decoding. */ SDL_SetSurfaceRLE(surface, 0); return SDL_BlitScaled(src, srcrect, surface, &final_rect); } }
static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { int bpp; Uint32 Rmask, Gmask, Bmask, Amask; if (!SDL_PixelFormatEnumToMasks (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { return SDL_SetError("Unknown texture format"); } texture->driverdata = SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, Bmask, Amask); SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g, texture->b); SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a); SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode); /* Only RLE encode textures without an alpha channel since the RLE coder * discards the color values of pixels with an alpha value of zero. */ if (texture->access == SDL_TEXTUREACCESS_STATIC && !Amask) { SDL_SetSurfaceRLE(texture->driverdata, 1); } if (!texture->driverdata) { return -1; } return 0; }
bool Image::RLE ( bool flag ) { if ( SDL_SetSurfaceRLE ( this->image(), SDL_BOOL(flag) ) != 0 ) { NOM_LOG_ERR ( NOM, SDL_GetError() ); return false; } return true; }
static mrb_value mrb_sdl2_video_surface_set_rle(mrb_state *mrb, mrb_value self) { SDL_Surface *s = mrb_sdl2_video_surface_get_ptr(mrb, self); mrb_bool is_rle_enabled; mrb_get_args(mrb, "b", &is_rle_enabled); if (0 != SDL_SetSurfaceRLE(s, is_rle_enabled ? 1 : 0)) { mruby_sdl2_raise_error(mrb); } return self; }
static int SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) { SDL_Surface *surface = (SDL_Surface *) texture->driverdata; /* If the texture ever has multiple alpha values (surface alpha plus alpha channel), permanently * disable RLE (which doesn't support this) to avoid potentially frequent RLE encoding/decoding. */ if (texture->a != 255 && surface->format->Amask) { SDL_SetSurfaceRLE(surface, 0); } return SDL_SetSurfaceAlphaMod(surface, texture->a); }
static int SW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) { SDL_Surface *surface = (SDL_Surface *) texture->driverdata; /* If add or mod blending are ever enabled, permanently disable RLE (which doesn't support * them) to avoid potentially frequent RLE encoding/decoding. */ if ((texture->blendMode == SDL_BLENDMODE_ADD || texture->blendMode == SDL_BLENDMODE_MOD)) { SDL_SetSurfaceRLE(surface, 0); } return SDL_SetSurfaceBlendMode(surface, texture->blendMode); }
static int SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) { SDL_Surface *surface = (SDL_Surface *) texture->driverdata; /* If the color mod is ever enabled (non-white), permanently disable RLE (which doesn't support * color mod) to avoid potentially frequent RLE encoding/decoding. */ if ((texture->r & texture->g & texture->b) != 255) { SDL_SetSurfaceRLE(surface, 0); } return SDL_SetSurfaceColorMod(surface, texture->r, texture->g, texture->b); }
int SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value) { if (flag & SDL_SRCALPHA) { /* According to the docs, value is ignored for alpha surfaces */ if (surface->format->Amask) { value = 0xFF; } SDL_SetSurfaceAlphaMod(surface, value); SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND); } else { SDL_SetSurfaceAlphaMod(surface, 0xFF); SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); } SDL_SetSurfaceRLE(surface, (flag & SDL_RLEACCEL)); return 0; }
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 SDLManager::initGFX() { window = std::unique_ptr<SDL_Window, SDLWindowDeleter>(SDL_CreateWindow( "Chip8", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 64, 32, SDL_WINDOW_RESIZABLE )); renderer = std::unique_ptr<SDL_Renderer, SDLRendererDeleter>(SDL_CreateRenderer( window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE )); surface = std::unique_ptr<SDL_Surface, SDLSurfaceDeleter>(SDL_CreateRGBSurface( 0, 64, 32, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF)); texture = std::unique_ptr<SDL_Texture, SDLTextureDeleter>(SDL_CreateTexture( renderer.get(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 64, 32)); SDL_SetSurfaceRLE(surface.get(), 1); SDL_RenderSetLogicalSize(renderer.get(), 64, 32); }
static void PrepTextureForCopy(const SDL_RenderCommand *cmd) { const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const SDL_BlendMode blend = cmd->data.draw.blend; SDL_Texture *texture = cmd->data.draw.texture; SDL_Surface *surface = (SDL_Surface *) texture->driverdata; const SDL_bool colormod = ((r & g & b) != 0xFF); const SDL_bool alphamod = (a != 0xFF); const SDL_bool blending = ((blend == SDL_BLENDMODE_ADD) || (blend == SDL_BLENDMODE_MOD)); if (colormod || alphamod || blending) { SDL_SetSurfaceRLE(surface, 0); } /* !!! FIXME: we can probably avoid some of these calls. */ SDL_SetSurfaceColorMod(surface, r, g, b); SDL_SetSurfaceAlphaMod(surface, a); SDL_SetSurfaceBlendMode(surface, blend); }
static int SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect, const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SDL_Surface *src = (SDL_Surface *) texture->driverdata; SDL_Rect final_rect, tmp_rect; SDL_Surface *surface_rotated, *surface_scaled; int retval, dstwidth, dstheight, abscenterx, abscentery; double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; if (!surface) { return -1; } if (renderer->viewport.x || renderer->viewport.y) { final_rect.x = (int)(renderer->viewport.x + dstrect->x); final_rect.y = (int)(renderer->viewport.y + dstrect->y); } else { final_rect.x = (int)dstrect->x; final_rect.y = (int)dstrect->y; } final_rect.w = (int)dstrect->w; final_rect.h = (int)dstrect->h; /* SDLgfx_rotateSurface doesn't accept a source rectangle, so crop and scale if we need to */ tmp_rect = final_rect; tmp_rect.x = 0; tmp_rect.y = 0; if (srcrect->w == final_rect.w && srcrect->h == final_rect.h && srcrect->x == 0 && srcrect->y == 0) { surface_scaled = src; /* but if we don't need to, just use the original */ retval = 0; } else { SDL_Surface *blit_src = src; Uint32 colorkey; SDL_BlendMode blendMode; Uint8 alphaMod, r, g, b; SDL_bool cloneSource = SDL_FALSE; surface_scaled = SDL_CreateRGBSurface(SDL_SWSURFACE, final_rect.w, final_rect.h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask ); if (!surface_scaled) { return -1; } /* copy the color key, alpha mod, blend mode, and color mod so the scaled surface behaves like the source */ if (SDL_GetColorKey(src, &colorkey) == 0) { SDL_SetColorKey(surface_scaled, SDL_TRUE, colorkey); cloneSource = SDL_TRUE; } SDL_GetSurfaceAlphaMod(src, &alphaMod); /* these will be copied to surface_scaled below if necessary */ SDL_GetSurfaceBlendMode(src, &blendMode); SDL_GetSurfaceColorMod(src, &r, &g, &b); /* now we need to blit the src into surface_scaled. since we want to copy the colors from the source to * surface_scaled rather than blend them, etc. we'll need to disable the blend mode, alpha mod, etc. * but we don't want to modify src (in case it's being used on other threads), so we'll need to clone it * before changing the blend options */ cloneSource |= blendMode != SDL_BLENDMODE_NONE || (alphaMod & r & g & b) != 255; if (cloneSource) { blit_src = SDL_ConvertSurface(src, src->format, src->flags); /* clone src */ if (!blit_src) { SDL_FreeSurface(surface_scaled); return -1; } SDL_SetSurfaceAlphaMod(blit_src, 255); /* disable all blending options in blit_src */ SDL_SetSurfaceBlendMode(blit_src, SDL_BLENDMODE_NONE); SDL_SetColorKey(blit_src, 0, 0); SDL_SetSurfaceColorMod(blit_src, 255, 255, 255); SDL_SetSurfaceRLE(blit_src, 0); /* don't RLE encode a surface we'll only use once */ SDL_SetSurfaceAlphaMod(surface_scaled, alphaMod); /* copy blending options to surface_scaled */ SDL_SetSurfaceBlendMode(surface_scaled, blendMode); SDL_SetSurfaceColorMod(surface_scaled, r, g, b); } retval = SDL_BlitScaled(blit_src, srcrect, surface_scaled, &tmp_rect); if (blit_src != src) { SDL_FreeSurface(blit_src); } } if (!retval) { SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle); surface_rotated = SDLgfx_rotateSurface(surface_scaled, angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); if(surface_rotated) { /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ abscenterx = final_rect.x + (int)center->x; abscentery = final_rect.y + (int)center->y; /* Compensate the angle inversion to match the behaviour of the other backends */ sangle = -sangle; /* Top Left */ px = final_rect.x - abscenterx; py = final_rect.y - abscentery; p1x = px * cangle - py * sangle + abscenterx; p1y = px * sangle + py * cangle + abscentery; /* Top Right */ px = final_rect.x + final_rect.w - abscenterx; py = final_rect.y - abscentery; p2x = px * cangle - py * sangle + abscenterx; p2y = px * sangle + py * cangle + abscentery; /* Bottom Left */ px = final_rect.x - abscenterx; py = final_rect.y + final_rect.h - abscentery; p3x = px * cangle - py * sangle + abscenterx; p3y = px * sangle + py * cangle + abscentery; /* Bottom Right */ px = final_rect.x + final_rect.w - abscenterx; py = final_rect.y + final_rect.h - abscentery; p4x = px * cangle - py * sangle + abscenterx; p4y = px * sangle + py * cangle + abscentery; tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x)); tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y)); tmp_rect.w = dstwidth; tmp_rect.h = dstheight; retval = SDL_BlitSurface(surface_rotated, NULL, surface, &tmp_rect); SDL_FreeSurface(surface_rotated); } } if (surface_scaled != src) { SDL_FreeSurface(surface_scaled); } return retval; }
static int SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { SW_RenderData *data = (SW_RenderData *) renderer->driverdata; SDL_Surface *surface = SW_ActivateRenderer(renderer); const SDL_Rect *viewport = NULL; const SDL_Rect *cliprect = NULL; if (!surface) { return -1; } while (cmd) { switch (cmd->command) { case SDL_RENDERCMD_SETDRAWCOLOR: { break; /* Not used in this backend. */ } case SDL_RENDERCMD_SETVIEWPORT: { viewport = &cmd->data.viewport.rect; SDL_SetClipRect(data->surface, viewport); break; } case SDL_RENDERCMD_SETCLIPRECT: { SDL_assert(viewport != NULL); cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL; if (cliprect) { SDL_Rect clip_rect; clip_rect.x = cliprect->x + viewport->x; clip_rect.y = cliprect->y + viewport->y; clip_rect.w = cliprect->w; clip_rect.h = cliprect->h; SDL_IntersectRect(viewport, &clip_rect, &clip_rect); SDL_SetClipRect(surface, &clip_rect); } else { SDL_SetClipRect(surface, viewport); } break; } case SDL_RENDERCMD_CLEAR: { const Uint8 r = cmd->data.color.r; const Uint8 g = cmd->data.color.g; const Uint8 b = cmd->data.color.b; const Uint8 a = cmd->data.color.a; const SDL_Rect clip_rect = surface->clip_rect; /* By definition the clear ignores the clip rect */ SDL_SetClipRect(surface, NULL); SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, r, g, b, a)); SDL_SetClipRect(surface, &clip_rect); break; } case SDL_RENDERCMD_DRAW_POINTS: { const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; const SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; if (blend == SDL_BLENDMODE_NONE) { SDL_DrawPoints(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { SDL_BlendPoints(surface, verts, count, blend, r, g, b, a); } break; } case SDL_RENDERCMD_DRAW_LINES: { const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; const SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; if (blend == SDL_BLENDMODE_NONE) { SDL_DrawLines(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { SDL_BlendLines(surface, verts, count, blend, r, g, b, a); } break; } case SDL_RENDERCMD_FILL_RECTS: { const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; const SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; if (blend == SDL_BLENDMODE_NONE) { SDL_FillRects(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { SDL_BlendFillRects(surface, verts, count, blend, r, g, b, a); } break; } case SDL_RENDERCMD_COPY: { SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_Rect *srcrect = verts; SDL_Rect *dstrect = verts + 1; SDL_Texture *texture = cmd->data.draw.texture; SDL_Surface *src = (SDL_Surface *) texture->driverdata; PrepTextureForCopy(cmd); if ( srcrect->w == dstrect->w && srcrect->h == dstrect->h ) { SDL_BlitSurface(src, srcrect, surface, dstrect); } else { /* If scaling is ever done, permanently disable RLE (which doesn't support scaling) * to avoid potentially frequent RLE encoding/decoding. */ SDL_SetSurfaceRLE(surface, 0); SDL_BlitScaled(src, srcrect, surface, dstrect); } break; } case SDL_RENDERCMD_COPY_EX: { const CopyExData *copydata = (CopyExData *) (((Uint8 *) vertices) + cmd->data.draw.first); PrepTextureForCopy(cmd); SW_RenderCopyEx(renderer, surface, cmd->data.draw.texture, ©data->srcrect, ©data->dstrect, copydata->angle, ©data->center, copydata->flip); break; } case SDL_RENDERCMD_NO_OP: break; } cmd = cmd->next; } return 0; }
int inline Surface::setRLE(State & state, SDL_Surface * surface){ SDL_SetSurfaceRLE(surface, state.stack->to<int>(1)); return 0; }
SDL_Surface* Blitter::scale_surface(SDL_Surface* surface, int width, int height) { int i; int j; unsigned char *pixels; unsigned char *new_pixels; int x; int bpp; int new_pitch; SDL_Surface* new_surface; bpp = surface->format->BytesPerPixel; if (bpp == 1) { SDL_Palette* pal = SDL_AllocPalette(256); Uint32 ckey; int useckey = 0; useckey = SDL_GetColorKey(surface, &ckey) == 0; new_surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0); SDL_LockSurface(surface); SDL_LockSurface(new_surface); pixels = static_cast<unsigned char*>(surface->pixels); new_pixels = static_cast<unsigned char*>(new_surface->pixels); new_pitch = new_surface->pitch; memcpy(pal->colors, surface->format->palette->colors, sizeof(SDL_Color) * 256); for (i = 0; i < height; ++i) { x = i * new_pitch; for (j = 0; j < width; ++j) { new_pixels[x] = pixels[(i * surface->h / height) * surface->pitch + j * surface->w / width]; ++x; } } SDL_UnlockSurface(surface); SDL_UnlockSurface(new_surface); SDL_SetSurfacePalette(new_surface, pal); if (useckey) { SDL_SetColorKey(new_surface, SDL_TRUE, ckey); SDL_SetSurfaceRLE(new_surface, SDL_TRUE); } } else { int ix, iy; float fx, fy, fz; unsigned char *p1, *p2, *p3, *p4; new_surface = SDL_CreateRGBSurface(0, width, height, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask); SDL_LockSurface(surface); SDL_LockSurface(new_surface); pixels = static_cast<unsigned char*>(surface->pixels); new_pixels = static_cast<unsigned char*>(new_surface->pixels); new_pitch = new_surface->pitch; for (i = 0; i < height; ++i) { x = i * new_pitch; fy = static_cast<float>(i) * static_cast<float>(surface->h) / static_cast<float>(height); iy = static_cast<int>(fy); fy -= static_cast<float>(iy); for (j = 0; j < width; ++j) { fx = static_cast<float>(j) * static_cast<float>(surface->w) / static_cast<float>(width); ix = static_cast<int>(fx); fx -= static_cast<float>(ix); fz = (fx + fy) / 2; p1 = &pixels[iy * surface->pitch + ix * bpp]; p2 = (iy != surface->h - 1) ? &pixels[(iy + 1) * surface->pitch + ix * bpp] : p1; p3 = (ix != surface->w - 1) ? &pixels[iy * surface->pitch + (ix + 1) * bpp] : p1; p4 = (iy != surface->h - 1 && ix != surface->w - 1) ? &pixels[(iy + 1) * surface->pitch + (ix + 1) * bpp] : p1; new_pixels[x + 0] = static_cast<unsigned char>( (static_cast<float>(p1[0]) * (1 - fy) + static_cast<float>(p2[0]) * fy + static_cast<float>(p1[0]) * (1 - fx) + static_cast<float>(p3[0]) * fx + static_cast<float>(p1[0]) * (1 - fz) + static_cast<float>(p4[0]) * fz) / 3.0 + .5); new_pixels[x + 1] = static_cast<unsigned char>( (static_cast<float>(p1[1]) * (1 - fy) + static_cast<float>(p2[1]) * fy + static_cast<float>(p1[1]) * (1 - fx) + static_cast<float>(p3[1]) * fx + static_cast<float>(p1[1]) * (1 - fz) + static_cast<float>(p4[1]) * fz) / 3.0 + .5); new_pixels[x + 2] = static_cast<unsigned char>( (static_cast<float>(p1[2]) * (1 - fy) + static_cast<float>(p2[2]) * fy + static_cast<float>(p1[2]) * (1 - fx) + static_cast<float>(p3[2]) * fx + static_cast<float>(p1[2]) * (1 - fz) + static_cast<float>(p4[2]) * fz) / 3.0 + .5); if (bpp == 4) { new_pixels[x + 3] = static_cast<unsigned char>( (static_cast<float>(p1[3]) * (1 - fy) + static_cast<float>(p2[3]) * fy + static_cast<float>(p1[3]) * (1 - fx) + static_cast<float>(p3[3]) * fx + static_cast<float>(p1[3]) * (1 - fz) + static_cast<float>(p4[3]) * fz) / 3.0 + .5); } x += bpp; } } SDL_UnlockSurface(surface); SDL_UnlockSurface(new_surface); } return new_surface; }
//Basic Init, create the font, backbuffer, etc WINDOW *curses_init(void) { lastchar = -1; inputdelay = -1; std::string typeface = "Terminus"; std::string blending = "solid"; std::ifstream fin; int faceIndex = 0; int fontsize = 0; //actuall size fin.open("data/FONTDATA"); if (!fin.is_open()){ fontwidth = 8; fontheight = 16; std::ofstream fout;//create data/FONDATA file fout.open("data/FONTDATA"); if(fout.is_open()) { fout << typeface << "\n"; fout << fontwidth << "\n"; fout << fontheight; fout.close(); } } else { getline(fin, typeface); fin >> fontwidth; fin >> fontheight; fin >> fontsize; fin >> blending; if ((fontwidth <= 4) || (fontheight <= 4)) { fontheight = 16; fontwidth = 8; } fin.close(); } fontblending = (blending=="blended"); halfwidth=fontwidth / 2; halfheight=fontheight / 2; if(!InitSDL()) { DebugLog() << "Failed to initialize SDL: " << SDL_GetError() << "\n"; return NULL; } TERMINAL_WIDTH = OPTIONS["TERMINAL_X"]; TERMINAL_HEIGHT = OPTIONS["TERMINAL_Y"]; if(OPTIONS["FULLSCREEN"]) { // Fullscreen mode overrides terminal width/height SDL_DisplayMode display_mode; SDL_GetDesktopDisplayMode(0, &display_mode); TERMINAL_WIDTH = display_mode.w / fontwidth; TERMINAL_HEIGHT = display_mode.h / fontheight; WindowWidth = display_mode.w; WindowHeight = display_mode.h; } else { WindowWidth= OPTIONS["TERMINAL_X"]; if (WindowWidth < FULL_SCREEN_WIDTH) WindowWidth = FULL_SCREEN_WIDTH; WindowWidth *= fontwidth; WindowHeight = OPTIONS["TERMINAL_Y"] * fontheight; } if(!WinCreate()) { DebugLog() << "Failed to create game window: " << SDL_GetError() << "\n"; return NULL; } #ifdef SDLTILES DebugLog() << "Initializing SDL Tiles context\n"; tilecontext = new cata_tiles(renderer); try { tilecontext->init("gfx"); DebugLog() << "Tiles initialized successfully.\n"; } catch(std::string err) { // use_tiles is the cached value of the USE_TILES option. // most (all?) code refers to this to see if cata_tiles should be used. // Setting it to false disables this from getting used. use_tiles = false; } #endif // SDLTILES #ifdef SDLTILES while(!strcasecmp(typeface.substr(typeface.length()-4).c_str(),".bmp") || !strcasecmp(typeface.substr(typeface.length()-4).c_str(),".png")) { DebugLog() << "Loading bitmap font [" + typeface + "].\n" ; typeface = "data/font/" + typeface; SDL_Surface *asciiload = IMG_Load(typeface.c_str()); if(!asciiload || asciiload->w*asciiload->h < (fontwidth * fontheight * 256)) { DebugLog() << "Failed to load bitmap font: " << IMG_GetError() << "\n"; SDL_FreeSurface(asciiload); break; } Uint32 key = SDL_MapRGB(asciiload->format, 0xFF, 0, 0xFF); SDL_SetColorKey(asciiload,SDL_TRUE,key); SDL_Surface *ascii_surf[16]; ascii_surf[0] = SDL_ConvertSurface(asciiload,format,0); SDL_SetSurfaceRLE(ascii_surf[0], true); SDL_FreeSurface(asciiload); for(int a = 1; a < 16; ++a) { ascii_surf[a] = SDL_ConvertSurface(ascii_surf[0],format,0); SDL_SetSurfaceRLE(ascii_surf[a], true); } init_colors(); for(int a = 0; a < 15; ++a) { SDL_LockSurface(ascii_surf[a]); int size = ascii_surf[a]->h * ascii_surf[a]->w; Uint32 *pixels = (Uint32 *)ascii_surf[a]->pixels; Uint32 color = (windowsPalette[a].r << 16) | (windowsPalette[a].g << 8) | windowsPalette[a].b; for(int i=0;i<size;i++) { if(pixels[i] == 0xFFFFFF) pixels[i] = color; } SDL_UnlockSurface(ascii_surf[a]); } if(fontwidth) tilewidth = ascii_surf[0]->w / fontwidth; OutputChar = &OutputImageChar; //convert ascii_surf to SDL_Texture for(int a = 0; a < 16; ++a) { ascii[a] = SDL_CreateTextureFromSurface(renderer,ascii_surf[a]); SDL_FreeSurface(ascii_surf[a]); } mainwin = newwin(get_terminal_height(), get_terminal_width(),0,0); return mainwin; } #endif // SDLTILES std::string sysfnt = find_system_font(typeface, faceIndex); if(sysfnt != "") typeface = sysfnt; //make fontdata compatible with wincurse if(!fexists(typeface.c_str())) { faceIndex = 0; typeface = "data/font/" + typeface + ".ttf"; } //different default font with wincurse if(!fexists(typeface.c_str())) { faceIndex = 0; typeface = "data/font/fixedsys.ttf"; } DebugLog() << "Loading truetype font [" + typeface + "].\n" ; if(fontsize <= 0) fontsize = fontheight - 1; // SDL_ttf handles bitmap fonts size incorrectly if(0 == strcasecmp(typeface.substr(typeface.length() - 4).c_str(), ".fon")) faceIndex = test_face_size(typeface, fontsize, faceIndex); font = TTF_OpenFontIndex(typeface.c_str(), fontsize, faceIndex); if (font == NULL) { DebugLog() << "Failed to load truetype font: " << TTF_GetError() << "\n"; return NULL; } TTF_SetFontStyle(font, TTF_STYLE_NORMAL); // glyph height hack by utunnels // SDL_ttf doesn't use FT_HAS_VERTICAL for function TTF_GlyphMetrics // this causes baseline problems for certain fonts // I can only guess by check a certain tall character... cache_glyphs(); init_colors(); OutputChar = &OutputFontChar; mainwin = newwin(get_terminal_height(), get_terminal_width(),0,0); return mainwin; //create the 'stdscr' window and return its ref }
/* * 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; /* 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) { /* Set the colorkey by color, which needs to be unique */ Uint8 keyR, keyG, keyB, keyA; SDL_GetRGBA(surface->map->info.colorkey, surface->format, &keyR, &keyG, &keyB, &keyA); SDL_SetColorKey(convert, 1, SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA)); /* 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_COLORKEY|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); }