diff --git a/src/sys/ags.cpp b/src/sys/ags.cpp index 5d6ff4f..9113829 100644 --- a/src/sys/ags.cpp +++ b/src/sys/ags.cpp @@ -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); } } diff --git a/src/sys/ags.h b/src/sys/ags.h index ead6c0f..9dc1ccc 100644 --- a/src/sys/ags.h +++ b/src/sys/ags.h @@ -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; diff --git a/src/win/nact_win.cpp b/src/win/nact_win.cpp index 82d166f..7221405 100644 --- a/src/win/nact_win.cpp +++ b/src/win/nact_win.cpp @@ -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());