static void SW_DestroyRenderer(SDL_Renderer * renderer) { SW_RenderData *data = (SW_RenderData *) renderer->driverdata; SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); int i; if (data) { for (i = 0; i < SDL_arraysize(data->texture); ++i) { if (data->texture[i]) { DestroyTexture(data->renderer, data->texture[i]); } } if (data->surface.format) { SDL_SetSurfacePalette(&data->surface, NULL); SDL_FreeFormat(data->surface.format); } if (display->palette) { SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data); } if (data->renderer) { data->renderer->DestroyRenderer(data->renderer); } SDL_FreeDirtyRects(&data->dirty); SDL_free(data); } SDL_free(renderer); }
/* * Free a surface created by the above function. */ void SDL_FreeSurface(SDL_Surface * surface) { if (surface == NULL) { return; } if (surface->flags & SDL_DONTFREE) { return; } if (--surface->refcount > 0) { return; } while (surface->locked > 0) { SDL_UnlockSurface(surface); } if (surface->flags & SDL_RLEACCEL) { SDL_UnRLESurface(surface, 0); } if (surface->format) { SDL_SetSurfacePalette(surface, NULL); SDL_FreeFormat(surface->format); surface->format = NULL; } if (surface->map != NULL) { SDL_FreeBlitMap(surface->map); surface->map = NULL; } if (!(surface->flags & SDL_PREALLOC)) { SDL_free(surface->pixels); } SDL_free(surface); }
void SDLFilm::afterSet() { if (!texture) return; SDL_FreeFormat(pixelFormat); pixelFormat = nullptr; pixels = nullptr; SDL_UnlockTexture(texture); }
SDL_Surface * SDL_DisplayFormatAlpha(SDL_Surface * surface) { SDL_PixelFormat *vf; SDL_PixelFormat *format; SDL_Surface *converted; /* default to ARGB8888 */ Uint32 amask = 0xff000000; Uint32 rmask = 0x00ff0000; Uint32 gmask = 0x0000ff00; Uint32 bmask = 0x000000ff; if (!SDL_PublicSurface) { SDL_SetError("No video mode has been set"); return NULL; } vf = SDL_PublicSurface->format; switch (vf->BytesPerPixel) { case 2: /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. For anything else (like ARGB4444) it doesn't matter since we have no special code for it anyway */ if ((vf->Rmask == 0x1f) && (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { rmask = 0xff; bmask = 0xff0000; } break; case 3: case 4: /* Keep the video format, as long as the high 8 bits are unused or alpha */ if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) { rmask = 0xff; bmask = 0xff0000; } break; default: /* We have no other optimised formats right now. When/if a new optimised alpha format is written, add the converter here */ break; } format = SDL_AllocFormat(SDL_MasksToPixelFormatEnum(32, rmask, gmask, bmask, amask)); if (!format) { return NULL; } converted = SDL_ConvertSurface(surface, format, SDL_RLEACCEL); SDL_FreeFormat(format); return converted; }
// create a bitmapped font with a drop-shadow. bool NXFont::InitBitmapCharsShadowed(SDL_Surface *sheet, uint32_t fgcolor, \ uint32_t color, uint32_t shadowcolor) { Uint32 format = screen->Format()->format; NXFont fgfont, shadowfont; SDL_Rect dstrect; // create temporary fonts in the fg and shadow color if (fgfont.InitBitmapChars(sheet, fgcolor, color)) return 1; if (shadowfont.InitBitmapChars(sheet, fgcolor, shadowcolor)) return 1; SDL_PixelFormat* pxformat = SDL_AllocFormat(format); if (!pxformat) { staterr("InitBitmapChars: SDL_AllocFormat failed: %s", SDL_GetError()); return 1; } // now combine the two fonts uint32_t transp = SDL_MapRGB(pxformat, 0, 0, 0); for(int i=0;i<NUM_FONT_LETTERS;i++) { if (fgfont.letters[i]) { letters[i] = SDL_CreateRGBSurface(0, \ BITMAP_CHAR_WIDTH+1, BITMAP_CHAR_HEIGHT+1+SHADOW_OFFSET, pxformat->BitsPerPixel, \ pxformat->Rmask, pxformat->Gmask, pxformat->Bmask, pxformat->Amask); SDL_FillRect(letters[i], NULL, transp); SDL_SetColorKey(letters[i], SDL_TRUE, transp); dstrect.x = 0; dstrect.y = SHADOW_OFFSET; SDL_BlitSurface(shadowfont.letters[i], NULL, letters[i], &dstrect); dstrect.x = 0; dstrect.y = 0; SDL_BlitSurface(fgfont.letters[i], NULL, letters[i], &dstrect); } } SDL_FreeFormat(pxformat); return 0; }
Graphics::Texture* ResourceManager::texture(const string& filename) { if (_textures.count(filename)) { return _textures.at(filename).get(); } string ext = filename.substr(filename.length() - 4); Graphics::Texture* texture = nullptr; if (ext == ".png") { // @fixme: this section looks quite ugly. we should try to do something with it someday SDL_Surface* tempSurface = IMG_Load(string(CrossPlatform::findFalltergeistDataPath() + "/" +filename).c_str()); if (tempSurface == NULL) { throw Exception("ResourceManager::texture(name) - cannot load texture from file " + filename + ": " + IMG_GetError()); } SDL_PixelFormat* pixelFormat = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888); SDL_Surface* tempSurface2 = SDL_ConvertSurface(tempSurface, pixelFormat, 0); texture = new Graphics::Texture(tempSurface2); SDL_FreeFormat(pixelFormat); SDL_FreeSurface(tempSurface); SDL_FreeSurface(tempSurface2); } else if (ext == ".rix") { auto rix = rixFileType(filename); if (!rix) return nullptr; texture = new Graphics::Texture(rix->width(), rix->height()); texture->loadFromRGBA(rix->rgba()); } else if (ext == ".frm") { auto frm = frmFileType(filename); if (!frm) return nullptr; texture = new Graphics::Texture(frm->width(), frm->height()); texture->loadFromRGBA(frm->rgba(palFileType("color.pal"))); texture->setMask(*frm->mask(palFileType("color.pal"))); } else { throw Exception("ResourceManager::surface() - unknown image type:" + filename); } _textures.insert(make_pair(filename, unique_ptr<Graphics::Texture>(texture))); return texture; }
Uint32 SDLHardwareRenderDevice::MapRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { Uint32 u_format = SDL_GetWindowPixelFormat(window); SDL_PixelFormat* format = SDL_AllocFormat(u_format); if (format) { Uint32 ret = SDL_MapRGBA(format, r, g, b, a); SDL_FreeFormat(format); return ret; } else { return 0; } }
SDL_Surface * SDL_ConvertSurfaceFormat(SDL_Surface * surface, Uint32 pixel_format, Uint32 flags) { SDL_PixelFormat *fmt; SDL_Surface *convert = NULL; fmt = SDL_AllocFormat(pixel_format); if (fmt) { convert = SDL_ConvertSurface(surface, fmt, flags); SDL_FreeFormat(fmt); } return convert; }
void GraphicsTerminate(GraphicsDevice *g) { debug(D_NORMAL, "Shutting down video...\n"); CArrayTerminate(&g->validModes); SDL_FreeSurface(g->icon); SDL_DestroyTexture(g->screen); SDL_DestroyTexture(g->bkg); SDL_DestroyTexture(g->brightnessOverlay); SDL_DestroyRenderer(g->renderer); SDL_FreeFormat(g->Format); SDL_DestroyWindow(g->window); SDL_VideoQuit(); CFREE(g->buf); }
static SDL_Surface* sload(const char* const path) { SDL_Surface* const bmp = SDL_LoadBMP(path); if(bmp == NULL) { puts(SDL_GetError()); exit(1); } SDL_PixelFormat* const allocation = SDL_AllocFormat(SDL_PIXELFORMAT_RGB888); SDL_Surface* const converted = SDL_ConvertSurface(bmp, allocation, 0); SDL_FreeFormat(allocation); SDL_FreeSurface(bmp); return converted; }
/** * \brief Returns a buffer of the raw pixels of this surface. * * Pixels returned have the RGBA 32-bit format. * * \return The pixel buffer. */ std::string Surface::get_pixels() const { if (!software_destination && Video::is_acceleration_enabled()) { // The surface is in GPU. return ""; // TODO } const int num_pixels = get_width() * get_height(); if (internal_surface == nullptr) { // No surface: this may be a color. if (internal_color == nullptr) { // No color either: fully transparent surface. return std::string(num_pixels * 4, (size_t) 0); } uint8_t r, g, b, a; internal_color->get_components(r, g, b, a); std::string pixel; pixel += r; pixel += g; pixel += b; pixel += a; std::ostringstream oss; for (int i = 0; i < num_pixels; ++i) { oss << pixel; } return oss.str(); } if (internal_surface->format->format == SDL_PIXELFORMAT_ABGR8888) { // No conversion needed. const char* buffer = static_cast<const char*>(internal_surface->pixels); return std::string(buffer, num_pixels * 4); } // Convert to RGBA format. SDL_PixelFormat* format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888); // TODO keep this object SDL_Surface_UniquePtr converted_surface(SDL_ConvertSurface( internal_surface.get(), format, 0 )); SDL_FreeFormat(format); Debug::check_assertion(converted_surface != nullptr, "Failed to convert pixels to RGBA format"); const char* buffer = static_cast<const char*>(converted_surface->pixels); return std::string(buffer, num_pixels * 4); }
void WinDestroy() { if(joystick) { SDL_JoystickClose(joystick); joystick = 0; } if(format) SDL_FreeFormat(format); format = NULL; if(renderer) SDL_DestroyRenderer(renderer); renderer = NULL; if(window) SDL_DestroyWindow(window); window = NULL; };
Uint32 SDLHardwareImage::MapRGB(Uint8 r, Uint8 g, Uint8 b) { if (!surface) return 0; Uint32 u_format; SDL_QueryTexture(surface, &u_format, NULL, NULL, NULL); SDL_PixelFormat* format = SDL_AllocFormat(u_format); if (format) { Uint32 ret = SDL_MapRGB(format, r, g, b); SDL_FreeFormat(format); return ret; } else { return 0; } }
void SDLHardwareRenderDevice::drawPixel( int x, int y, Uint32 color ) { Uint32 u_format = SDL_GetWindowPixelFormat(window); SDL_PixelFormat* format = SDL_AllocFormat(u_format); if (!format) return; SDL_Color rgba; SDL_GetRGBA(color, format, &rgba.r, &rgba.g, &rgba.b, &rgba.a); SDL_FreeFormat(format); SDL_SetRenderDrawColor(renderer, rgba.r, rgba.g, rgba.b, rgba.a); SDL_RenderDrawPoint(renderer, x, y); }
void SDLHardwareImage::fillWithColor(Uint32 color) { if (!surface) return; Uint32 u_format; SDL_QueryTexture(surface, &u_format, NULL, NULL, NULL); SDL_PixelFormat* format = SDL_AllocFormat(u_format); if (!format) return; SDL_Color rgba; SDL_GetRGBA(color, format, &rgba.r, &rgba.g, &rgba.b, &rgba.a); SDL_FreeFormat(format); SDL_SetRenderTarget(renderer, surface); SDL_SetTextureBlendMode(surface, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(renderer, rgba.r, rgba.g , rgba.b, rgba.a); SDL_RenderClear(renderer); SDL_SetRenderTarget(renderer, NULL); }
/* * Set the pixel at (x, y) to the given value */ void SDLHardwareImage::drawPixel(int x, int y, Uint32 pixel) { if (!surface) return; Uint32 u_format; SDL_QueryTexture(surface, &u_format, NULL, NULL, NULL); SDL_PixelFormat* format = SDL_AllocFormat(u_format); if (!format) return; SDL_Color rgba; SDL_GetRGBA(pixel, format, &rgba.r, &rgba.g, &rgba.b, &rgba.a); SDL_FreeFormat(format); SDL_SetRenderTarget(renderer, surface); SDL_SetTextureBlendMode(surface, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(renderer, rgba.r, rgba.g, rgba.b, rgba.a); SDL_RenderDrawPoint(renderer, x, y); SDL_SetRenderTarget(renderer, NULL); }
int main(int argc, char *argv[]) { google::InitGoogleLogging(argv[0]); // Setup the filename if(argc != 2) { printUsage(); return 1; } else { std::string romName = argv[1]; LOG(INFO) << "Reading rom " << romName; std::vector<unsigned char> rom = Chip8::FileUtils::readRom(romName); LOG(INFO) << "Rom size = " << rom.size(); for(unsigned int i = 0; i < rom.size(); i++) { if(!Chip8::Memory::instance().write(Chip8::Memory::StartAddress + i, rom.at(i))) { LOG(INFO) << "Failed to load rom into " << (int) Chip8::Memory::StartAddress + i; std::cout << "Failed to load rom into " << (int) Chip8::Memory::StartAddress + i << std::endl; return 1; } } LOG(INFO) << "Loaded rom"; for(unsigned int i = 0; i < rom.size(); i++) { unsigned char data = 0; Chip8::Memory::instance().read(Chip8::Memory::StartAddress + i, data); LOG(INFO) << (int) data; } } // Setup SDL. // Chip8 has a render size of 64x32 int upScale = 24; int error = SDL_Init(SDL_INIT_VIDEO); if(error < 0) { LOG(FATAL) << "Failed to init SDL - " << SDL_GetError(); } SDL_Window *window = SDL_CreateWindow("Chip8", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Chip8::Video::Width * upScale, Chip8::Video::Height * upScale, SDL_WINDOW_RESIZABLE); //SDL_Window *window = SDL_CreateWindow("Chip8", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP); if(window == NULL) { LOG(FATAL) << "Failed to create window - " << SDL_GetError(); } SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if(renderer == NULL) { LOG(FATAL) << "Failed to create renderer - " << SDL_GetError(); } SDL_RenderSetScale(renderer, upScale, upScale); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0); error = SDL_RenderSetLogicalSize(renderer, Chip8::Video::Width, Chip8::Video::Height); if(error < 0) { LOG(FATAL) << "Failed to set render size - " << SDL_GetError(); } // Create the texture that will be drawn to the screen every frame. SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, Chip8::Video::Width, Chip8::Video::Height); if(texture == NULL) { LOG(FATAL) << "Failed to create texture - " << SDL_GetError(); } // Make sure to set the correct pixel format for the Video module SDL_PixelFormat *format = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888); if(format == NULL) { LOG(FATAL) << "Failed to create format - " << SDL_GetError(); } Chip8::Video::instance().setPixelFormat(format); // Load fonts into memory for(unsigned char i = 0; i < 0xF + 1; i++) { LOG(INFO) << "Getting font sprite " << (int) i; const unsigned char *sprite = Chip8::Fonts::getSprite(i); for(unsigned char j = 0; j < Chip8::Fonts::SpriteHeight; j++) { unsigned int address = 0x0 + (i * Chip8::Fonts::SpriteHeight) + j; LOG(INFO) << "Loading font sprite byte " << (int) j << " to memory address " << address; if(!Chip8::Memory::instance().write(address, sprite[j])) { LOG(INFO) << "Failed to load font sprite " << (int) i << " into memory address " << address; } } } // Jump to start of rom Chip8::Cpu::instance().jump(Chip8::Memory::StartAddress); SDL_Event event; Uint32 lastFrame = SDL_GetTicks(); Uint32 sixtyFrame = 1000 / 60; do { Uint32 currentFrame = SDL_GetTicks(); Uint32 elapsed = currentFrame - lastFrame; lastFrame = currentFrame; if(elapsed < sixtyFrame) { SDL_Delay(sixtyFrame - elapsed); } // Handle event SDL_PollEvent(&event); switch(event.type) { case SDL_KEYDOWN: LOG(INFO) << "Key pressed " << event.key.keysym.scancode; if(event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { LOG(INFO) << "Escape pressed exiting now"; SDL_FreeFormat(format); SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; } else if(Chip8::InputManager::instance().IsWaitingForKeyPress) { unsigned char hex; Chip8::InputManager::instance().toHex(event.key.keysym.scancode, hex); LOG(INFO) << "InputManager waiting for key press key pressed = " << hex; if(Chip8::InputManager::instance().isValidKey(hex)) { LOG(INFO) << "Valid key detected, setting register " << Chip8::InputManager::instance().KeyPressRegister; Chip8::InputManager::instance().IsWaitingForKeyPress = false; Chip8::Memory::instance().setRegister(Chip8::InputManager::KeyPressRegister, hex); } } break; } if(!Chip8::InputManager::instance().IsWaitingForKeyPress) { // Cpu step Chip8::Cpu::instance().step(); Chip8::Timers::instance().step(); } // Render screen SDL_RenderClear(renderer); SDL_UpdateTexture(texture, NULL, Chip8::Video::instance().getPixels(), Chip8::Video::Width * sizeof(Uint32)); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } while(event.type != SDL_QUIT); SDL_FreeFormat(format); SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
int main(int argc, char *argv[]) { Uint32 *buf = NULL; SDL_Texture *t = NULL; SDL_PixelFormat *format = NULL; SDL_Window *window = NULL; SDL_Renderer *renderer = NULL; // Init SDL if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("SDL_Init error: %s\n", SDL_GetError()); goto bail; } // Create surface buf = malloc(SCREEN_W * SCREEN_H * sizeof(Uint32)); if (buf == NULL) { printf("Failed to allocate buffer\n"); goto bail; } // Create display window based on image size window = SDL_CreateWindow( argv[1], SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_W, SCREEN_H, 0); if (window == NULL) { printf("Failed to create window: %s\n", SDL_GetError()); goto bail; } format = SDL_AllocFormat(SDL_GetWindowPixelFormat(window)); if (format == NULL) { printf("Failed to alloc pixel format: %s\n", SDL_GetError()); goto bail; } renderer = SDL_CreateRenderer(window, -1, 0); if (renderer == NULL) { printf("Failed to create renderer: %s\n", SDL_GetError()); goto bail; } SDL_RenderSetLogicalSize(renderer, SCREEN_W, SCREEN_H); // Create texture t = SDL_CreateTexture( renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_W, SCREEN_H); if (t == NULL) { printf("Failed to create screen texture: %s\n", SDL_GetError()); goto bail; } // Draw a palette on the buffer #define MAX(x, y) ((x) > (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define CLAMP(v, _min, _max) MAX((_min), MIN((_max), (v))) #define GREY_MARGIN 20 for (int y = 0; y < SCREEN_H; y++) { Uint8 v = (Uint8)CLAMP((SCREEN_H - y) * 255.0 / (SCREEN_H / 2), 0, 255); double s = CLAMP(y * 1.0 / (SCREEN_H / 2), 0.0, 1.0); for (int x = 0; x < SCREEN_W; x++) { SDL_Color c; c.a = 255; if (x < SCREEN_W - GREY_MARGIN) { double h = x * 360.0 / (SCREEN_W - GREY_MARGIN); double ff; Uint8 p, q, t; long i; double hh = h; if (hh >= 360.0) { hh = 0.0; } hh /= 60.0; i = (long)hh; ff = hh - i; p = (Uint8)CLAMP(v * (1.0 - s), 0, 255); q = (Uint8)CLAMP(v * (1.0 - (s * ff)), 0, 255); t = (Uint8)CLAMP(v * (1.0 - (s * (1.0 - ff))), 0, 255); switch (i) { case 0: c.r = v; c.g = t; c.b = p; break; case 1: c.r = q; c.g = v; c.b = p; break; case 2: c.r = p; c.g = v; c.b = t; break; case 3: c.r = p; c.g = q; c.b = v; break; case 4: c.r = t; c.g = p; c.b = v; break; case 5: default: c.r = v; c.g = p; c.b = q; break; } } else { c.r = c.g = c.b = (Uint8)CLAMP((SCREEN_H - y) * 255.0 / SCREEN_H, 0, 255); } Uint32 pixel = SDL_MapRGBA(format, c.r, c.g, c.b, c.a); buf[x + y*SCREEN_W] = pixel; } } // Render to texture SDL_UpdateTexture(t, NULL, buf, SCREEN_W * sizeof(Uint32)); if (SDL_RenderClear(renderer) != 0) { printf("Failed to clear renderer: %s\n", SDL_GetError()); goto bail; } // Blit the texture to screen if (SDL_RenderCopy(renderer, t, NULL, NULL) != 0) { printf("Failed to blit surface: %s\n", SDL_GetError()); goto bail; } // Display SDL_RenderPresent(renderer); // Wait for keypress to exit bool quit = false; while (!quit) { SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_KEYDOWN || e.type == SDL_QUIT) { quit = true; } } SDL_Delay(100); } bail: SDL_DestroyTexture(t); free(buf); SDL_DestroyRenderer(renderer); SDL_FreeFormat(format); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
void destructor(State & state, SDL_PixelFormat * pixelformat){ SDL_FreeFormat(pixelformat); }
int SDL_WM_ToggleFullScreen(SDL_Surface * surface) { int length; void *pixels; Uint8 *src, *dst; int row; int window_w; int window_h; if (!SDL_PublicSurface) { SDL_SetError("SDL_SetVideoMode() hasn't been called"); return 0; } /* Copy the old bits out */ length = SDL_PublicSurface->w * SDL_PublicSurface->format->BytesPerPixel; pixels = SDL_malloc(SDL_PublicSurface->h * length); if (pixels) { src = (Uint8*)SDL_PublicSurface->pixels; dst = (Uint8*)pixels; for (row = 0; row < SDL_PublicSurface->h; ++row) { SDL_memcpy(dst, src, length); src += SDL_PublicSurface->pitch; dst += length; } } /* Do the physical mode switch */ if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) { if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) { return 0; } SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; } else { if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) { return 0; } SDL_PublicSurface->flags |= SDL_FULLSCREEN; } /* Recreate the screen surface */ SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); if (!SDL_WindowSurface) { /* We're totally hosed... */ return 0; } /* Center the public surface in the window surface */ SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h); SDL_VideoViewport.x = (window_w - SDL_VideoSurface->w)/2; SDL_VideoViewport.y = (window_h - SDL_VideoSurface->h)/2; SDL_VideoViewport.w = SDL_VideoSurface->w; SDL_VideoViewport.h = SDL_VideoSurface->h; /* Do some shuffling behind the application's back if format changes */ if (SDL_VideoSurface->format->format != SDL_WindowSurface->format->format) { if (SDL_ShadowSurface) { if (SDL_ShadowSurface->format->format == SDL_WindowSurface->format->format) { /* Whee! We don't need a shadow surface anymore! */ SDL_VideoSurface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(SDL_VideoSurface); SDL_free(SDL_ShadowSurface->pixels); SDL_VideoSurface = SDL_ShadowSurface; SDL_VideoSurface->flags |= SDL_PREALLOC; SDL_ShadowSurface = NULL; } else { /* No problem, just change the video surface format */ SDL_FreeFormat(SDL_VideoSurface->format); SDL_VideoSurface->format = SDL_WindowSurface->format; SDL_VideoSurface->format->refcount++; SDL_InvalidateMap(SDL_ShadowSurface->map); } } else { /* We can make the video surface the shadow surface */ SDL_ShadowSurface = SDL_VideoSurface; SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); SDL_ShadowSurface->pixels = SDL_malloc(SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); if (!SDL_ShadowSurface->pixels) { /* Uh oh, we're hosed */ SDL_ShadowSurface = NULL; return 0; } SDL_ShadowSurface->flags &= ~SDL_PREALLOC; SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0); SDL_VideoSurface->flags = SDL_ShadowSurface->flags; SDL_VideoSurface->flags |= SDL_PREALLOC; SDL_FreeFormat(SDL_VideoSurface->format); SDL_VideoSurface->format = SDL_WindowSurface->format; SDL_VideoSurface->format->refcount++; SDL_VideoSurface->w = SDL_ShadowSurface->w; SDL_VideoSurface->h = SDL_ShadowSurface->h; } } /* Update the video surface */ SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels + SDL_VideoViewport.y * SDL_VideoSurface->pitch + SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel); SDL_SetClipRect(SDL_VideoSurface, NULL); /* Copy the old bits back */ if (pixels) { src = (Uint8*)pixels; dst = (Uint8*)SDL_PublicSurface->pixels; for (row = 0; row < SDL_PublicSurface->h; ++row) { SDL_memcpy(dst, src, length); src += length; dst += SDL_PublicSurface->pitch; } SDL_Flip(SDL_PublicSurface); SDL_free(pixels); } /* We're done! */ return 1; }
void GraphicsInitialize(GraphicsDevice *g) { if (g->IsInitialized && !g->cachedConfig.RestartFlags) { return; } if (!g->IsWindowInitialized) { char buf[CDOGS_PATH_MAX]; GetDataFilePath(buf, "cdogs_icon.bmp"); g->icon = IMG_Load(buf); AddSupportedGraphicsModes(g); g->IsWindowInitialized = true; } g->IsInitialized = false; const int w = g->cachedConfig.Res.x; const int h = g->cachedConfig.Res.y; const bool initRenderer = !!(g->cachedConfig.RestartFlags & RESTART_RESOLUTION); const bool initTextures = !!(g->cachedConfig.RestartFlags & (RESTART_RESOLUTION | RESTART_SCALE_MODE)); const bool initBrightness = !!(g->cachedConfig.RestartFlags & (RESTART_RESOLUTION | RESTART_SCALE_MODE | RESTART_BRIGHTNESS)); if (initRenderer) { Uint32 sdlFlags = SDL_WINDOW_RESIZABLE; if (g->cachedConfig.Fullscreen) { sdlFlags |= SDL_WINDOW_FULLSCREEN; } LOG(LM_GFX, LL_INFO, "graphics mode(%dx%d %dx)", w, h, g->cachedConfig.ScaleFactor); // Get the previous window's size and recreate it Vec2i windowSize = Vec2iNew( w * g->cachedConfig.ScaleFactor, h * g->cachedConfig.ScaleFactor); if (g->window) { SDL_GetWindowSize(g->window, &windowSize.x, &windowSize.y); } LOG(LM_GFX, LL_DEBUG, "destroying previous renderer"); SDL_DestroyTexture(g->screen); SDL_DestroyTexture(g->bkg); SDL_DestroyTexture(g->brightnessOverlay); SDL_DestroyRenderer(g->renderer); SDL_FreeFormat(g->Format); SDL_DestroyWindow(g->window); LOG(LM_GFX, LL_DEBUG, "creating window %dx%d flags(%X)", windowSize.x, windowSize.y, sdlFlags); if (SDL_CreateWindowAndRenderer( windowSize.x, windowSize.y, sdlFlags, &g->window, &g->renderer) == -1 || g->window == NULL || g->renderer == NULL) { LOG(LM_GFX, LL_ERROR, "cannot create window or renderer: %s", SDL_GetError()); return; } char title[32]; sprintf(title, "C-Dogs SDL %s%s", g->cachedConfig.IsEditor ? "Editor " : "", CDOGS_SDL_VERSION); LOG(LM_GFX, LL_DEBUG, "setting title(%s) and icon", title); SDL_SetWindowTitle(g->window, title); SDL_SetWindowIcon(g->window, g->icon); g->Format = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888); if (SDL_RenderSetLogicalSize(g->renderer, w, h) != 0) { LOG(LM_GFX, LL_ERROR, "cannot set renderer logical size: %s", SDL_GetError()); return; } GraphicsSetBlitClip( g, 0, 0, g->cachedConfig.Res.x - 1, g->cachedConfig.Res.y - 1); } if (initTextures) { if (!initRenderer) { SDL_DestroyTexture(g->screen); SDL_DestroyTexture(g->bkg); SDL_DestroyTexture(g->brightnessOverlay); } // Set render scale mode const char *renderScaleQuality = "nearest"; switch ((ScaleMode)ConfigGetEnum(&gConfig, "Graphics.ScaleMode")) { case SCALE_MODE_NN: renderScaleQuality = "nearest"; break; case SCALE_MODE_BILINEAR: renderScaleQuality = "linear"; break; default: CASSERT(false, "unknown scale mode"); break; } LOG(LM_GFX, LL_DEBUG, "setting scale quality %s", renderScaleQuality); if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, renderScaleQuality)) { LOG(LM_GFX, LL_WARN, "cannot set render quality hint: %s", SDL_GetError()); } g->screen = CreateTexture( g->renderer, SDL_TEXTUREACCESS_STREAMING, Vec2iNew(w, h), SDL_BLENDMODE_BLEND, 255); if (g->screen == NULL) { return; } CFREE(g->buf); CCALLOC(g->buf, GraphicsGetMemSize(&g->cachedConfig)); g->bkg = CreateTexture( g->renderer, SDL_TEXTUREACCESS_STATIC, Vec2iNew(w, h), SDL_BLENDMODE_NONE, 255); if (g->bkg == NULL) { return; } } if (initBrightness) { if (!initRenderer && !initTextures) { SDL_DestroyTexture(g->brightnessOverlay); } const int brightness = ConfigGetInt(&gConfig, "Graphics.Brightness"); // Alpha is approximately 50% max const Uint8 alpha = (Uint8)(brightness > 0 ? brightness : -brightness) * 13; g->brightnessOverlay = CreateTexture( g->renderer, SDL_TEXTUREACCESS_STATIC, Vec2iNew(w, h), SDL_BLENDMODE_BLEND, alpha); if (g->brightnessOverlay == NULL) { return; } const color_t overlayColour = brightness > 0 ? colorWhite : colorBlack; DrawRectangle(g, Vec2iZero(), g->cachedConfig.Res, overlayColour, 0); SDL_UpdateTexture( g->brightnessOverlay, NULL, g->buf, g->cachedConfig.Res.x * sizeof(Uint32)); memset(g->buf, 0, GraphicsGetMemSize(&g->cachedConfig)); g->cachedConfig.Brightness = brightness; } g->IsInitialized = true; g->cachedConfig.Res.x = w; g->cachedConfig.Res.y = h; g->cachedConfig.RestartFlags = 0; }
SDL_Surface * SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) { SDL_DisplayMode desktop_mode; int display = GetVideoDisplay(); int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); int window_w; int window_h; Uint32 window_flags; Uint32 surface_flags; if (!SDL_GetVideoDevice()) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { return NULL; } } SDL_GetDesktopDisplayMode(display, &desktop_mode); if (width == 0) { width = desktop_mode.w; } if (height == 0) { height = desktop_mode.h; } if (bpp == 0) { bpp = SDL_BITSPERPIXEL(desktop_mode.format); } /* See if we can simply resize the existing window and surface */ if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) { return SDL_PublicSurface; } /* Destroy existing window */ SDL_PublicSurface = NULL; if (SDL_ShadowSurface) { SDL_ShadowSurface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(SDL_ShadowSurface); SDL_ShadowSurface = NULL; } if (SDL_VideoSurface) { SDL_VideoSurface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(SDL_VideoSurface); SDL_VideoSurface = NULL; } if (SDL_VideoContext) { /* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */ SDL_GL_DeleteContext(SDL_VideoContext); SDL_VideoContext = NULL; } if (SDL_VideoWindow) { SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y); SDL_DestroyWindow(SDL_VideoWindow); } /* Set up the event filter */ if (!SDL_GetEventFilter(NULL, NULL)) { SDL_SetEventFilter(SDL_CompatEventFilter, NULL); } /* Create a new window */ window_flags = SDL_WINDOW_SHOWN; if (flags & SDL_FULLSCREEN) { window_flags |= SDL_WINDOW_FULLSCREEN; } if (flags & SDL_OPENGL) { window_flags |= SDL_WINDOW_OPENGL; } if (flags & SDL_RESIZABLE) { window_flags |= SDL_WINDOW_RESIZABLE; } if (flags & SDL_NOFRAME) { window_flags |= SDL_WINDOW_BORDERLESS; } GetEnvironmentWindowPosition(width, height, &window_x, &window_y); SDL_VideoWindow = SDL_CreateWindow(wm_title, window_x, window_y, width, height, window_flags); if (!SDL_VideoWindow) { return NULL; } SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon); SetupScreenSaver(flags); window_flags = SDL_GetWindowFlags(SDL_VideoWindow); surface_flags = 0; if (window_flags & SDL_WINDOW_FULLSCREEN) { surface_flags |= SDL_FULLSCREEN; } if ((window_flags & SDL_WINDOW_OPENGL) && (flags & SDL_OPENGL)) { surface_flags |= SDL_OPENGL; } if (window_flags & SDL_WINDOW_RESIZABLE) { surface_flags |= SDL_RESIZABLE; } if (window_flags & SDL_WINDOW_BORDERLESS) { surface_flags |= SDL_NOFRAME; } SDL_VideoFlags = flags; /* If we're in OpenGL mode, just create a stub surface and we're done! */ if (flags & SDL_OPENGL) { SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow); if (!SDL_VideoContext) { return NULL; } if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) { return NULL; } SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0); if (!SDL_VideoSurface) { return NULL; } SDL_VideoSurface->flags |= surface_flags; SDL_PublicSurface = SDL_VideoSurface; return SDL_PublicSurface; } /* Create the screen surface */ SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); if (!SDL_WindowSurface) { return NULL; } /* Center the public surface in the window surface */ SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h); SDL_VideoViewport.x = (window_w - width)/2; SDL_VideoViewport.y = (window_h - height)/2; SDL_VideoViewport.w = width; SDL_VideoViewport.h = height; SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0); SDL_VideoSurface->flags |= surface_flags; SDL_VideoSurface->flags |= SDL_DONTFREE; SDL_FreeFormat(SDL_VideoSurface->format); SDL_VideoSurface->format = SDL_WindowSurface->format; SDL_VideoSurface->format->refcount++; SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels + SDL_VideoViewport.y * SDL_VideoSurface->pitch + SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel); SDL_SetClipRect(SDL_VideoSurface, NULL); /* Create a shadow surface if necessary */ if ((bpp != SDL_VideoSurface->format->BitsPerPixel) && !(flags & SDL_ANYFORMAT)) { SDL_ShadowSurface = SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0); if (!SDL_ShadowSurface) { return NULL; } SDL_ShadowSurface->flags |= surface_flags; SDL_ShadowSurface->flags |= SDL_DONTFREE; /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */ if (SDL_ShadowSurface->format->palette) { SDL_ShadowSurface->flags |= SDL_HWPALETTE; SDL_DitherColors(SDL_ShadowSurface->format->palette->colors, SDL_ShadowSurface->format->BitsPerPixel); } SDL_FillRect(SDL_ShadowSurface, NULL, SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0)); } SDL_PublicSurface = (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface); ClearVideoSurface(); /* We're finally done! */ return SDL_PublicSurface; }
SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) { const SDL_PixelFormat *fmt; SDL_bool needAlpha; Uint32 i; Uint32 format; SDL_Texture *texture; CHECK_RENDERER_MAGIC(renderer, NULL); if (!surface) { SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); return NULL; } /* See what the best texture format is */ fmt = surface->format; if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) { needAlpha = SDL_TRUE; } else { needAlpha = SDL_FALSE; } format = renderer->info.texture_formats[0]; for (i = 0; i < renderer->info.num_texture_formats; ++i) { if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) && SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) { format = renderer->info.texture_formats[i]; break; } } texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, surface->w, surface->h); if (!texture) { return NULL; } if (format == surface->format->format) { if (SDL_MUSTLOCK(surface)) { SDL_LockSurface(surface); SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); SDL_UnlockSurface(surface); } else { SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); } } else { SDL_PixelFormat *dst_fmt; SDL_Surface *temp = NULL; /* Set up a destination surface for the texture update */ dst_fmt = SDL_AllocFormat(format); temp = SDL_ConvertSurface(surface, dst_fmt, 0); SDL_FreeFormat(dst_fmt); if (temp) { SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch); SDL_FreeSurface(temp); } else { SDL_DestroyTexture(texture); return NULL; } } { Uint8 r, g, b, a; SDL_BlendMode blendMode; SDL_GetSurfaceColorMod(surface, &r, &g, &b); SDL_SetTextureColorMod(texture, r, g, b); SDL_GetSurfaceAlphaMod(surface, &a); SDL_SetTextureAlphaMod(texture, a); if (SDL_GetColorKey(surface, NULL) == 0) { /* We converted to a texture with alpha format */ SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); } else { SDL_GetSurfaceBlendMode(surface, &blendMode); SDL_SetTextureBlendMode(texture, blendMode); } } return texture; }
// Create a font from a bitmapped font sheet. // sheet: a 8bpp (paletted) sheet to create the font from. // fgindex: color index of foreground color of letters. // color: the color you want the letters to be. bool NXFont::InitBitmapChars(SDL_Surface *sheet, uint32_t fgcolor, uint32_t color) { Uint32 format = screen->Format()->format; SDL_Rect srcrect, dstrect; SDL_Surface *letter; int x, y, i; SDL_PixelFormat* pxformat = SDL_AllocFormat(format); if (!pxformat) { staterr("InitBitmapChars: SDL_AllocFormat failed: %s", SDL_GetError()); return 1; } // NULL out letters we don't have a character for memset(this->letters, 0, sizeof(this->letters)); // change the color of the letters by messing with the palette on the sheet ReplaceColor(sheet, fgcolor, color); // start at the top of the letter sheet. x = 0; y = 0; for(i=0;bitmap_map[i];i++) { uint8_t ch = bitmap_map[i]; //stat("copying letter %d: '%c' from [%d,%d]", i, ch, x, y); // make character surface one pixel larger than the actual char so that there // is some space between letters in autospaced text such as on the menus. letter = SDL_CreateRGBSurface(0, \ BITMAP_CHAR_WIDTH+1, BITMAP_CHAR_HEIGHT+1, pxformat->BitsPerPixel, \ pxformat->Rmask, pxformat->Gmask, pxformat->Bmask, pxformat->Amask); if (!letter) { staterr("InitBitmapChars: failed to create surface for character %d/%d", i, ch); SDL_FreeFormat(pxformat); return 1; } SDL_FillRect(letter, NULL, SDL_MapRGB(pxformat, 0, 0, 0)); // copy letter off of sheet srcrect.x = x; srcrect.y = y; srcrect.w = BITMAP_CHAR_WIDTH; srcrect.h = BITMAP_CHAR_HEIGHT; dstrect.x = 0; dstrect.y = 0; SDL_BlitSurface(sheet, &srcrect, letter, &dstrect); // make background transparent and copy into final position SDL_SetColorKey(letter, SDL_TRUE, SDL_MapRGB(pxformat, 0, 0, 0)); SDL_PixelFormat * format = screen->Format(); letters[ch] = SDL_ConvertSurfaceFormat(letter, format->format, 0); SDL_FreeSurface(letter); // letters[ch] = letter; // advance to next position on sheet x += BITMAP_SPAC_WIDTH; if (x >= sheet->w) { x = 0; y += BITMAP_SPAC_HEIGHT; } } return 0; }
SDLWindowManager::SDLWindowManager(Application* application): WindowManager(application) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == -1) { throw RuntimeException("SDL initialization failed."); } int displayCount = SDL_GetNumVideoDisplays(); displays.resize(displayCount); primaryDisplay = &displays[0]; for (int i = 0; i < displayCount; ++i) { Display* display = &displays[i]; const char* displayName = SDL_GetDisplayName(i); if (displayName) { display->setName(displayName); } SDL_DisplayMode sdlCurrentDisplayMode; SDL_GetCurrentDisplayMode(i, &sdlCurrentDisplayMode); int displayModeCount = SDL_GetNumDisplayModes(i); for (int j = 0; j < displayModeCount; ++j) { SDL_DisplayMode sdlDisplayMode; SDL_GetDisplayMode(i, j, &sdlDisplayMode); SDL_PixelFormat* format = SDL_AllocFormat(sdlDisplayMode.format); if (!format) { std::cerr << "Failed to create SDL pixel format: " << SDL_GetPixelFormatName(sdlDisplayMode.format) << '\n'; continue; } int width = sdlDisplayMode.w; int height = sdlDisplayMode.h; int refreshRate = sdlDisplayMode.refresh_rate; int redBits, greenBits, blueBits, alphaBits; SDLPixelFormatMap::getChannelBits(format, &redBits, &greenBits, &blueBits, &alphaBits); SDL_FreeFormat(format); display->addMode( DisplayMode(width, height, redBits, greenBits, blueBits, alphaBits, refreshRate)); if (sdlCurrentDisplayMode.w == sdlDisplayMode.w && sdlCurrentDisplayMode.h == sdlDisplayMode.h && sdlCurrentDisplayMode.format == sdlDisplayMode.format && sdlCurrentDisplayMode.refresh_rate == sdlDisplayMode.refresh_rate) { display->setCurrentMode(j); } } } keyboard = new Keyboard("Default Keyboard"); mouse = new Mouse("Default Mouse"); application->getInputManager()->registerKeyboard(keyboard); application->getInputManager()->registerMouse(mouse); }
/* ! * Tests surface conversion across all pixel formats. */ int surface_testCompleteSurfaceConversion(void *arg) { Uint32 pixel_formats[] = { SDL_PIXELFORMAT_INDEX8, SDL_PIXELFORMAT_RGB332, SDL_PIXELFORMAT_RGB444, SDL_PIXELFORMAT_RGB555, SDL_PIXELFORMAT_BGR555, SDL_PIXELFORMAT_ARGB4444, SDL_PIXELFORMAT_RGBA4444, SDL_PIXELFORMAT_ABGR4444, SDL_PIXELFORMAT_BGRA4444, SDL_PIXELFORMAT_ARGB1555, SDL_PIXELFORMAT_RGBA5551, SDL_PIXELFORMAT_ABGR1555, SDL_PIXELFORMAT_BGRA5551, SDL_PIXELFORMAT_RGB565, SDL_PIXELFORMAT_BGR565, SDL_PIXELFORMAT_RGB24, SDL_PIXELFORMAT_BGR24, SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGBX8888, SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGRX8888, SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB2101010, }; SDL_Surface *face = NULL, *cvt1, *cvt2, *final; SDL_PixelFormat *fmt1, *fmt2; int i, j, ret = 0; /* Create sample surface */ face = SDLTest_ImageFace(); SDLTest_AssertCheck(face != NULL, "Verify face surface is not NULL"); if (face == NULL) return TEST_ABORTED; /* Set transparent pixel as the pixel at (0,0) */ if (face->format->palette) { ret = SDL_SetColorKey(face, SDL_RLEACCEL, *(Uint8 *) face->pixels); SDLTest_AssertPass("Call to SDL_SetColorKey()"); SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetColorKey, expected: 0, got: %i", ret); } for ( i = 0; i < SDL_arraysize(pixel_formats); ++i ) { for ( j = 0; j < SDL_arraysize(pixel_formats); ++j ) { fmt1 = SDL_AllocFormat(pixel_formats[i]); SDL_assert(fmt1 != NULL); cvt1 = SDL_ConvertSurface(face, fmt1, 0); SDL_assert(cvt1 != NULL); fmt2 = SDL_AllocFormat(pixel_formats[j]); SDL_assert(fmt1 != NULL); cvt2 = SDL_ConvertSurface(cvt1, fmt2, 0); SDL_assert(cvt2 != NULL); if ( fmt1->BytesPerPixel == face->format->BytesPerPixel && fmt2->BytesPerPixel == face->format->BytesPerPixel && (fmt1->Amask != 0) == (face->format->Amask != 0) && (fmt2->Amask != 0) == (face->format->Amask != 0) ) { final = SDL_ConvertSurface( cvt2, face->format, 0 ); SDL_assert(final != NULL); /* Compare surface. */ ret = SDLTest_CompareSurfaces( face, final, 0 ); SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); SDL_FreeSurface(final); } SDL_FreeSurface(cvt1); SDL_FreeFormat(fmt1); SDL_FreeSurface(cvt2); SDL_FreeFormat(fmt2); } }
U32 SGL_DataSaveImage(const char* name, SDL_Surface * surf) { U32 loc; U32 hash; SDL_Surface* convSurf; if (surf == NULL) { SDL_Log("SGL_DataSaveImage couldn't save because surf pointer is NULL"); return SGL_FALSE; } if (surf->format->format != SDL_PIXELFORMAT_ARGB8888) { convSurf = surf; } else if (surf->format->BytesPerPixel <= 4) { //SDL_PIXELFORMAT_ARGB8888 == VK_FORMAT_B8G8R8A8_UNORM //I havent had time to check why the SDL pixel format is reversed in comparison to the vulkan format //27.2.2016 Vulkan doesnt currently support 3 component pixel formats, actually the only format i found working was mentioned above SDL_PixelFormat* format = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888); convSurf = SDL_ConvertSurface(surf, format, 0); SDL_FreeFormat(format); if (convSurf == NULL) { SDL_Log("SGL_DataSaveImage couldn't convert surface to SDL_PIXELFORMAT_ARGB8888/VK_FORMAT_B8G8R8A8_UNORM, you could maybe add unimplemented format if vulkan supports it?"); return SGL_FALSE; } } else { SDL_Log("SGL_DataSaveImage encountered unsupported pixel format. Aborting save"); return SGL_FALSE; } targetData.block.imageCount++; { SDL_RWops* rw = SDL_RWFromFile(targetData.path, "rb+"); if (rw == NULL) { SDL_Log("SGL_DataSaveImage couldn't open file in path: %s, SDL_Error:%s", targetData.path, SDL_GetError()); return SGL_FALSE; } loc = (U32)SDL_RWseek(rw, 0, RW_SEEK_END); const SGL_FileSurface surfData = { convSurf->flags, convSurf->w, convSurf->h, convSurf->format->BitsPerPixel, convSurf->format->Rmask, convSurf->format->Gmask, convSurf->format->Bmask, convSurf->format->Amask }; if (SDL_RWwrite(rw, &surfData, sizeof(SGL_FileSurface), 1) != 1) { SDL_RWclose(rw); SDL_Log("SGL_DataSaveImage couldn't write to data file in path: %s", targetData.path); return SGL_FALSE; } { I32 y; const U32 pixelSize = convSurf->format->BytesPerPixel; //y axis gets flipped here //this prolly hurts the writing speed but this is done only when saving the textures for (y = surfData.h-1; y >= 0; y--) { I32 x; for (x = 0; x < surfData.w; x++) { SDL_RWwrite(rw, ((U8*)convSurf->pixels)+(y*surfData.w*pixelSize)+(x*pixelSize), pixelSize, 1); } } } SDL_RWseek(rw, 0, RW_SEEK_SET); if (SDL_RWwrite(rw, &targetData.block, sizeof(SGL_DataBlock), 1) != 1) { SDL_RWclose(rw); SDL_Log("SGL_DataSaveImage couldn't write to data file in path: %s, SDL_Error: %s", targetData.path, SDL_GetError()); return SGL_FALSE; } SDL_RWclose(rw); } MurmurHash3_x86_32(name, (I32)SDL_strlen(name), targetData.block.seed, &hash); return AddNode(hash, loc); }
int main(int argc, char** argv) #endif { #ifdef _WIN32 LPSTR *argv = __argv; int argc = __argc; (void) argv; (void) argc; #endif SDL_Window *screen; SDL_Renderer *renderer; SDL_Shader *shader; if ( SDL_Init(SDL_INIT_VIDEO) < 0 ){ fprintf(stderr, "Error: %s \n", SDL_GetError()); return 1; } SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 ); SDL_SetHint( SDL_HINT_RENDER_DRIVER, getenv("RENDER_DRIVER") ); int width = 500; int height = 700; screen = SDL_CreateWindow("Caption", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE); // SDL_WINDOW_FULLSCREEN_DESKTOP ); if ( screen == NULL ) { fprintf(stderr, "Error: %s \n", SDL_GetError()); return 2; } renderer = SDL_CreateRenderer( screen, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE ); //renderer = SDL_CreateRenderer( screen, -1, SDL_RENDERER_SOFTWARE|SDL_RENDERER_TARGETTEXTURE ); if ( renderer == NULL ) { fprintf(stderr, "Error: %s \n", SDL_GetError()); return 3; } SDL_RenderSetLogicalSize(renderer, width, height); SDL_SetWindowTitle( screen, renderer->info.name ); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderClear(renderer); printf("renderer name: %s\n" , renderer->info.name ); printf("SDL_PIXELFORMAT_UNKNOWN= %d\n",SDL_PIXELFORMAT_UNKNOWN); printf("SDL_PIXELFORMAT_INDEX1LSB= %d\n",SDL_PIXELFORMAT_INDEX1LSB); printf("SDL_PIXELFORMAT_INDEX1MSB= %d\n",SDL_PIXELFORMAT_INDEX1MSB); printf("SDL_PIXELFORMAT_INDEX4LSB= %d\n",SDL_PIXELFORMAT_INDEX4LSB); printf("SDL_PIXELFORMAT_INDEX4MSB= %d\n",SDL_PIXELFORMAT_INDEX4MSB); printf("SDL_PIXELFORMAT_INDEX8= %d\n",SDL_PIXELFORMAT_INDEX8); printf("SDL_PIXELFORMAT_RGB332= %d\n",SDL_PIXELFORMAT_RGB332); printf("SDL_PIXELFORMAT_RGB444= %d\n",SDL_PIXELFORMAT_RGB444); printf("SDL_PIXELFORMAT_RGB555= %d\n",SDL_PIXELFORMAT_RGB555); printf("SDL_PIXELFORMAT_BGR555= %d\n",SDL_PIXELFORMAT_BGR555); printf("SDL_PIXELFORMAT_ARGB4444= %d\n",SDL_PIXELFORMAT_ARGB4444); printf("SDL_PIXELFORMAT_RGBA4444= %d\n",SDL_PIXELFORMAT_RGBA4444); printf("SDL_PIXELFORMAT_ABGR4444= %d\n",SDL_PIXELFORMAT_ABGR4444); printf("SDL_PIXELFORMAT_BGRA4444= %d\n",SDL_PIXELFORMAT_BGRA4444); printf("SDL_PIXELFORMAT_ARGB1555= %d\n",SDL_PIXELFORMAT_ARGB1555); printf("SDL_PIXELFORMAT_RGBA5551= %d\n",SDL_PIXELFORMAT_RGBA5551); printf("SDL_PIXELFORMAT_ABGR1555= %d\n",SDL_PIXELFORMAT_ABGR1555); printf("SDL_PIXELFORMAT_BGRA5551= %d\n",SDL_PIXELFORMAT_BGRA5551); printf("SDL_PIXELFORMAT_RGB565= %d\n",SDL_PIXELFORMAT_RGB565); printf("SDL_PIXELFORMAT_BGR565= %d\n",SDL_PIXELFORMAT_BGR565); printf("SDL_PIXELFORMAT_RGB24= %d\n",SDL_PIXELFORMAT_RGB24); printf("SDL_PIXELFORMAT_BGR24= %d\n",SDL_PIXELFORMAT_BGR24); printf("SDL_PIXELFORMAT_RGB888= %d\n",SDL_PIXELFORMAT_RGB888); printf("SDL_PIXELFORMAT_RGBX8888= %d\n",SDL_PIXELFORMAT_RGBX8888); printf("SDL_PIXELFORMAT_BGR888= %d\n",SDL_PIXELFORMAT_BGR888); printf("SDL_PIXELFORMAT_BGRX8888= %d\n",SDL_PIXELFORMAT_BGRX8888); printf("SDL_PIXELFORMAT_ARGB8888= %d\n",SDL_PIXELFORMAT_ARGB8888); printf("SDL_PIXELFORMAT_RGBA8888= %d\n",SDL_PIXELFORMAT_RGBA8888); printf("SDL_PIXELFORMAT_ABGR8888= %d\n",SDL_PIXELFORMAT_ABGR8888); printf("SDL_PIXELFORMAT_BGRA8888= %d\n",SDL_PIXELFORMAT_BGRA8888); printf("SDL_PIXELFORMAT_ARGB2101010=%d\n",SDL_PIXELFORMAT_ARGB2101010); shader = SDL_createShader( renderer, "../shaders/do_nothing/do_nothing" ); if ( shader == NULL ){ fprintf(stderr, "Error: %s \n", SDL_GetError()); return 4; } SDL_Surface* srf; srf = IMG_Load( "../img.png" ); if ( !srf ) { fprintf(stderr, "Error: %s \n", SDL_GetError()); return 5; } int i; Uint32 formats[] = { /* Indexed formats and YUV are not supported */ SDL_PIXELFORMAT_RGB332, SDL_PIXELFORMAT_RGB444, SDL_PIXELFORMAT_RGB555, SDL_PIXELFORMAT_BGR555, SDL_PIXELFORMAT_ARGB4444, SDL_PIXELFORMAT_RGBA4444, SDL_PIXELFORMAT_ABGR4444, SDL_PIXELFORMAT_BGRA4444, SDL_PIXELFORMAT_ARGB1555, SDL_PIXELFORMAT_RGBA5551, SDL_PIXELFORMAT_ABGR1555, SDL_PIXELFORMAT_BGRA5551, SDL_PIXELFORMAT_RGB565, SDL_PIXELFORMAT_BGR565, SDL_PIXELFORMAT_RGB24, SDL_PIXELFORMAT_BGR24, SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGBX8888, SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGRX8888, SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB2101010 }; char fmt_names[][NUM_OF_TEXTURES] = { "RGB332", "RGB444", "RGB555", "BGR555", "ARGB4444", "RGBA4444", "ABGR4444", "BGRA4444", "ARGB1555", "RGBA5551", "ABGR1555", "BGRA5551", "RGB565", "BGR565", "RGB24", "BGR24", "RGB888", "RGBX8888", "BGR888", "BGRX8888", "ARGB8888", "RGBA8888", "ABGR8888", "BGRA8888", "ARGB2101010" }; SDL_BlendMode blendModes[] = { SDL_BLENDMODE_NONE, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_ADD, SDL_BLENDMODE_MOD }; char* blendNames[] = { "NONE", "BLEND", "ADD", "MOD" }; int current_blend = 0; int colors[][4] = { {255,255,255,255}, {255, 0, 0,255}, { 0,255, 0,255}, { 0, 0,255,255}, {255,255,255,127} }; char* colorNames[] = { "white", "red", "green", "blue", "semi transp." }; int current_color = 0; SDL_Texture* textures[ NUM_OF_TEXTURES ]; for ( i=0; i< (int)(NUM_OF_TEXTURES); i++) { SDL_PixelFormat* fmt = SDL_AllocFormat( formats[i] ); SDL_assert(fmt != NULL); SDL_Surface* srf2 = SDL_ConvertSurface(srf, fmt, 0); SDL_assert(srf2 != NULL); textures[i] = SDL_CreateTextureFromSurface(renderer, srf2 ); SDL_SetTextureBlendMode(textures[i], blendModes[current_blend]); SDL_FreeSurface( srf2 ); SDL_FreeFormat(fmt); if ( !textures[i] ){ return 1000 + i; } if ( textures[i]->native ){ printf("native_tex: %d \n",textures[i]->native->format ); }else{ printf("SDL_tex: %d \n",textures[i]->format ); } } SDL_FreeSurface(srf); SDL_SetRenderTarget( renderer, NULL ); SDL_Event e; SDL_SetRenderDrawColor(renderer, 0,0,0,1); int ret = 0; int quit = 0; while ( !quit ) { SDLTest_DrawString( renderer, 8, 8, blendNames[current_blend] ); SDLTest_DrawString( renderer, 108, 8, colorNames[current_color] ); for ( i=0; i< (int)(NUM_OF_TEXTURES); i++) { int x=30+(i%8)*55; int y=30+(i/8)*75; SDL_Rect dst = {x,y,50,50}; ret = SDL_renderCopyShd( shader, textures[i], NULL, &dst ); if ( ret!=0 ){ fprintf(stderr,"Err: %s\n", SDL_GetError()); } SDLTest_DrawString( renderer, dst.x,dst.y+55 + (i%2==0 ? 10 : 0), fmt_names[i] ); dst.y += (NUM_OF_TEXTURES)/8 * 75 + 85; SDL_RenderCopy( renderer, textures[i], NULL, &dst ); SDLTest_DrawString( renderer, dst.x,dst.y+55 + (i%2==0 ? 10 : 0), fmt_names[i] ); } while (SDL_PollEvent(&e)){ switch ( e.type ) { case SDL_QUIT: quit = 1; break; case SDL_KEYDOWN: switch ( e.key.keysym.sym ) { case SDLK_SPACE: current_blend = (current_blend+1)%4; for ( i=0; i< (int)(NUM_OF_TEXTURES); i++) { SDL_SetTextureBlendMode(textures[i], blendModes[current_blend]); } break; case SDLK_TAB: current_color = (current_color+1)%5; for ( i=0; i< (int)(NUM_OF_TEXTURES); i++) { SDL_SetTextureColorMod(textures[i], colors[current_color][0], colors[current_color][1], colors[current_color][2]); SDL_SetTextureAlphaMod(textures[i], colors[current_color][3] ); } break; } break; case SDL_WINDOWEVENT: SDL_updateViewport( shader ); } } SDL_RenderPresent(renderer); SDL_SetRenderDrawColor(renderer, 160, 160, 160, 255); SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); } for ( i=0; i<(int)NUM_OF_TEXTURES; i++ ) { SDL_DestroyTexture( textures[i] ); textures[i] = NULL; } SDL_destroyShader( shader ); SDL_DestroyRenderer( renderer ); SDL_DestroyWindow( screen ); SDL_Quit(); return 0; }
// create a font with a drop-shadow (used for "MNA" stage-name displays) bool NXFont::InitCharsShadowed(TTF_Font *font, uint32_t color, uint32_t shadowcolor) { SDL_Color fgcolor, shcolor; SDL_Surface *top, *bottom; SDL_Rect dstrect; fgcolor.r = (uint8_t)(color >> 16); fgcolor.g = (uint8_t)(color >> 8); fgcolor.b = (uint8_t)(color); shcolor.r = (uint8_t)(shadowcolor >> 16); shcolor.g = (uint8_t)(shadowcolor >> 8); shcolor.b = (uint8_t)(shadowcolor); char str[2]; str[1] = 0; SDL_PixelFormat* pxformat = SDL_AllocFormat(screen->Format()->format); if (!pxformat) { staterr("InitBitmapChars: SDL_AllocFormat failed: %s", SDL_GetError()); return 1; } uint32_t transp = SDL_ALPHA_TRANSPARENT; for(int i=1;i<NUM_LETTERS_RENDERED;i++) { str[0] = i; top = TTF_RenderText_Solid(font, str, fgcolor); bottom = TTF_RenderText_Solid(font, str, shcolor); if (!top || !bottom) { staterr("InitCharsShadowed: failed to render character %d: %s", i, TTF_GetError()); SDL_FreeFormat(pxformat); SDL_FreeSurface(top); SDL_FreeSurface(bottom); return 1; } letters[i] = SDL_CreateRGBSurface(0, top->w, top->h+SHADOW_OFFSET, pxformat->BitsPerPixel, pxformat->Rmask, pxformat->Gmask, pxformat->Bmask, pxformat->Amask); if (!letters[i]) { staterr("InitCharsShadowed: failed to create surface for character %d: %s", i, SDL_GetError()); SDL_FreeFormat(pxformat); SDL_FreeSurface(top); SDL_FreeSurface(bottom); return 1; } SDL_FillRect(letters[i], NULL, transp); SDL_SetColorKey(letters[i], SDL_TRUE, transp); dstrect.x = 0; dstrect.y = SHADOW_OFFSET; SDL_BlitSurface(bottom, NULL, letters[i], &dstrect); dstrect.x = 0; dstrect.y = 0; SDL_BlitSurface(top, NULL, letters[i], &dstrect); SDL_FreeSurface(top); SDL_FreeSurface(bottom); } return 0; }
~BitmapPrivate() { SDL_FreeFormat(format); pixman_region_fini(&tainted); }