diff --git a/src/config.cpp b/src/config.cpp index 1d4620c..99985ae 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -104,6 +104,8 @@ Config::Config(int argc, char *argv[]) title = argv[++i]; else if (strcmp(argv[i], "-timiditycfg") == 0) timidity_cfg = argv[++i]; + else if (strcmp(argv[i], "-scanline") == 0) + scanline = true; } } @@ -158,6 +160,8 @@ void Config::load_ini() title = val; else if (!strcasecmp(key, "timiditycfg")) timidity_cfg = normalize_path(val); + else if (!strcasecmp(key, "scanline")) + scanline = to_bool(val, lineno); else WARNING(INIFILENAME ":%d unknown key '%s'", lineno, key); } else if (current_section == STRING) { diff --git a/src/config.h b/src/config.h index 2bd3a33..0603d45 100644 --- a/src/config.h +++ b/src/config.h @@ -31,6 +31,7 @@ struct Config { std::string timidity_cfg; bool use_fm = false; bool no_antialias = false; + bool scanline = false; private: void load_ini(); diff --git a/src/sys/ags.cpp b/src/sys/ags.cpp index cd0d1c7..5b779ef 100644 --- a/src/sys/ags.cpp +++ b/src/sys/ags.cpp @@ -36,6 +36,28 @@ static SDL_Surface* display_surface; box[n].ey = y2; \ } +namespace { + +const uint32 SCANLINE_ALPHA = 0x38; // 0-255 + +SDL_Texture* create_scanline_texture(SDL_Renderer* renderer, int width, int height) +{ + SDL_Surface* sf = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_ARGB8888); + for (int y = 0; y < height; y++) { + uint32* p = surface_line(sf, y); + uint32 v = y % 2 ? (SCANLINE_ALPHA << 24) : 0; + for (int x = 0; x < width; x++) { + p[x] = v; + } + } + SDL_Texture* tx = SDL_CreateTextureFromSurface(renderer, sf); + SDL_SetTextureBlendMode(tx, SDL_BLENDMODE_BLEND); + SDL_FreeSurface(sf); + return tx; +} + +} // namespace + AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false) { // 画面サイズ @@ -52,6 +74,7 @@ AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false) 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? + scanline_texture = NULL; // DIBSection 8bpp * 3 (表, 裏, メニュー) for(int i = 0; i < 3; i++) { @@ -358,6 +381,8 @@ AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false) // マウスカーソル cursor_color = 15; cursor_index = 0; + + set_scanline_mode(config.scanline); } AGS::~AGS() @@ -527,10 +552,26 @@ void AGS::update_screen() SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, 255); SDL_SetRenderDrawBlendMode(g_renderer, SDL_BLENDMODE_NONE); } + if (scanline_texture) + SDL_RenderCopy(g_renderer, scanline_texture, NULL, NULL); SDL_RenderPresent(g_renderer); dirty = false; } +void AGS::set_scanline_mode(bool enable) +{ + if (enable && !scanline_texture) { + scanline_texture = create_scanline_texture(g_renderer, screen_width, screen_height); + dirty = true; + update_screen(); + } else if (!enable && scanline_texture) { + SDL_DestroyTexture(scanline_texture); + scanline_texture = NULL; + dirty = true; + update_screen(); + } +} + void AGS::save_screenshot(const char* path) { SDL_Surface* sf = SDL_CreateRGBSurface(0, screen_width, screen_height, 32, 0, 0, 0, 0); @@ -539,6 +580,14 @@ void AGS::save_screenshot(const char* path) SDL_BlitSurface(hBmpDest, &r, sf, NULL); SDL_LockSurface(hBmpDest); + if (scanline_texture) { + SDL_Renderer* renderer = SDL_CreateSoftwareRenderer(sf); + SDL_Texture *tx = create_scanline_texture(renderer, screen_width, screen_height); + SDL_RenderCopy(renderer, tx, NULL, NULL); + SDL_DestroyTexture(tx); + SDL_DestroyRenderer(renderer); + } + if (SDL_SaveBMP(sf, path) != 0) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "system3", SDL_GetError(), g_window); diff --git a/src/sys/ags.h b/src/sys/ags.h index e5c4102..8ca0bfa 100644 --- a/src/sys/ags.h +++ b/src/sys/ags.h @@ -40,6 +40,7 @@ protected: NACT* nact; private: SDL_Texture* sdlTexture; + SDL_Texture* scanline_texture; // Surface SDL_Surface* hBmpScreen[3]; // 8bpp * 3 (表, 裏, メニュー) @@ -128,6 +129,8 @@ public: void select_cursor(); void translate_mouse_coords(int* x, int* y); + bool get_scanline_mode() const { return scanline_texture; } + void set_scanline_mode(bool enable); void save_screenshot(const char* path); int calculate_menu_max(int window); diff --git a/src/win/nact_win.cpp b/src/win/nact_win.cpp index d4ee563..353551f 100644 --- a/src/win/nact_win.cpp +++ b/src/win/nact_win.cpp @@ -21,13 +21,15 @@ HWND get_hwnd(SDL_Window* window) { return info.info.win.window; } -void init_menu(bool mouse_move_enabled) +void init_menu(bool mouse_move_enabled, bool scanline_enabled) { HINSTANCE hinst = (HINSTANCE)GetModuleHandle(NULL); HMENU hmenu = LoadMenu(hinst, MAKEINTRESOURCE(IDR_MENU1)); SetMenu(get_hwnd(g_window), hmenu); if (mouse_move_enabled) CheckMenuItem(hmenu, ID_OPTION_MOUSE_MOVE, MF_BYCOMMAND | MFS_CHECKED); + if (scanline_enabled) + CheckMenuItem(hmenu, ID_SCANLINE, MF_BYCOMMAND | MFS_CHECKED); } void init_console(int sys_ver) @@ -129,7 +131,7 @@ void NACT::text_dialog() void NACT::platform_initialize() { - init_menu(mouse_move_enabled); + init_menu(mouse_move_enabled, config.scanline); init_console(sys_ver); SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); } @@ -188,6 +190,11 @@ bool NACT::handle_platform_event(const SDL_Event& e) SDL_SetWindowFullscreen(g_window, SDL_WINDOW_FULLSCREEN_DESKTOP); ags->flush_screen(true); break; + case ID_SCANLINE: + ags->set_scanline_mode(!ags->get_scanline_mode()); + CheckMenuItem(GetMenu(get_hwnd(g_window)), ID_SCANLINE, MF_BYCOMMAND | + ags->get_scanline_mode() ? MFS_CHECKED : MFS_UNCHECKED); + break; case ID_OPTION_MOUSE_MOVE: mouse_move_enabled = !mouse_move_enabled; CheckMenuItem(GetMenu(get_hwnd(g_window)), ID_OPTION_MOUSE_MOVE, diff --git a/src/win/resource.h b/src/win/resource.h index d8234f3..4a663f3 100644 --- a/src/win/resource.h +++ b/src/win/resource.h @@ -24,6 +24,7 @@ #define ID_EXIT 40002 #define ID_SCREEN_WINDOW 40010 #define ID_SCREEN_FULL 40011 +#define ID_SCANLINE 40012 #define ID_OPTION_MOUSE_MOVE 40020 #define ID_OPTION_FM 40021 #define ID_OPTION_MIDI 40022 diff --git a/src/win/resource.rc b/src/win/resource.rc index d4ebd31..02aa779 100644 --- a/src/win/resource.rc +++ b/src/win/resource.rc @@ -97,6 +97,8 @@ BEGIN BEGIN MENUITEM "Window", ID_SCREEN_WINDOW MENUITEM "Fullscreen", ID_SCREEN_FULL + MENUITEM SEPARATOR + MENUITEM "Scanline effect", ID_SCANLINE END POPUP "Option" BEGIN @@ -153,6 +155,8 @@ BEGIN BEGIN MENUITEM "ウィンドウ", ID_SCREEN_WINDOW MENUITEM "フルスクリーン", ID_SCREEN_FULL + MENUITEM SEPARATOR + MENUITEM "走査線エフェクト", ID_SCANLINE END POPUP "オプション" BEGIN @@ -209,6 +213,8 @@ BEGIN BEGIN MENUITEM "窗口化", ID_SCREEN_WINDOW MENUITEM "全屏化", ID_SCREEN_FULL + MENUITEM SEPARATOR + MENUITEM "Scanline effect", ID_SCANLINE END POPUP "选项" BEGIN