mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-09-22 22:58:12 +03:00
AGS: Remove intermediate screen buffer
Pixels are now copied directly from the 8-bit buffer to the texture.
This commit is contained in:
+18
-33
@@ -13,7 +13,6 @@
|
||||
|
||||
extern SDL_Window* g_window;
|
||||
extern SDL_Renderer* g_renderer;
|
||||
static SDL_Surface* display_surface;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -51,7 +50,7 @@ AGS::AGS(const Config& config, const GameId& game_id) : game_id(game_id), dirty(
|
||||
|
||||
SDL_SetWindowSize(g_window, window_width, window_height);
|
||||
SDL_RenderSetLogicalSize(g_renderer, window_width, window_height);
|
||||
sdlTexture = SDL_CreateTexture(g_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, screen_width, screen_height); // TOOD: pixelformat?
|
||||
sdlTexture = SDL_CreateTexture(g_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen_width, screen_height);
|
||||
scanline_texture = NULL;
|
||||
|
||||
// DIBSection 8bpp * 3 (表, 裏, メニュー)
|
||||
@@ -65,9 +64,6 @@ AGS::AGS(const Config& config, const GameId& game_id) : game_id(game_id), dirty(
|
||||
SDL_SetSurfacePalette(hBmpScreen[1], screen_palette);
|
||||
SDL_SetSurfacePalette(hBmpScreen[2], screen_palette);
|
||||
|
||||
// DIBSection 24bpp * 1 (最終出力先)
|
||||
display_surface = hBmpDest = SDL_CreateRGBSurface(0, 640, 480, 32, 0, 0, 0, 0);
|
||||
|
||||
// フォント
|
||||
TTF_Init();
|
||||
if (!config.font_file.empty()) {
|
||||
@@ -261,8 +257,6 @@ AGS::~AGS()
|
||||
SDL_FreeSurface(hBmpScreen[i]);
|
||||
}
|
||||
|
||||
SDL_FreeSurface(hBmpDest);
|
||||
|
||||
SDL_DestroyTexture(sdlTexture);
|
||||
}
|
||||
|
||||
@@ -408,29 +402,21 @@ void AGS::fade_in(int duration_ms)
|
||||
|
||||
void AGS::flush_screen(bool update)
|
||||
{
|
||||
if(update) {
|
||||
SDL_Rect rect = {0, 0, screen_width, screen_height};
|
||||
SDL_BlitSurface(hBmpScreen[0], &rect, hBmpDest, &rect);
|
||||
}
|
||||
invalidate_screen(0, 0, screen_width, screen_height);
|
||||
if (update)
|
||||
draw_screen(0, 0, screen_width, screen_height);
|
||||
else
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void AGS::draw_screen(int sx, int sy, int width, int height)
|
||||
{
|
||||
SDL_Rect rect = {sx, sy, width, height};
|
||||
SDL_BlitSurface(hBmpScreen[0], &rect, hBmpDest, &rect);
|
||||
invalidate_screen(sx, sy, width, height);
|
||||
}
|
||||
|
||||
void AGS::invalidate_screen(int sx, int sy, int width, int height)
|
||||
{
|
||||
uint32* pixels = surface_line(hBmpDest, sy) + sx;
|
||||
if (sy + height > screen_height)
|
||||
height = screen_height - sy;
|
||||
if (sx + width > hBmpDest->w)
|
||||
width = hBmpDest->w - sx;
|
||||
SDL_Rect rect = {sx, sy, width, height};
|
||||
SDL_UpdateTexture(sdlTexture, &rect, pixels, hBmpDest->pitch);
|
||||
SDL_Rect screen_rect = {0, 0, screen_width, screen_height};
|
||||
SDL_IntersectRect(&rect, &screen_rect, &rect);
|
||||
SDL_Surface *sf;
|
||||
SDL_LockTextureToSurface(sdlTexture, &rect, &sf);
|
||||
SDL_BlitSurface(hBmpScreen[0], &rect, sf, NULL);
|
||||
SDL_UnlockTexture(sdlTexture);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@@ -478,11 +464,10 @@ void AGS::set_scanline_mode(bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
void AGS::save_screenshot(const char* path)
|
||||
bool AGS::save_screenshot(const char* path)
|
||||
{
|
||||
SDL_Surface* sf = SDL_CreateRGBSurface(0, screen_width, screen_height, 32, 0, 0, 0, 0);
|
||||
SDL_Rect r = {0, 0, screen_width, screen_height};
|
||||
SDL_BlitSurface(hBmpDest, &r, sf, NULL);
|
||||
SDL_BlitSurface(hBmpScreen[0], NULL, sf, NULL);
|
||||
|
||||
if (scanline_texture) {
|
||||
SDL_Renderer* renderer = SDL_CreateSoftwareRenderer(sf);
|
||||
@@ -492,13 +477,15 @@ void AGS::save_screenshot(const char* path)
|
||||
SDL_DestroyRenderer(renderer);
|
||||
}
|
||||
|
||||
if (SDL_SaveBMP(sf, path) != 0) {
|
||||
bool ok = SDL_SaveBMP(sf, path) == 0;
|
||||
if (!ok) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "system3",
|
||||
SDL_GetError(), g_window);
|
||||
SDL_ClearError();
|
||||
}
|
||||
|
||||
SDL_FreeSurface(sf);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int AGS::calculate_menu_max(int window) {
|
||||
@@ -512,10 +499,8 @@ int AGS::calculate_menu_max(int window) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
extern "C" {
|
||||
|
||||
void* EMSCRIPTEN_KEEPALIVE sdl_getDisplaySurface() {
|
||||
if (SDL_MUSTLOCK(display_surface))
|
||||
return NULL;
|
||||
return display_surface->pixels;
|
||||
bool EMSCRIPTEN_KEEPALIVE save_screenshot(const char* path) {
|
||||
return g_nact->ags->save_screenshot(path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-3
@@ -35,7 +35,6 @@ private:
|
||||
|
||||
// Surface
|
||||
SDL_Surface* hBmpScreen[3]; // 8bpp * 3 (表, 裏, メニュー)
|
||||
SDL_Surface* hBmpDest; // DIBSection 24bpp (最終出力先)
|
||||
uint8_t (*vram[3])[640]; // convenience pointer to hBmpScreen[i]->pixels
|
||||
|
||||
SDL_Palette* program_palette;
|
||||
@@ -65,7 +64,6 @@ private:
|
||||
void draw_gaiji(int dest, int dest_x, int dest_y, const uint8_t bitmap[32], int size, uint8 color);
|
||||
|
||||
void draw_screen(int sx, int sy, int width, int heignt);
|
||||
void invalidate_screen(int sx, int sy, int width, int height);
|
||||
|
||||
uint8_t palR(uint8_t col) const { return screen_palette->colors[col].r; }
|
||||
uint8_t palG(uint8_t col) const { return screen_palette->colors[col].g; }
|
||||
@@ -140,7 +138,7 @@ public:
|
||||
|
||||
bool get_scanline_mode() const { return scanline_texture; }
|
||||
void set_scanline_mode(bool enable);
|
||||
void save_screenshot(const char* path);
|
||||
bool save_screenshot(const char* path);
|
||||
int calculate_menu_max(int window);
|
||||
|
||||
bool dirty;
|
||||
|
||||
@@ -193,11 +193,11 @@ bool NACT::handle_platform_event(const SDL_Event& e)
|
||||
break;
|
||||
case ID_SCREEN_WINDOW:
|
||||
SDL_SetWindowFullscreen(g_window, 0);
|
||||
ags->flush_screen(true);
|
||||
ags->flush_screen(false);
|
||||
break;
|
||||
case ID_SCREEN_FULL:
|
||||
SDL_SetWindowFullscreen(g_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
ags->flush_screen(true);
|
||||
ags->flush_screen(false);
|
||||
break;
|
||||
case ID_SCANLINE:
|
||||
ags->set_scanline_mode(!ags->get_scanline_mode());
|
||||
|
||||
Reference in New Issue
Block a user